From 33fe18560b8448a164350643a3dfe29101528d0f Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 29 Feb 2024 15:39:16 +0200 Subject: [PATCH 1/3] [mono][interp] Intrinsify SpanHelpers.ClearWithoutReferences Also rename MINT_INITOBJ to MINT_ZEROBLK_IMM for consistency. --- src/mono/mono/mini/interp/interp.c | 6 +++++- src/mono/mono/mini/interp/mintops.def | 3 ++- src/mono/mono/mini/interp/transform-opt.c | 6 +++--- src/mono/mono/mini/interp/transform.c | 11 +++++++---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index c16afc494011fd..070278d2cd0e84 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -7618,7 +7618,11 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; /* top of stack is result of filter */ frame->retval->data.i = LOCAL_VAR (ip [1], gint32); goto exit_clause; - MINT_IN_CASE(MINT_INITOBJ) + MINT_IN_CASE(MINT_ZEROBLK) + memset (LOCAL_VAR (ip [1], gpointer), 0, LOCAL_VAR (ip [2], gsize)); + ip += 3; + MINT_IN_BREAK; + MINT_IN_CASE(MINT_ZEROBLK_IMM) memset (LOCAL_VAR (ip [1], gpointer), 0, ip [2]); ip += 3; MINT_IN_BREAK; diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index afd4bf10dea60d..87108ca73bff38 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -363,7 +363,8 @@ OPDEF(MINT_NEWOBJ_STRING, "newobj_string", 4, 1, 1, MintOpMethodToken) OPDEF(MINT_NEWOBJ, "newobj", 5, 1, 1, MintOpMethodToken) OPDEF(MINT_NEWOBJ_INLINED, "newobj_inlined", 3, 1, 0, MintOpVTableToken) OPDEF(MINT_NEWOBJ_VT, "newobj_vt", 5, 1, 1, MintOpMethodToken) -OPDEF(MINT_INITOBJ, "initobj", 3, 0, 1, MintOpShortInt) +OPDEF(MINT_ZEROBLK, "zeroblk", 3, 0, 2, MintOpNoArgs) +OPDEF(MINT_ZEROBLK_IMM, "zeroblk_imm", 3, 0, 1, MintOpShortInt) OPDEF(MINT_CASTCLASS, "castclass", 4, 1, 1, MintOpClassToken) OPDEF(MINT_ISINST, "isinst", 4, 1, 1, MintOpClassToken) OPDEF(MINT_CASTCLASS_INTERFACE, "castclass.interface", 4, 1, 1, MintOpClassToken) diff --git a/src/mono/mono/mini/interp/transform-opt.c b/src/mono/mono/mini/interp/transform-opt.c index 41473cabb0aabf..1b5e2b7a026b8b 100644 --- a/src/mono/mono/mini/interp/transform-opt.c +++ b/src/mono/mono/mini/interp/transform-opt.c @@ -3041,12 +3041,12 @@ interp_cprop (TransformData *td) interp_dump_ins (ins, td->data_items); } } - } else if (opcode == MINT_INITOBJ) { + } else if (opcode == MINT_ZEROBLK_IMM) { InterpInst *ldloca = get_var_value_def (td, sregs [0]); if (ldloca != NULL && ldloca->opcode == MINT_LDLOCA_S) { int size = ins->data [0]; int local = ldloca->sregs [0]; - // Replace LDLOCA + INITOBJ with or LDC + // Replace LDLOCA + ZEROBLK_IMM with or LDC if (size <= 4) ins->opcode = MINT_LDC_I4_0; else if (size <= 8) @@ -3057,7 +3057,7 @@ interp_cprop (TransformData *td) ins->dreg = local; if (td->verbose_level) { - g_print ("Replace ldloca/initobj pair :\n\t"); + g_print ("Replace ldloca/zeroblk pair :\n\t"); interp_dump_ins (ins, td->data_items); } } diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index ac654631313fe7..1df4795a0432cb 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -1938,9 +1938,12 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas } } else if (in_corlib && !strcmp (klass_name_space, "System") && - !strcmp (klass_name, "SpanHelpers") && - !strcmp (tm, "ClearWithReferences")) { - *op = MINT_INTRINS_CLEAR_WITH_REFERENCES; + !strcmp (klass_name, "SpanHelpers")) { + if (!strcmp (tm, "ClearWithReferences")) { + *op = MINT_INTRINS_CLEAR_WITH_REFERENCES; + } else if (!strcmp (tm, "ClearWithoutReferences")) { + *op = MINT_ZEROBLK; + } } else if (in_corlib && !strcmp (klass_name_space, "System") && !strcmp (klass_name, "Marvin")) { if (!strcmp (tm, "Block")) { InterpInst *ldloca2 = td->last_ins; @@ -8125,7 +8128,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, CHECK_TYPELOAD (klass); if (m_class_is_valuetype (klass)) { --td->sp; - interp_add_ins (td, MINT_INITOBJ); + interp_add_ins (td, MINT_ZEROBLK_IMM); interp_ins_set_sreg (td->last_ins, td->sp [0].var); i32 = mono_class_value_size (klass, NULL); g_assert (i32 < G_MAXUINT16); From 7456a63a8a5c063864e6c7f5e09b2a8324cf27d7 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 29 Feb 2024 16:12:44 +0200 Subject: [PATCH 2/3] [mono][interp] Intrinsify SpanHelpers.Fill for 1 byte element size --- src/mono/mono/mini/interp/transform.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 1df4795a0432cb..d791ea9d579e4d 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -1943,6 +1943,15 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas *op = MINT_INTRINS_CLEAR_WITH_REFERENCES; } else if (!strcmp (tm, "ClearWithoutReferences")) { *op = MINT_ZEROBLK; + } else if (!strcmp (tm, "Fill") && csignature->param_count == 3) { + int align; + if (mono_type_size (csignature->params [2], &align) == 1) { + interp_add_ins (td, MINT_INITBLK); + td->sp -= 3; + interp_ins_set_sregs3 (td->last_ins, td->sp [0].var, td->sp [2].var, td->sp [1].var); + td->ip += 5; + return TRUE; + } } } else if (in_corlib && !strcmp (klass_name_space, "System") && !strcmp (klass_name, "Marvin")) { if (!strcmp (tm, "Block")) { From 256696d8ecfdd40760eb362e2435bf0a50c3b681 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 29 Feb 2024 13:19:21 -0800 Subject: [PATCH 3/3] Update jiterpreter --- .../runtime/jiterpreter-trace-generator.ts | 15 ++++++++++++++- .../mono/mini/interp/jiterpreter-opcode-values.h | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/mono/browser/runtime/jiterpreter-trace-generator.ts b/src/mono/browser/runtime/jiterpreter-trace-generator.ts index f8ac833956ff69..9b3002eae107ab 100644 --- a/src/mono/browser/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/browser/runtime/jiterpreter-trace-generator.ts @@ -378,7 +378,20 @@ export function generateWasmBody( builder.callImport("localloc"); break; } - case MintOpcode.MINT_INITOBJ: { + case MintOpcode.MINT_ZEROBLK: { + // dest + append_ldloc(builder, getArgU16(ip, 1), WasmOpcode.i32_load); + // value + builder.i32_const(0); + // count + append_ldloc(builder, getArgU16(ip, 2), WasmOpcode.i32_load); + // memset + builder.appendU8(WasmOpcode.PREFIX_sat); + builder.appendU8(11); + builder.appendU8(0); + break; + } + case MintOpcode.MINT_ZEROBLK_IMM: { append_ldloc(builder, getArgU16(ip, 1), WasmOpcode.i32_load); append_memset_dest(builder, 0, getArgU16(ip, 2)); break; diff --git a/src/mono/mono/mini/interp/jiterpreter-opcode-values.h b/src/mono/mono/mini/interp/jiterpreter-opcode-values.h index bf9965dc148a5f..fb677b438d3871 100644 --- a/src/mono/mono/mini/interp/jiterpreter-opcode-values.h +++ b/src/mono/mono/mini/interp/jiterpreter-opcode-values.h @@ -132,7 +132,8 @@ OP(MINT_INTRINS_MEMORYMARSHAL_GETARRAYDATAREF, HIGH) OP(MINT_INITLOCAL, MASSIVE) OP(MINT_INITLOCALS, MASSIVE) OP(MINT_LOCALLOC, NORMAL) -OP(MINT_INITOBJ, MASSIVE) +OP(MINT_ZEROBLK, MASSIVE) +OP(MINT_ZEROBLK_IMM, HIGH) OP(MINT_INTRINS_RUNTIMEHELPERS_OBJECT_HAS_COMPONENT_SIZE, HIGH) OP(MINT_INTRINS_ENUM_HASFLAG, HIGH) OP(MINT_INTRINS_ORDINAL_IGNORE_CASE_ASCII, HIGH)