Skip to content

Commit

Permalink
[interp] Small improvements around ByReference ctor (dotnet#38561)
Browse files Browse the repository at this point in the history
* [interp] Add stfld opcode for storing valuetypes without refs

* [interp] Remove MINT_VTRESULT use with byrefernce ctor intrinsic
  • Loading branch information
BrzVlad authored Jun 30, 2020
1 parent 2573c96 commit af28bfa
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
19 changes: 17 additions & 2 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5202,8 +5202,8 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
gpointer *byreference_this = (gpointer*)vt_sp;
*byreference_this = arg0;

/* Followed by a VTRESULT opcode which will push the result on the stack */
/* FIXME kill MINT_VTRESULT */
sp [-1].data.p = vt_sp;
vt_sp += MINT_VT_ALIGNMENT;
ip++;
MINT_IN_BREAK;
}
Expand Down Expand Up @@ -5514,6 +5514,21 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
MINT_IN_CASE(MINT_STFLD_I8_UNALIGNED) STFLD_UNALIGNED(l, gint64, TRUE); MINT_IN_BREAK;
MINT_IN_CASE(MINT_STFLD_R8_UNALIGNED) STFLD_UNALIGNED(f, double, TRUE); MINT_IN_BREAK;

MINT_IN_CASE(MINT_STFLD_VT_NOREF) {
MonoObject* const o = sp [-2].data.o;
NULL_CHECK (o);
sp -= 2;

guint16 offset = ip [1];
guint16 vtsize = ip [2];

memcpy ((char *) o + offset, sp [1].data.p, vtsize);

vt_sp -= ALIGN_TO (vtsize, MINT_VT_ALIGNMENT);
ip += 3;
MINT_IN_BREAK;
}

MINT_IN_CASE(MINT_STFLD_VT) {
MonoObject* const o = sp [-2].data.o;
NULL_CHECK (o);
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 @@ -138,6 +138,7 @@ OPDEF(MINT_STFLD_R4, "stfld.r4", 2, Pop2, Push0, MintOpUShortInt)
OPDEF(MINT_STFLD_R8, "stfld.r8", 2, Pop2, Push0, MintOpUShortInt)
OPDEF(MINT_STFLD_O, "stfld.o", 2, Pop2, Push0, MintOpUShortInt)
OPDEF(MINT_STFLD_VT, "stfld.vt", 3, Pop2, Push0, MintOpTwoShorts)
OPDEF(MINT_STFLD_VT_NOREF, "stfld.vt.noref", 3, Pop2, Push0, MintOpTwoShorts)
OPDEF(MINT_STFLD_I8_UNALIGNED, "stfld.i8.unaligned", 2, Pop2, Push0, MintOpUShortInt)
OPDEF(MINT_STFLD_R8_UNALIGNED, "stfld.r8.unaligned", 2, Pop2, Push0, MintOpUShortInt)

Expand Down
12 changes: 9 additions & 3 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -4731,7 +4731,9 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
vt_stack_used += size;
}
}
if (vt_stack_used != 0 || vt_res_size != 0) {
if ((vt_stack_used != 0 || vt_res_size != 0) &&
td->last_ins->opcode != MINT_INTRINS_BYREFERENCE_CTOR) {
/* FIXME Remove this once vtsp and sp are unified */
interp_add_ins (td, MINT_VTRESULT);
td->last_ins->data [0] = vt_res_size;
WRITE32_INS (td->last_ins, 1, &vt_stack_used);
Expand Down Expand Up @@ -5008,8 +5010,12 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
/* the vtable of the field might not be initialized at this point */
mono_class_vtable_checked (domain, field_klass, error);
goto_if_nok (error, exit);

td->last_ins->data [1] = get_data_item_index (td, field_klass);
if (m_class_has_references (field_klass)) {
td->last_ins->data [1] = get_data_item_index (td, field_klass);
} else {
td->last_ins->opcode = MINT_STFLD_VT_NOREF;
td->last_ins->data [1] = mono_class_value_size (field_klass, NULL);
}
}
}
}
Expand Down

0 comments on commit af28bfa

Please sign in to comment.