Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono][interp] Refactor icall opcodes #87269

Merged
merged 8 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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