From 5b4ffc07531c860d0cafb1d2cff95c9bc8c91664 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Wed, 12 Jul 2023 13:22:55 -0400 Subject: [PATCH] [interp] break up MINT_LDSTR_TOKEN into two opcodes (#88738) MINT_LDSTR_DYNAMIC for dynamic methods. the data item is an index into the DynamicMethod:method.method_data which stores pointers to MonoString objects that are held by the managed DynamicMethod. MINT_LDSTR_CSTR for ilgen wrappers. the data item is a raw C string that is global, or was allocated by malloc Fixes https://github.com/dotnet/runtime/issues/88694 by allowing MINT_LDSTR_CSTR in any method since we no longer depend on mono_method_get_wrapper_data at execution time. And at transform time we have access to the actual wrapper method. --- src/mono/mono/mini/interp/interp.c | 22 +++++++++++++--------- src/mono/mono/mini/interp/mintops.def | 3 ++- src/mono/mono/mini/interp/transform.c | 19 ++++++++++++++++--- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 6b2e341..4ca6be9 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -5573,19 +5573,23 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; LOCAL_VAR (ip [1], gpointer) = frame->imethod->data_items [ip [2]]; ip += 3; MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDSTR_TOKEN) { + MINT_IN_CASE(MINT_LDSTR_DYNAMIC) { MonoString *s = NULL; guint32 strtoken = (guint32)(gsize)frame->imethod->data_items [ip [2]]; MonoMethod *method = frame->imethod->method; - if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) { - s = (MonoString*)mono_method_get_wrapper_data (method, strtoken); - } else if (method->wrapper_type != MONO_WRAPPER_NONE) { - // FIXME push/pop LMF - s = mono_string_new_wrapper_internal ((const char*)mono_method_get_wrapper_data (method, strtoken)); - } else { - g_assert_not_reached (); - } + g_assert (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD); + s = (MonoString*)mono_method_get_wrapper_data (method, strtoken); + LOCAL_VAR (ip [1], gpointer) = s; + ip += 3; + MINT_IN_BREAK; + } + MINT_IN_CASE(MINT_LDSTR_CSTR) { + MonoString *s = NULL; + const char* cstr = (const char*)frame->imethod->data_items [ip [2]]; + + // FIXME push/pop LMF + s = mono_string_new_wrapper_internal (cstr); LOCAL_VAR (ip [1], gpointer) = s; ip += 3; MINT_IN_BREAK; diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index e0472a8..5352b65 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -347,7 +347,8 @@ OPDEF(MINT_BLT_UN_I8_IMM_SP, "blt.un.i8.imm.sp", 4, 0, 1, MintOpShortAndShortBra OPDEF(MINT_SWITCH, "switch", 0, 0, 1, MintOpSwitch) OPDEF(MINT_LDSTR, "ldstr", 3, 1, 0, MintOpShortInt) -OPDEF(MINT_LDSTR_TOKEN, "ldstr.token", 3, 1, 0, MintOpShortInt) +OPDEF(MINT_LDSTR_DYNAMIC, "ldstr.dynamic", 3, 1, 0, MintOpShortInt) +OPDEF(MINT_LDSTR_CSTR, "ldstr.cstr", 3, 1, 0, MintOpShortInt) OPDEF(MINT_JMP, "jmp", 2, 0, 0, MintOpMethodToken) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 6c35a7b..32c9b2e 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -6106,11 +6106,24 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, interp_add_ins (td, MINT_LDSTR); interp_ins_set_dreg (td->last_ins, td->sp [-1].local); td->last_ins->data [0] = get_data_item_index (td, s); - } else { - /* defer allocation to execution-time */ - interp_add_ins (td, MINT_LDSTR_TOKEN); + } else if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) { + /* token is an index into the MonoDynamicMethod:method.method_data + * which comes from ReflectionMethodBuilder:refs. See + * reflection_methodbuilder_to_mono_method. + * + * the actual data item is a managed MonoString from the managed DynamicMethod + */ + interp_add_ins (td, MINT_LDSTR_DYNAMIC); interp_ins_set_dreg (td->last_ins, td->sp [-1].local); td->last_ins->data [0] = get_data_item_index (td, GUINT_TO_POINTER (token)); + } else { + /* the token is an index into MonoWrapperMethod:method_data that + * stores a global or malloc'ed C string. defer MonoString + * allocation to execution-time */ + interp_add_ins (td, MINT_LDSTR_CSTR); + interp_ins_set_dreg (td->last_ins, td->sp [-1].local); + const char *cstr = (const char*)mono_method_get_wrapper_data (method, token); + td->last_ins->data [0] = get_data_item_index (td, (void*)cstr); } td->ip += 5; break; -- 2.7.4