Skip to content

Commit e05b3e7

Browse files
authored
[interp] Add MINT_STELEM_VT_NOREF (dotnet#87161)
Based on instrumentation 0.2% of all mono_gc_wbarrier_value_copy_internal calls in a run of System.Runtime.Tests are from MINT_STELEM_VT. I suspect adding this NOREF version of the opcode will improve performance for data structures that store structs in arrays but don't contain any references - for example List<ValueTuple<...>> or Dictionary<int, int> - but it's hard to measure locally.
1 parent 57608c3 commit e05b3e7

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

src/mono/mono/mini/interp/interp.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6505,6 +6505,19 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
65056505
ip += 6;
65066506
MINT_IN_BREAK;
65076507
}
6508+
MINT_IN_CASE(MINT_STELEM_VT_NOREF) {
6509+
MonoArray *o = LOCAL_VAR (ip [1], MonoArray*);
6510+
NULL_CHECK (o);
6511+
guint32 aindex = LOCAL_VAR (ip [2], guint32);
6512+
if (aindex >= mono_array_length_internal (o))
6513+
THROW_EX (interp_get_exception_index_out_of_range (frame, ip), ip);
6514+
6515+
guint16 size = ip [5];
6516+
char *dst_addr = mono_array_addr_with_size_fast ((MonoArray *) o, size, aindex);
6517+
memcpy (dst_addr, locals + ip [3], size);
6518+
ip += 6;
6519+
MINT_IN_BREAK;
6520+
}
65086521
MINT_IN_CASE(MINT_CONV_OVF_I4_U4) {
65096522
gint32 val = LOCAL_VAR (ip [2], gint32);
65106523
if (val < 0)

src/mono/mono/mini/interp/mintops.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ OPDEF(MINT_STELEM_R4, "stelem.r4", 4, 0, 3, MintOpNoArgs)
419419
OPDEF(MINT_STELEM_R8, "stelem.r8", 4, 0, 3, MintOpNoArgs)
420420
OPDEF(MINT_STELEM_REF, "stelem.ref", 4, 0, 3, MintOpNoArgs)
421421
OPDEF(MINT_STELEM_VT, "stelem.vt", 6, 0, 3, MintOpTwoShorts)
422+
OPDEF(MINT_STELEM_VT_NOREF, "stelem.vt.noref", 6, 0, 3, MintOpTwoShorts)
422423

423424
OPDEF(MINT_LDLEN, "ldlen", 3, 1, 1, MintOpNoArgs)
424425

src/mono/mono/mini/interp/transform.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7095,7 +7095,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
70957095
int size = mono_class_value_size (klass, NULL);
70967096
g_assert (size < G_MAXUINT16);
70977097

7098-
handle_stelem (td, MINT_STELEM_VT);
7098+
handle_stelem (td, m_class_has_references (klass) ? MINT_STELEM_VT : MINT_STELEM_VT_NOREF);
70997099
td->last_ins->data [0] = get_data_item_index (td, klass);
71007100
td->last_ins->data [1] = GINT_TO_UINT16 (size);
71017101
break;

src/mono/wasm/runtime/jiterpreter-trace-generator.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3316,6 +3316,15 @@ function emit_arrayop(builder: WasmBuilder, frame: NativePointer, ip: MintOpcode
33163316
builder.callImport("value_copy");
33173317
return true;
33183318
}
3319+
case MintOpcode.MINT_STELEM_VT_NOREF: {
3320+
const elementSize = getArgU16(ip, 5);
3321+
// dest
3322+
append_getelema1(builder, ip, objectOffset, indexOffset, elementSize);
3323+
// src
3324+
append_ldloca(builder, valueOffset, 0);
3325+
append_memmove_dest_src(builder, elementSize);
3326+
return true;
3327+
}
33193328
default:
33203329
return false;
33213330
}

0 commit comments

Comments
 (0)