Skip to content

Commit

Permalink
[mono][interp] Refactor icall opcodes (#87269)
Browse files Browse the repository at this point in the history
* [mono][interp] Use MINT_CALLI_NAT_FAST opcode instead of MINT_ICALL_*

MINT_ICALL_* opcodes are pretty much dead and untested

* [mono][interp] Remove duplicated code

* [mono][interp] Add new generic icall opcode

Having the signature hardcoded in the opcode seems overkill for icalls.

* [mono][interp] Remove per signature CALLI opcodes

* Remove code in jiterp

* [mono][interp] Rename defines

* [mono][interp] Opcode data consistency

* [mono][interp] Fix jiterp build
  • Loading branch information
BrzVlad authored Jun 15, 2023
1 parent fe866e6 commit 48da5c0
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 157 deletions.
73 changes: 30 additions & 43 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2214,91 +2214,91 @@ interp_entry (InterpEntryData *data)
}

static void
do_icall (MonoMethodSignature *sig, int op, stackval *ret_sp, stackval *sp, gpointer ptr, gboolean save_last_error)
do_icall (MonoMethodSignature *sig, MintICallSig op, stackval *ret_sp, stackval *sp, gpointer ptr, gboolean save_last_error)
{
if (save_last_error)
mono_marshal_clear_last_error ();

switch (op) {
case MINT_ICALL_V_V: {
case MINT_ICALLSIG_V_V: {
typedef void (*T)(void);
T func = (T)ptr;
func ();
break;
}
case MINT_ICALL_V_P: {
case MINT_ICALLSIG_V_P: {
typedef gpointer (*T)(void);
T func = (T)ptr;
ret_sp->data.p = func ();
break;
}
case MINT_ICALL_P_V: {
case MINT_ICALLSIG_P_V: {
typedef void (*T)(gpointer);
T func = (T)ptr;
func (sp [0].data.p);
break;
}
case MINT_ICALL_P_P: {
case MINT_ICALLSIG_P_P: {
typedef gpointer (*T)(gpointer);
T func = (T)ptr;
ret_sp->data.p = func (sp [0].data.p);
break;
}
case MINT_ICALL_PP_V: {
case MINT_ICALLSIG_PP_V: {
typedef void (*T)(gpointer,gpointer);
T func = (T)ptr;
func (sp [0].data.p, sp [1].data.p);
break;
}
case MINT_ICALL_PP_P: {
case MINT_ICALLSIG_PP_P: {
typedef gpointer (*T)(gpointer,gpointer);
T func = (T)ptr;
ret_sp->data.p = func (sp [0].data.p, sp [1].data.p);
break;
}
case MINT_ICALL_PPP_V: {
case MINT_ICALLSIG_PPP_V: {
typedef void (*T)(gpointer,gpointer,gpointer);
T func = (T)ptr;
func (sp [0].data.p, sp [1].data.p, sp [2].data.p);
break;
}
case MINT_ICALL_PPP_P: {
case MINT_ICALLSIG_PPP_P: {
typedef gpointer (*T)(gpointer,gpointer,gpointer);
T func = (T)ptr;
ret_sp->data.p = func (sp [0].data.p, sp [1].data.p, sp [2].data.p);
break;
}
case MINT_ICALL_PPPP_V: {
case MINT_ICALLSIG_PPPP_V: {
typedef void (*T)(gpointer,gpointer,gpointer,gpointer);
T func = (T)ptr;
func (sp [0].data.p, sp [1].data.p, sp [2].data.p, sp [3].data.p);
break;
}
case MINT_ICALL_PPPP_P: {
case MINT_ICALLSIG_PPPP_P: {
typedef gpointer (*T)(gpointer,gpointer,gpointer,gpointer);
T func = (T)ptr;
ret_sp->data.p = func (sp [0].data.p, sp [1].data.p, sp [2].data.p, sp [3].data.p);
break;
}
case MINT_ICALL_PPPPP_V: {
case MINT_ICALLSIG_PPPPP_V: {
typedef void (*T)(gpointer,gpointer,gpointer,gpointer,gpointer);
T func = (T)ptr;
func (sp [0].data.p, sp [1].data.p, sp [2].data.p, sp [3].data.p, sp [4].data.p);
break;
}
case MINT_ICALL_PPPPP_P: {
case MINT_ICALLSIG_PPPPP_P: {
typedef gpointer (*T)(gpointer,gpointer,gpointer,gpointer,gpointer);
T func = (T)ptr;
ret_sp->data.p = func (sp [0].data.p, sp [1].data.p, sp [2].data.p, sp [3].data.p, sp [4].data.p);
break;
}
case MINT_ICALL_PPPPPP_V: {
case MINT_ICALLSIG_PPPPPP_V: {
typedef void (*T)(gpointer,gpointer,gpointer,gpointer,gpointer,gpointer);
T func = (T)ptr;
func (sp [0].data.p, sp [1].data.p, sp [2].data.p, sp [3].data.p, sp [4].data.p, sp [5].data.p);
break;
}
case MINT_ICALL_PPPPPP_P: {
case MINT_ICALLSIG_PPPPPP_P: {
typedef gpointer (*T)(gpointer,gpointer,gpointer,gpointer,gpointer,gpointer);
T func = (T)ptr;
ret_sp->data.p = func (sp [0].data.p, sp [1].data.p, sp [2].data.p, sp [3].data.p, sp [4].data.p, sp [5].data.p);
Expand All @@ -2322,7 +2322,7 @@ do_icall (MonoMethodSignature *sig, int op, stackval *ret_sp, stackval *sp, gpoi
#endif
// Do not inline in case order of frame addresses matters, and maybe other reasons.
static MONO_NO_OPTIMIZATION MONO_NEVER_INLINE gpointer
do_icall_wrapper (InterpFrame *frame, MonoMethodSignature *sig, int op, stackval *ret_sp, stackval *sp, gpointer ptr, gboolean save_last_error, gboolean *gc_transitions)
do_icall_wrapper (InterpFrame *frame, MonoMethodSignature *sig, MintICallSig op, stackval *ret_sp, stackval *sp, gpointer ptr, gboolean save_last_error, gboolean *gc_transitions)
{
MonoLMFExt ext;
INTERP_PUSH_LMF_WITH_CTX (frame, ext, exit_icall);
Expand Down Expand Up @@ -3545,7 +3545,7 @@ mono_interp_leave (InterpFrame* parent_frame)
* to check the abort threshold. For this to work we use frame as a
* dummy frame that is stored in the lmf and serves as the transition frame
*/
do_icall_wrapper (&frame, NULL, MINT_ICALL_V_P, &tmp_sp, &tmp_sp, (gpointer)mono_thread_get_undeniable_exception, FALSE, &gc_transitions);
do_icall_wrapper (&frame, NULL, MINT_ICALLSIG_V_P, &tmp_sp, &tmp_sp, (gpointer)mono_thread_get_undeniable_exception, FALSE, &gc_transitions);

return (MonoException*)tmp_sp.data.p;
}
Expand Down Expand Up @@ -4051,8 +4051,8 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
goto call;
}
MINT_IN_CASE(MINT_CALLI_NAT_FAST) {
MonoMethodSignature *csignature = (MonoMethodSignature*)frame->imethod->data_items [ip [4]];
int icall_opcode = ip [5];
MintICallSig icall_sig = (MintICallSig)ip [4];
MonoMethodSignature *csignature = (MonoMethodSignature*)frame->imethod->data_items [ip [5]];
gboolean save_last_error = ip [6];

stackval *ret = (stackval*)(locals + ip [1]);
Expand All @@ -4061,7 +4061,7 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
/* for calls, have ip pointing at the start of next instruction */
frame->state.ip = ip + 7;

do_icall_wrapper (frame, csignature, icall_opcode , ret, args, target_ip, save_last_error, &gc_transitions);
do_icall_wrapper (frame, csignature, icall_sig, ret, args, target_ip, save_last_error, &gc_transitions);
EXCEPTION_CHECKPOINT;
CHECK_RESUME_STATE (context);
ip += 7;
Expand Down Expand Up @@ -6955,32 +6955,19 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
ip += short_offset ? (gint16)*(ip + 1) : (gint32)READ32 (ip + 1);
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_ICALL_V_V)
MINT_IN_CASE(MINT_ICALL_P_V)
MINT_IN_CASE(MINT_ICALL_PP_V)
MINT_IN_CASE(MINT_ICALL_PPP_V)
MINT_IN_CASE(MINT_ICALL_PPPP_V)
MINT_IN_CASE(MINT_ICALL_PPPPP_V)
MINT_IN_CASE(MINT_ICALL_PPPPPP_V)
frame->state.ip = ip + 3;
do_icall_wrapper (frame, NULL, *ip, NULL, (stackval*)(locals + ip [1]), frame->imethod->data_items [ip [2]], FALSE, &gc_transitions);
EXCEPTION_CHECKPOINT;
CHECK_RESUME_STATE (context);
ip += 3;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_ICALL_V_P)
MINT_IN_CASE(MINT_ICALL_P_P)
MINT_IN_CASE(MINT_ICALL_PP_P)
MINT_IN_CASE(MINT_ICALL_PPP_P)
MINT_IN_CASE(MINT_ICALL_PPPP_P)
MINT_IN_CASE(MINT_ICALL_PPPPP_P)
MINT_IN_CASE(MINT_ICALL_PPPPPP_P)
frame->state.ip = ip + 4;
do_icall_wrapper (frame, NULL, *ip, (stackval*)(locals + ip [1]), (stackval*)(locals + ip [2]), frame->imethod->data_items [ip [3]], FALSE, &gc_transitions);
MINT_IN_CASE(MINT_ICALL) {
stackval *ret = (stackval*)(locals + ip [1]);
stackval *args = (stackval*)(locals + ip [2]);
MintICallSig icall_sig = (MintICallSig)ip [3];
gpointer target_ip = frame->imethod->data_items [ip [4]];

frame->state.ip = ip + 5;
do_icall_wrapper (frame, NULL, icall_sig, ret, args, target_ip, FALSE, &gc_transitions);
EXCEPTION_CHECKPOINT;
CHECK_RESUME_STATE (context);
ip += 4;
ip += 5;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_LDPTR)
LOCAL_VAR (ip [1], gpointer) = frame->imethod->data_items [ip [2]];
ip += 3;
Expand Down
6 changes: 0 additions & 6 deletions src/mono/mono/mini/interp/jiterpreter-opcode-values.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,6 @@ OP(MINT_SHL_AND_I8, HIGH)
// information, so treat it as a low value branch
OP(MINT_ENDFINALLY, BRANCH)

OP(MINT_ICALL_V_P, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)
OP(MINT_ICALL_V_V, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)
OP(MINT_ICALL_P_P, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)
OP(MINT_ICALL_P_V, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)
OP(MINT_ICALL_PP_V, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)
OP(MINT_ICALL_PP_P, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)
OP(MINT_MONO_RETHROW, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)
OP(MINT_THROW, ABORT_OUTSIDE_BRANCH_BLOCK_NONE)

Expand Down
15 changes: 1 addition & 14 deletions src/mono/mono/mini/interp/mintops.def
Original file line number Diff line number Diff line change
Expand Up @@ -695,20 +695,7 @@ OPDEF(MINT_CALL_VARARG, "call.vararg", 6, 1, 1, MintOpMethodToken)
OPDEF(MINT_TAILCALL, "tailcall", 4, 0, 1, MintOpMethodToken)
OPDEF(MINT_TAILCALL_VIRT, "tailcall.virt", 5, 0, 1, MintOpMethodToken)

OPDEF(MINT_ICALL_V_V, "mono_icall_v_v", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_ICALL_V_P, "mono_icall_v_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_ICALL_P_V, "mono_icall_p_v", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_ICALL_P_P, "mono_icall_p_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PP_V, "mono_icall_pp_v", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PP_P, "mono_icall_pp_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPP_V, "mono_icall_ppp_v", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPP_P, "mono_icall_ppp_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPPP_V, "mono_icall_pppp_v", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPPP_P, "mono_icall_pppp_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPPPP_V, "mono_icall_ppppp_v", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPPPP_P, "mono_icall_ppppp_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPPPPP_V, "mono_icall_pppppp_v", 3, 0, 1, MintOpShortInt)
OPDEF(MINT_ICALL_PPPPPP_P, "mono_icall_pppppp_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_ICALL, "mono_icall", 5, 1, 1, MintOpTwoShorts)
// FIXME: MintOp
OPDEF(MINT_JIT_CALL, "mono_jit_call", 4, 1, 1, MintOpNoArgs)
OPDEF(MINT_JIT_CALL2, "mono_jit_call2", 7, 1, 1, MintOpNoArgs)
Expand Down
18 changes: 18 additions & 0 deletions src/mono/mono/mini/interp/mintops.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,24 @@ typedef enum {

#define MINT_MOV_PAIRS_MAX 4

typedef enum {
MINT_ICALLSIG_V_V = 0,
MINT_ICALLSIG_V_P,
MINT_ICALLSIG_P_V,
MINT_ICALLSIG_P_P,
MINT_ICALLSIG_PP_V,
MINT_ICALLSIG_PP_P,
MINT_ICALLSIG_PPP_V,
MINT_ICALLSIG_PPP_P,
MINT_ICALLSIG_PPPP_V,
MINT_ICALLSIG_PPPP_P,
MINT_ICALLSIG_PPPPP_V,
MINT_ICALLSIG_PPPPP_P,
MINT_ICALLSIG_PPPPPP_V,
MINT_ICALLSIG_PPPPPP_P,
MINT_ICALLSIG_MAX
} MintICallSig;

extern unsigned char const mono_interp_oplen[];
extern int const mono_interp_op_dregs [];
extern int const mono_interp_op_sregs [];
Expand Down
Loading

0 comments on commit 48da5c0

Please sign in to comment.