Skip to content
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

Integrate mibc mono config extension #71657

Merged
merged 4 commits into from
Jul 6, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/coreclr/vm/ClrEtwAll.man
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@
<bitMap name="RuntimeSkuMap">
<map value="0x1" message="$(string.RuntimePublisher.RuntimeSku.DesktopCLRMapMessage)"/>
<map value="0x2" message="$(string.RuntimePublisher.RuntimeSku.CoreCLRMapMessage)"/>
<map value="0x4" message="$(string.RuntimePublisher.RuntimeSku.MonoMapMessage)"/>
</bitMap>
<bitMap name="ExceptionThrownFlagsMap">
<map value="0x1" message="$(string.RuntimePublisher.ExceptionThrown.HasInnerExceptionMapMessage)"/>
Expand Down Expand Up @@ -4309,6 +4310,7 @@
<bitMap name="RuntimeSkuMap">
<map value="0x1" message="$(string.RundownPublisher.RuntimeSku.DesktopCLRMapMessage)"/>
<map value="0x2" message="$(string.RundownPublisher.RuntimeSku.CoreCLRMapMessage)"/>
<map value="0x4" message="$(string.RundownPublisher.RuntimeSku.MonoMapMessage)"/>
</bitMap>
<bitMap name="StartupFlagsMap">
<map value="0x000001" message="$(string.RundownPublisher.Startup.CONCURRENT_GCMapMessage)"/>
Expand Down Expand Up @@ -8678,6 +8680,7 @@
<string id="RuntimePublisher.StartupMode.OtherMapMessage" value="Other" />
<string id="RuntimePublisher.RuntimeSku.DesktopCLRMapMessage" value="DesktopClr" />
<string id="RuntimePublisher.RuntimeSku.CoreCLRMapMessage" value="CoreClr" />
<string id="RuntimePublisher.RuntimeSku.MonoMapMessage" value="Mono" />
<string id="RuntimePublisher.ExceptionThrown.HasInnerExceptionMapMessage" value="HasInnerException" />
<string id="RuntimePublisher.ExceptionThrown.NestedMapMessage" value="Nested" />
<string id="RuntimePublisher.ExceptionThrown.ReThrownMapMessage" value="ReThrown" />
Expand Down Expand Up @@ -8808,6 +8811,7 @@
<string id="RundownPublisher.StartupMode.OtherMapMessage" value="Other" />
<string id="RundownPublisher.RuntimeSku.DesktopCLRMapMessage" value="DesktopClr" />
<string id="RundownPublisher.RuntimeSku.CoreCLRMapMessage" value="CoreClr" />
<string id="RundownPublisher.RuntimeSku.MonoMapMessage" value="Mono" />
<string id="RundownPublisher.Startup.CONCURRENT_GCMapMessage" value="CONCURRENT_GC" />
<string id="RundownPublisher.Startup.LOADER_OPTIMIZATION_SINGLE_DOMAINMapMessage" value="LOADER_OPTIMIZATION_SINGLE_DOMAIN" />
<string id="RundownPublisher.Startup.LOADER_OPTIMIZATION_MULTI_DOMAINMapMessage" value="LOADER_OPTIMIZATION_MULTI_DOMAIN" />
Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/metadata/image-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#include <mono/metadata/loader-internals.h>

typedef struct {
int dont_care_about_cli : 1;
int dont_care_about_pecoff : 1;
gboolean dont_care_about_cli : 1;
gboolean dont_care_about_pecoff : 1;
} MonoImageLoadOptions;

