-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mono] Implement AssemblyExtensions.TryGetRawMetadata
.
#111642
base: main
Are you sure you want to change the base?
Conversation
f9afb32
to
e0a2378
Compare
e0a2378
to
68d5e54
Compare
src/mono/mono/metadata/icall.c
Outdated
ves_icall_System_Reflection_RuntimeAssembly_InternalTryGetRawMetadata (MonoQCallAssemblyHandle assembly_h, gpointer_ref blob, gint32_ref length, MonoError *error) | ||
{ | ||
MonoAssembly *assembly = assembly_h.assembly; | ||
MonoImage *image = assembly->image; | ||
|
||
if (image_is_dynamic (image)) { | ||
return FALSE; | ||
} | ||
|
||
*blob = image->raw_metadata; | ||
*((guint32*)length) = image->raw_metadata_len; | ||
|
||
return TRUE; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure that this handles the hot reload case? I think this would give back the metadata for the unedited image with Mono's hot reload implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea. What does CoreCLR do in hot-reloaded assemblies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For CoreCLR, we have an editable metadata system, so RefEmit and Hot Reload go down the same path (no metadata blob available to pass up to callers).
For Mono, their RefEmit solution is a completely separate lookup system, so Hot Reload uses a separate mechanism that works via "layers".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So for Mono, you need to check the has_updates
bit on the MonoImage. If that's true, this function needs to return false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For CoreCLR, we have an editable metadata system, so RefEmit and Hot Reload go down the same path (no metadata blob available to pass up to callers).
If I am reading the correctly, CoreCLR returns the original metadata blob for hot reload assemblies from this API.
you need to check the has_updates bit on the MonoImage.
I think it is unnecessary difference from the CoreCLR behavior. I do not see a block like this in the CoreCLR implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jkotas, you're right. I was thinking of a different internal API that the implementation in CoreCLR doesn't use. The actual function it calls doesn't care about Hot Reload and just returns the original image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated code to remove checks and rely on the metadata pointer not being null. This now matches the CoreCLR implementation.
runtime/src/coreclr/vm/assemblynative.cpp
Lines 1287 to 1310 in abf8e94
extern "C" BOOL QCALLTYPE AssemblyNative_InternalTryGetRawMetadata( | |
QCall::AssemblyHandle assembly, | |
UINT8 **blobRef, | |
INT32 *lengthRef) | |
{ | |
QCALL_CONTRACT; | |
PTR_CVOID metadata = nullptr; | |
BEGIN_QCALL; | |
_ASSERTE(assembly != nullptr); | |
_ASSERTE(blobRef != nullptr); | |
_ASSERTE(lengthRef != nullptr); | |
static_assert_no_msg(sizeof(*lengthRef) == sizeof(COUNT_T)); | |
metadata = assembly->GetPEAssembly()->GetLoadedMetadata(reinterpret_cast<COUNT_T *>(lengthRef)); | |
*blobRef = reinterpret_cast<UINT8 *>(const_cast<PTR_VOID>(metadata)); | |
_ASSERTE(*lengthRef >= 0); | |
END_QCALL; | |
return metadata != nullptr; | |
} |
And return if the metadata blob pointer is not null, matching CoreCLR implementation.
No description provided.