[interp] break up MINT_LDSTR_TOKEN into two opcodes (#88738)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Wed, 12 Jul 2023 17:22:55 +0000 (13:22 -0400)
committerGitHub <noreply@github.com>
Wed, 12 Jul 2023 17:22:55 +0000 (13:22 -0400)
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
src/mono/mono/mini/interp/mintops.def
src/mono/mono/mini/interp/transform.c

index 6b2e341..4ca6be9 100644 (file)
@@ -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;
index e0472a8..5352b65 100644 (file)
@@ -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)
 
index 6c35a7b..32c9b2e 100644 (file)
@@ -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;