typedef struct {
Expand Down
109 changes: 108 additions & 1 deletion src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -13350,14 +13350,116 @@ add_mibc_group_method_methods (MonoAotCompile *acfg, MonoMethod *mibcGroupMethod
return count;
}

typedef enum {
PARSING_MIBC_CONFIG_NONE,
PARSING_MIBC_CONFIG_RUNTIME_FIELD,
} MibcConfigParserState;

//---------------------------------------------------------------------------------------
//
// compatible_mibc_profile_config is responsible for ensuring that the .mibc profile
// used is compatible with Mono. An incompatible .mibc profile contains types that
// cannot be found on Mono, exemplified by a .mibc generated from a .nettrace collected
// from a CoreCLR based app, as it will contain Canon types not found on Mono. If the
// MibcConfig can be found and the associated runtime is not Mono, return false. If there
// is no MibcConfig, consider the .mibc having been generated prior to the introduction of
// the MibcConfig and permit it.
//
// Sample MibcConfig format
//
// Method 'MibcConfig' (#1443) (0x06000001)
// {
// // Code size 49 (0x31)
// .maxstack 8
// IL_0000: ldstr 0x70000001 // FormatVersion
// IL_0005: ldstr 0x7000001D // 1.0
// IL_000a: pop
// IL_000b: pop
// IL_000c: ldstr 0x70000025 // Os
// IL_0011: ldstr 0x7000002B // macOS
// IL_0016: pop
// IL_0017: pop
// IL_0018: ldstr 0x70000037 // Arch
// IL_001d: ldstr 0x70000041 // arm64
// IL_0022: pop
// IL_0023: pop
// IL_0024: ldstr 0x7000004D // Runtime
// IL_0029: ldstr 0x7000005D // Mono (or 4)
// IL_002e: pop
// IL_002f: pop
// IL_0030: ret
// }
//
// Arguments:
// * image - the MonoImage corresponding to the .mibc
// * mibcModuleClass - the MonoClass containing the MibcConfig
//
// Return Value:
// gboolean pertaining to the compatibility of the provided mibc with mono runtime
//

static gboolean
compatible_mibc_profile_config (MonoImage *image, MonoClass *mibcModuleClass)
{
ERROR_DECL (error);

MonoMethod *mibcConfig = mono_class_get_method_from_name_checked (mibcModuleClass, "MibcConfig", 0, 0, error);
mono_error_assert_ok (error);

// If there is no MibcConfig, assume it was a .mibc generated prior to MibcConfig addition
if (!mibcConfig)
return TRUE;

MonoMethodHeader *mibcConfigHeader = mono_method_get_header_internal (mibcConfig, error);
mono_error_assert_ok (error);

gboolean isConfigCompatible = FALSE;
MibcConfigParserState state = PARSING_MIBC_CONFIG_NONE;
uint8_t *cur = (uint8_t*)mibcConfigHeader->code;
mdh1418 marked this conversation as resolved.
Show resolved Hide resolved
uint8_t *end = (uint8_t*)mibcConfigHeader->code + mibcConfigHeader->code_size;
while (cur < end) {
MonoOpcodeEnum il_op;
const unsigned char *opcodeIp = (unsigned char*)cur;
const unsigned char *opcodeEnd = (unsigned char*)end;
mdh1418 marked this conversation as resolved.
Show resolved Hide resolved
cur += mono_opcode_value_and_size (&opcodeIp, opcodeEnd, &il_op);
// opcodeIp gets moved to point at end of opcode
// il opcode arg is opcodeIp + 1
// we only care about args of ldstr, which are 32bits/4bytes
if (il_op == MONO_CEE_POP)
continue;

if (il_op == MONO_CEE_RET)
break;

g_assert (opcodeIp + 4 < opcodeEnd);
guint32 token = read32 (opcodeIp + 1);

char *value = mono_ldstr_utf8 (image, mono_metadata_token_index (token), error);
mono_error_assert_ok (error);

if (state == PARSING_MIBC_CONFIG_RUNTIME_FIELD)
isConfigCompatible = !strcmp(value, "Mono") || !strcmp(value, "4");
mdh1418 marked this conversation as resolved.
Show resolved Hide resolved

if (!strcmp(value, "Runtime"))
state = PARSING_MIBC_CONFIG_RUNTIME_FIELD;
else
state = PARSING_MIBC_CONFIG_NONE;

g_free (value);
}

return isConfigCompatible;
}

//---------------------------------------------------------------------------------------
//
// add_mibc_profile_methods is the overarching method that adds methods within a .mibc
// profile file to be compiled ahead of time. .mibc is a portable executable with
// methods grouped under mibcGroupMethods, which are summarized within the global
// function AssemblyDictionary. This method obtains the AssemblyDictionary and iterates
// over il opcodes and arguments to retrieve mibcGroupMethods and thereafter calls
// add_mibc_group_method_methods.
// add_mibc_group_method_methods. A .mibc also may contain a MibcConfig, which we
// check for compatibility with mono.
//
// Sample AssemblyDictionary format
//
Expand Down Expand Up @@ -13389,6 +13491,11 @@ add_mibc_profile_methods (MonoAotCompile *acfg, char *filename)
MonoClass *mibcModuleClass = mono_class_from_name_checked (image, "", "<Module>", error);
mono_error_assert_ok (error);

if (!compatible_mibc_profile_config (image, mibcModuleClass)) {
aot_printf (acfg, "Skipping .mibc profile '%s' as it is not compatible with the mono runtime. The MibcConfig within the .mibc does not record the Runtime flavor 'Mono'.\n", filename);
return;
}

MonoMethod *assemblyDictionary = mono_class_get_method_from_name_checked (mibcModuleClass, "AssemblyDictionary", 0, 0, error);
MonoGenericContext *context = mono_method_get_context (assemblyDictionary);
mono_error_assert_ok (error);
Expand Down