Skip to content

Commit

Permalink
[mono][interp] Replace ldobj.vt + stobj.vt.noref pair with cpobj.vt.n…
Browse files Browse the repository at this point in the history
…oref (#79302)

* [mono][interp] Add new cpobj version that doesn't require card marking

* [mono][interp] Replace ldobj.vt + stobj.vt.noref pair with cpobj.vt.noref
  • Loading branch information
BrzVlad authored Dec 7, 2022
1 parent be63af2 commit 0116323
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5514,6 +5514,13 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
ip += 4;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_CPOBJ_VT_NOREF) {
gpointer src_addr = LOCAL_VAR (ip [2], gpointer);
NULL_CHECK (src_addr);
memcpy (LOCAL_VAR (ip [1], gpointer), src_addr, ip [3]);
ip += 4;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_LDOBJ_VT) {
guint16 size = ip [3];
gpointer srcAddr = LOCAL_VAR (ip [2], gpointer);
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 @@ -380,6 +380,7 @@ OPDEF(MINT_LDFTN_DYNAMIC, "ldftn.dynamic", 3, 1, 1, MintOpMethodToken)
OPDEF(MINT_LDVIRTFTN, "ldvirtftn", 4, 1, 1, MintOpMethodToken)
OPDEF(MINT_CPOBJ, "cpobj", 4, 0, 2, MintOpClassToken)
OPDEF(MINT_CPOBJ_VT, "cpobj.vt", 4, 0, 2, MintOpClassToken)
OPDEF(MINT_CPOBJ_VT_NOREF, "cpobj.vt.noref", 4, 0, 2, MintOpUShortInt)
OPDEF(MINT_LDOBJ_VT, "ldobj.vt", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_STOBJ_VT, "stobj.vt", 4, 0, 2, MintOpClassToken)
OPDEF(MINT_STOBJ_VT_NOREF, "stobj.vt.noref", 4, 0, 2, MintOpShortInt)
Expand Down
27 changes: 25 additions & 2 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -5650,9 +5650,14 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
if (m_class_is_valuetype (klass)) {
mt = mint_type (m_class_get_byval_arg (klass));
td->sp -= 2;
interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_CPOBJ_VT : MINT_CPOBJ);
if (mt == MINT_TYPE_VT && !m_class_has_references (klass)) {
interp_add_ins (td, MINT_CPOBJ_VT_NOREF);
td->last_ins->data [0] = GINT32_TO_UINT16 (mono_class_value_size (klass, NULL));
} else {
interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_CPOBJ_VT : MINT_CPOBJ);
td->last_ins->data [0] = get_data_item_index (td, klass);
}
interp_ins_set_sregs2 (td->last_ins, td->sp [0].local, td->sp [1].local);
td->last_ins->data [0] = get_data_item_index(td, klass);
} else {
td->sp--;
interp_add_ins (td, MINT_LDIND_I);
Expand Down Expand Up @@ -9433,6 +9438,24 @@ interp_super_instructions (TransformData *td)
}

}
} else if (opcode == MINT_STOBJ_VT_NOREF) {
int sreg_src = ins->sregs [1];
InterpInst *def = td->locals [sreg_src].def;
if (def != NULL && interp_prev_ins (ins) == def && def->opcode == MINT_LDOBJ_VT && ins->data [0] == def->data [0] && td->local_ref_count [sreg_src] == 1) {
InterpInst *new_inst = interp_insert_ins (td, ins, MINT_CPOBJ_VT_NOREF);
new_inst->sregs [0] = ins->sregs [0]; // dst
new_inst->sregs [1] = def->sregs [0]; // src
new_inst->data [0] = ins->data [0]; // size

interp_clear_ins (def);
interp_clear_ins (ins);
local_ref_count [sreg_src]--;
mono_interp_stats.super_instructions++;
if (td->verbose_level) {
g_print ("superins: ");
dump_interp_inst (new_inst);
}
}
}
noe += get_inst_length (ins);
}
Expand Down

0 comments on commit 0116323

Please sign in to comment.