Skip to content

Commit

Permalink
[mono][interp] Intrinsify CreateSpan (#82093)
Browse files Browse the repository at this point in the history
* [mono][interp] Remove redundant opcode

* [mono][interp] Intrinsify CreateSpan
  • Loading branch information
BrzVlad authored Feb 15, 2023
1 parent 33e912d commit a979774
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 23 deletions.
7 changes: 1 addition & 6 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -6785,11 +6785,6 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
ip += 4;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_LDTOKEN)
// FIXME same as MINT_MONO_LDPTR
LOCAL_VAR (ip [1], gpointer) = frame->imethod->data_items [ip [2]];
ip += 3;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_ADD_OVF_I4) {
gint32 i1 = LOCAL_VAR (ip [2], gint32);
gint32 i2 = LOCAL_VAR (ip [3], gint32);
Expand Down Expand Up @@ -6966,7 +6961,7 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
CHECK_RESUME_STATE (context);
ip += 4;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_MONO_LDPTR)
MINT_IN_CASE(MINT_LDPTR)
LOCAL_VAR (ip [1], gpointer) = frame->imethod->data_items [ip [2]];
ip += 3;
MINT_IN_BREAK;
Expand Down
3 changes: 1 addition & 2 deletions src/mono/mono/mini/interp/jiterpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,10 @@ jiterp_should_abort_trace (InterpInst *ins, gboolean *inside_branch_block)
case MINT_INITOBJ:
case MINT_CKNULL:
case MINT_LDLOCA_S:
case MINT_LDTOKEN:
case MINT_LDSTR:
case MINT_LDFTN:
case MINT_LDFTN_ADDR:
case MINT_MONO_LDPTR:
case MINT_LDPTR:
case MINT_CPOBJ_VT:
case MINT_LDOBJ_VT:
case MINT_STOBJ_VT:
Expand Down
3 changes: 1 addition & 2 deletions src/mono/mono/mini/interp/mintops.def
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,6 @@ OPDEF(MINT_BOX_VT, "box.vt", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_BOX_PTR, "box.ptr", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_BOX_NULLABLE_PTR, "box.nullable.ptr", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_UNBOX, "unbox", 4, 1, 1, MintOpClassToken)
OPDEF(MINT_LDTOKEN, "ldtoken", 3, 1, 0, MintOpShortInt)
OPDEF(MINT_LDFTN, "ldftn", 3, 1, 0, MintOpMethodToken)
OPDEF(MINT_LDFTN_ADDR, "ldftn_addr", 3, 1, 0, MintOpMethodToken)
OPDEF(MINT_LDFTN_DYNAMIC, "ldftn.dynamic", 3, 1, 1, MintOpMethodToken)
Expand Down Expand Up @@ -714,7 +713,7 @@ OPDEF(MINT_ICALL_PPPPPP_P, "mono_icall_pppppp_p", 4, 1, 1, MintOpShortInt)
OPDEF(MINT_JIT_CALL, "mono_jit_call", 4, 1, 1, MintOpNoArgs)
OPDEF(MINT_JIT_CALL2, "mono_jit_call2", 7, 1, 1, MintOpNoArgs)

OPDEF(MINT_MONO_LDPTR, "mono_ldptr", 3, 1, 0, MintOpShortInt)
OPDEF(MINT_LDPTR, "mono_ldptr", 3, 1, 0, MintOpShortInt)
OPDEF(MINT_MONO_NEWOBJ, "mono_newobj", 3, 1, 0, MintOpClassToken)
OPDEF(MINT_MONO_RETOBJ, "mono_retobj", 2, 0, 1, MintOpNoArgs)
OPDEF(MINT_MONO_MEMORY_BARRIER, "mono_memory_barrier", 1, 0, 0, MintOpNoArgs)
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/interp/mintops.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ typedef enum {
#define MINT_IS_LDIND_OFFSET(op) ((op) >= MINT_LDIND_OFFSET_I1 && (op) <= MINT_LDIND_OFFSET_I8)

// TODO Add more
#define MINT_NO_SIDE_EFFECTS(op) (MINT_IS_MOV (op) || MINT_IS_LDC_I4 (op) || MINT_IS_LDC_I8 (op) || op == MINT_MONO_LDPTR)
#define MINT_NO_SIDE_EFFECTS(op) (MINT_IS_MOV (op) || MINT_IS_LDC_I4 (op) || MINT_IS_LDC_I8 (op) || op == MINT_LDPTR)

#define MINT_CALL_ARGS 2
#define MINT_CALL_ARGS_SREG -2
Expand Down
56 changes: 46 additions & 10 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1366,12 +1366,12 @@ interp_generate_mae_throw (TransformData *td, MonoMethod *method, MonoMethod *ta
MonoJitICallInfo *info = &mono_get_jit_icall_info ()->mono_throw_method_access;

/* Inject code throwing MethodAccessException */
interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
push_simple_type (td, STACK_TYPE_I);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, method);

interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
push_simple_type (td, STACK_TYPE_I);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, target_method);
Expand Down Expand Up @@ -1418,7 +1418,7 @@ interp_generate_ipe_throw_with_msg (TransformData *td, MonoError *error_msg)

char *msg = mono_mem_manager_strdup (td->mem_manager, mono_error_get_message (error_msg));

interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
push_simple_type (td, STACK_TYPE_I);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, msg);
Expand Down Expand Up @@ -2445,6 +2445,42 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
has_refs = m_class_has_references (klass);

*op = has_refs ? MINT_LDC_I4_1 : MINT_LDC_I4_0;
} else if (!strcmp (tm, "CreateSpan") && csignature->param_count == 1 &&
td->last_ins->opcode == MINT_LDPTR && td->last_ins->dreg == td->sp [-1].local) {
MonoGenericContext* ctx = mono_method_get_context (target_method);
g_assert (ctx);
g_assert (ctx->method_inst);
g_assert (ctx->method_inst->type_argc == 1);
MonoType *span_arg_type = mini_get_underlying_type (ctx->method_inst->type_argv [0]);

MonoClassField *field = (MonoClassField*)td->data_items [td->last_ins->data [0]];
int alignment = 0;
int element_size = mono_type_size (span_arg_type, &alignment);
int num_elements = mono_type_size (field->type, &alignment) / element_size;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
const int swizzle = 1;
#else
const int swizzle = element_size;
#endif
gpointer data_ptr = (gpointer)mono_field_get_rva (field, swizzle);
// instead of the field, we push directly the associated data
td->last_ins->data [0] = get_data_item_index (td, data_ptr);

// push the length of this span
push_simple_type (td, STACK_TYPE_I4);
interp_get_ldc_i4_from_const (td, NULL, num_elements, td->sp [-1].local);

// create span
interp_add_ins (td, MINT_INTRINS_SPAN_CTOR);
td->sp -= 2;
interp_ins_set_sregs2 (td->last_ins, td->sp [0].local, td->sp [1].local);

MonoClass *ret_class = mono_class_from_mono_type_internal (csignature->ret);
push_type_vt (td, ret_class, mono_class_value_size (ret_class, NULL));
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);

td->ip += 5;
return TRUE;
}
} else if (in_corlib && !strcmp (klass_name_space, "System") && !strcmp (klass_name, "RuntimeMethodHandle") && !strcmp (tm, "GetFunctionPointer") && csignature->param_count == 1) {
// We must intrinsify this method on interp so we don't return a pointer to native code entering interpreter
Expand All @@ -2467,7 +2503,7 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
return_val_if_nok (error, FALSE);

td->sp--;
interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
push_type (td, STACK_TYPE_O, mono_defaults.runtimetype_class);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, systype);
Expand Down Expand Up @@ -7207,15 +7243,15 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
break;
}

interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
gpointer systype = mono_type_get_object_checked ((MonoType*)handle, error);
goto_if_nok (error, exit);
push_type (td, STACK_TYPE_O, mono_defaults.runtimetype_class);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, systype);
td->ip = next_ip + 5;
} else {
interp_add_ins (td, MINT_LDTOKEN);
interp_add_ins (td, MINT_LDPTR);
push_type_vt (td, klass, sizeof (gpointer));
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, handle);
Expand Down Expand Up @@ -7429,15 +7465,15 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
case CEE_MONO_METHODCONST:
token = read32 (td->ip + 1);
td->ip += 5;
interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
push_simple_type (td, STACK_TYPE_I);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, mono_method_get_wrapper_data (method, token));
break;
case CEE_MONO_PINVOKE_ADDR_CACHE: {
token = read32 (td->ip + 1);
td->ip += 5;
interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
g_assert (method->wrapper_type != MONO_WRAPPER_NONE);
push_simple_type (td, STACK_TYPE_I);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
Expand Down Expand Up @@ -7502,7 +7538,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
++td->ip;
break;
case CEE_MONO_LDPTR_INT_REQ_FLAG:
interp_add_ins (td, MINT_MONO_LDPTR);
interp_add_ins (td, MINT_LDPTR);
push_type (td, STACK_TYPE_MP, NULL);
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
td->last_ins->data [0] = get_data_item_index (td, &mono_thread_interruption_request_flag);
Expand Down Expand Up @@ -9351,7 +9387,7 @@ interp_cprop (TransformData *td)
} else if (MINT_IS_LDC_I8 (opcode)) {
local_defs [dreg].type = LOCAL_VALUE_I8;
local_defs [dreg].l = interp_get_const_from_ldc_i8 (ins);
} else if (ins->opcode == MINT_MONO_LDPTR) {
} else if (ins->opcode == MINT_LDPTR) {
#if SIZEOF_VOID_P == 8
local_defs [dreg].type = LOCAL_VALUE_I8;
local_defs [dreg].l = (gint64)td->data_items [ins->data [0]];
Expand Down
3 changes: 1 addition & 2 deletions src/mono/wasm/runtime/jiterpreter-trace-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,10 @@ export function generate_wasm_body (
append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.i32_store);
break;

case MintOpcode.MINT_LDTOKEN:
case MintOpcode.MINT_LDSTR:
case MintOpcode.MINT_LDFTN:
case MintOpcode.MINT_LDFTN_ADDR:
case MintOpcode.MINT_MONO_LDPTR: {
case MintOpcode.MINT_LDPTR: {
// Pre-load locals for the store op
builder.local("pLocals");

Expand Down

0 comments on commit a979774

Please sign in to comment.