Skip to content

Commit

Permalink
[interp] Add MINT_STELEM_VT_NOREF (#87161)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kg authored Jul 8, 2023
1 parent 57608c3 commit e05b3e7
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -6505,6 +6505,19 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
ip += 6;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_STELEM_VT_NOREF) {
MonoArray *o = LOCAL_VAR (ip [1], MonoArray*);
NULL_CHECK (o);
guint32 aindex = LOCAL_VAR (ip [2], guint32);
if (aindex >= mono_array_length_internal (o))
THROW_EX (interp_get_exception_index_out_of_range (frame, ip), ip);

guint16 size = ip [5];
char *dst_addr = mono_array_addr_with_size_fast ((MonoArray *) o, size, aindex);
memcpy (dst_addr, locals + ip [3], size);
ip += 6;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_CONV_OVF_I4_U4) {
gint32 val = LOCAL_VAR (ip [2], gint32);
if (val < 0)
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/interp/mintops.def
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ OPDEF(MINT_STELEM_R4, "stelem.r4", 4, 0, 3, MintOpNoArgs)
OPDEF(MINT_STELEM_R8, "stelem.r8", 4, 0, 3, MintOpNoArgs)
OPDEF(MINT_STELEM_REF, "stelem.ref", 4, 0, 3, MintOpNoArgs)
OPDEF(MINT_STELEM_VT, "stelem.vt", 6, 0, 3, MintOpTwoShorts)
OPDEF(MINT_STELEM_VT_NOREF, "stelem.vt.noref", 6, 0, 3, MintOpTwoShorts)

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

Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -7095,7 +7095,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
int size = mono_class_value_size (klass, NULL);
g_assert (size < G_MAXUINT16);

handle_stelem (td, MINT_STELEM_VT);
handle_stelem (td, m_class_has_references (klass) ? MINT_STELEM_VT : MINT_STELEM_VT_NOREF);
td->last_ins->data [0] = get_data_item_index (td, klass);
td->last_ins->data [1] = GINT_TO_UINT16 (size);
break;
Expand Down
9 changes: 9 additions & 0 deletions src/mono/wasm/runtime/jiterpreter-trace-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3316,6 +3316,15 @@ function emit_arrayop(builder: WasmBuilder, frame: NativePointer, ip: MintOpcode
builder.callImport("value_copy");
return true;
}
case MintOpcode.MINT_STELEM_VT_NOREF: {
const elementSize = getArgU16(ip, 5);
// dest
append_getelema1(builder, ip, objectOffset, indexOffset, elementSize);
// src
append_ldloca(builder, valueOffset, 0);
append_memmove_dest_src(builder, elementSize);
return true;
}
default:
return false;
}
Expand Down

0 comments on commit e05b3e7

Please sign in to comment.