From: Zoltan Varga Date: Thu, 5 Mar 2015 01:03:24 +0000 (-0500) Subject: [jit] Add a new mini_get_underlying_type () function which handles byref, enums,... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=54f76829688a1378e9cc11e17d9ae976865c7596;p=mono.git [jit] Add a new mini_get_underlying_type () function which handles byref, enums, native types, and generic sharing. Use it in places where possible. --- diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 6df610b771f..a7ea46ba97b 100755 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -276,7 +276,7 @@ mono_type_to_regmove (MonoCompile *cfg, MonoType *type) if (type->byref) return OP_MOVE; - type = mini_replace_type (type); + type = mini_get_underlying_type (cfg, type); handle_enum: switch (type->type) { case MONO_TYPE_I1: @@ -738,7 +738,7 @@ type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst) { MonoClass *klass; - type = mini_replace_type (type); + type = mini_get_underlying_type (cfg, type); inst->klass = klass = mono_class_from_mono_type (type); if (type->byref) { inst->type = STACK_MP; @@ -2140,12 +2140,8 @@ emit_instrumentation_call (MonoCompile *cfg, void *func) static int ret_type_to_call_opcode (MonoCompile *cfg, MonoType *type, int calli, int virt, MonoGenericSharingContext *gsctx) { - if (type->byref) - return calli? OP_CALL_REG: virt? OP_CALL_MEMBASE: OP_CALL; - handle_enum: - type = mini_get_basic_type_from_generic (gsctx, type); - type = mini_replace_type (type); + type = mini_get_underlying_type (cfg, type); switch (type->type) { case MONO_TYPE_VOID: return calli? OP_VOIDCALL_REG: virt? OP_VOIDCALL_MEMBASE: OP_VOIDCALL; @@ -2217,7 +2213,6 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg) MonoType *simple_type; MonoClass *klass; - target = mini_replace_type (target); if (target->byref) { /* FIXME: check that the pointed to types match */ if (arg->type == STACK_MP) @@ -2227,7 +2222,7 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg) return 1; } - simple_type = mono_type_get_underlying_type (target); + simple_type = mini_get_underlying_type (cfg, target); switch (simple_type->type) { case MONO_TYPE_VOID: return 1; @@ -2612,7 +2607,7 @@ mono_emit_call_args (MonoCompile *cfg, MonoMethodSignature *sig, call->args = args; call->signature = sig; call->rgctx_reg = rgctx; - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); type_to_eval_stack_type ((cfg), sig_ret, &call->inst); @@ -6671,7 +6666,7 @@ emit_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype) MonoInst *ins; int t; - rtype = mini_replace_type (rtype); + rtype = mini_get_underlying_type (cfg, rtype); t = rtype->type; if (rtype->byref) { @@ -6707,7 +6702,7 @@ emit_dummy_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype) { int t; - rtype = mini_replace_type (rtype); + rtype = mini_get_underlying_type (cfg, rtype); t = rtype->type; if (rtype->byref) { @@ -7410,7 +7405,7 @@ emit_optimized_ldloca_ir (MonoCompile *cfg, unsigned char *ip, unsigned char *en token = read32 (ip + 2); klass = mini_get_class (cfg->current_method, token, cfg->generic_context); CHECK_TYPELOAD (klass); - type = mini_replace_type (&klass->byval_arg); + type = mini_get_underlying_type (cfg, &klass->byval_arg); emit_init_local (cfg, local, type, TRUE); return ip + 6; } @@ -9548,7 +9543,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b emit_pop_lmf (cfg); if (cfg->ret) { - MonoType *ret_type = mini_replace_type (mono_method_signature (method)->ret); + MonoType *ret_type = mini_get_underlying_type (cfg, mono_method_signature (method)->ret); if (seq_points && !sym_seq_points) { /* diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index 3a7eedd7e35..69769b53be4 100755 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -1250,7 +1250,7 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig c1 = get_call_info (NULL, NULL, caller_sig); c2 = get_call_info (NULL, NULL, callee_sig); res = c1->stack_usage >= c2->stack_usage; - callee_ret = mini_replace_type (callee_sig->ret); + callee_ret = mini_get_underlying_type (cfg, callee_sig->ret); if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg) /* An address on the callee's stack is passed as the first argument */ res = FALSE; @@ -1659,7 +1659,7 @@ mono_arch_fill_argument_info (MonoCompile *cfg) sig = mono_method_signature (cfg->method); cinfo = cfg->arch.cinfo; - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); /* * Contrary to mono_arch_allocate_vars (), the information should describe @@ -1741,7 +1741,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) sig = mono_method_signature (cfg->method); cinfo = cfg->arch.cinfo; - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); mono_arch_compute_omit_fp (cfg); @@ -2022,7 +2022,7 @@ mono_arch_create_vars (MonoCompile *cfg) if (cinfo->ret.storage == ArgValuetypeInReg) cfg->ret_var_is_local = TRUE; - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); if ((cinfo->ret.storage != ArgValuetypeInReg) && MONO_TYPE_ISSTRUCT (sig_ret)) { cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG); if (G_UNLIKELY (cfg->verbose_level > 1)) { @@ -2167,7 +2167,7 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig) MonoType *t, *sig_ret; n = sig->param_count + sig->hasthis; - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); @@ -2398,7 +2398,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sig->sentinelpos)) emit_sig_cookie (cfg, call, cinfo); - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); if (sig_ret && MONO_TYPE_ISSTRUCT (sig_ret)) { MonoInst *vtarg; @@ -2533,7 +2533,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) void mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val) { - MonoType *ret = mini_replace_type (mono_method_signature (method)->ret); + MonoType *ret = mini_get_underlying_type (cfg, mono_method_signature (method)->ret); if (ret->type == MONO_TYPE_R4) { if (COMPILE_LLVM (cfg)) @@ -7662,7 +7662,7 @@ mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolea guchar *code = p; int save_mode = SAVE_NONE; MonoMethod *method = cfg->method; - MonoType *ret_type = mini_replace_type (mono_method_signature (method)->ret); + MonoType *ret_type = mini_get_underlying_type (cfg, mono_method_signature (method)->ret); int i; switch (ret_type->type) { diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c index ea04525ff14..d89c46b500e 100644 --- a/mono/mini/mini-arm.c +++ b/mono/mini/mini-arm.c @@ -1753,7 +1753,7 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig * the extra stack space would be left on the stack after the tail call. */ res = c1->stack_usage >= c2->stack_usage; - callee_ret = mini_replace_type (callee_sig->ret); + callee_ret = mini_get_underlying_type (cfg, callee_sig->ret); if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != RegTypeStructByVal) /* An address on the callee's stack is passed as the first argument */ res = FALSE; @@ -1869,7 +1869,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) if (!cfg->arch.cinfo) cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); cinfo = cfg->arch.cinfo; - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); mono_arch_compute_omit_fp (cfg); diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 9fd46669119..25323968831 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -372,10 +372,10 @@ create_llvm_type_for_type (MonoClass *klass) static LLVMTypeRef type_to_llvm_type (EmitContext *ctx, MonoType *t) { - t = mini_replace_type (t); - if (t->byref) return LLVMPointerType (LLVMInt8Type (), 0); + + t = mini_get_underlying_type (ctx->cfg, t); switch (t->type) { case MONO_TYPE_VOID: return LLVMVoidType (); @@ -1152,7 +1152,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo * if (sinfo) memset (sinfo, 0, sizeof (LLVMSigInfo)); - rtype = mini_replace_type (sig->ret); + rtype = mini_get_underlying_type (ctx->cfg, sig->ret); ret_type = type_to_llvm_type (ctx, rtype); CHECK_FAILURE (ctx); diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index 9281ea9d1eb..7f213efd28d 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -324,7 +324,7 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn /* Special case structs with only a float member */ if (info->num_fields == 1) { - int ftype = mini_replace_type (info->fields [0].field->type)->type; + int ftype = mini_type_get_underlying_type (gsctx, info->fields [0].field->type)->type; if ((info->native_size == 8) && (ftype == MONO_TYPE_R8)) { ainfo->storage = ArgValuetypeInReg; ainfo->pair_storage [0] = ArgOnDoubleFpStack; @@ -721,7 +721,7 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig * the extra stack space would be left on the stack after the tail call. */ res = c1->stack_usage >= c2->stack_usage; - callee_ret = mini_replace_type (callee_sig->ret); + callee_ret = mini_get_underlying_type (cfg, callee_sig->ret); if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg) /* An address on the callee's stack is passed as the first argument */ res = FALSE; @@ -1209,7 +1209,7 @@ mono_arch_create_vars (MonoCompile *cfg) sig = mono_method_signature (cfg->method); cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); if (cinfo->ret.storage == ArgValuetypeInReg) cfg->ret_var_is_local = TRUE; @@ -1424,7 +1424,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) sig = call->signature; n = sig->param_count + sig->hasthis; - sig_ret = mini_replace_type (sig->ret); + sig_ret = mini_get_underlying_type (cfg, sig->ret); cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); call->call_info = cinfo; diff --git a/mono/mini/mini.c b/mono/mini/mini.c index b86f4afd6bd..409ef5dacf4 100755 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -423,10 +423,7 @@ mono_reverse_branch_op (guint32 opcode) guint mono_type_to_store_membase (MonoCompile *cfg, MonoType *type) { - if (type->byref) - return OP_STORE_MEMBASE_REG; - - type = mini_replace_type (type); + type = mini_get_underlying_type (cfg, type); handle_enum: switch (type->type) { @@ -474,10 +471,8 @@ handle_enum: goto handle_enum; case MONO_TYPE_VAR: case MONO_TYPE_MVAR: - if (mini_type_var_is_vt (cfg, type)) - return OP_STOREV_MEMBASE; - else - return OP_STORE_MEMBASE_REG; + g_assert (mini_type_var_is_vt (cfg, type)); + return OP_STOREV_MEMBASE; default: g_error ("unknown type 0x%02x in type_to_store_membase", type->type); } @@ -487,10 +482,7 @@ handle_enum: guint mono_type_to_load_membase (MonoCompile *cfg, MonoType *type) { - if (type->byref) - return OP_LOAD_MEMBASE; - - type = mini_replace_type (type); + type = mini_get_underlying_type (cfg, type); switch (type->type) { case MONO_TYPE_I1: @@ -539,10 +531,8 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type) case MONO_TYPE_VAR: case MONO_TYPE_MVAR: g_assert (cfg->generic_sharing_context); - if (mini_type_var_is_vt (cfg, type)) - return OP_LOADV_MEMBASE; - else - return OP_LOAD_MEMBASE; + g_assert (mini_type_var_is_vt (cfg, type)); + return OP_LOADV_MEMBASE; default: g_error ("unknown type 0x%02x in type_to_load_membase", type->type); } @@ -552,13 +542,10 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type) static guint mini_type_to_ldind (MonoCompile* cfg, MonoType *type) { - if (cfg->generic_sharing_context && !type->byref) { - if (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) { - if (mini_type_var_is_vt (cfg, type)) - return CEE_LDOBJ; - else - return CEE_LDIND_REF; - } + type = mini_get_underlying_type (cfg, type); + if (cfg->generic_sharing_context && !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) { + g_assert (mini_type_var_is_vt (cfg, type)); + return CEE_LDOBJ; } return mono_type_to_ldind (type); } @@ -568,15 +555,10 @@ mini_type_to_ldind (MonoCompile* cfg, MonoType *type) guint mini_type_to_stind (MonoCompile* cfg, MonoType *type) { - type = mini_replace_type (type); - - if (cfg->generic_sharing_context && !type->byref) { - if (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) { - if (mini_type_var_is_vt (cfg, type)) - return CEE_STOBJ; - else - return CEE_STIND_REF; - } + type = mini_get_underlying_type (cfg, type); + if (cfg->generic_sharing_context && !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) { + g_assert (mini_type_var_is_vt (cfg, type)); + return CEE_STOBJ; } return mono_type_to_stind (type); } @@ -751,7 +733,7 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, int num = cfg->num_varinfo; gboolean regpair; - type = mini_replace_type (type); + type = mini_get_underlying_type (cfg, type); if ((num + 1) >= cfg->varinfo_count) { int orig_count = cfg->varinfo_count; @@ -779,8 +761,7 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, if (type->byref) { mono_mark_vreg_as_mp (cfg, vreg); } else { - MonoType *t = mini_replace_type (type); - if ((MONO_TYPE_ISSTRUCT (t) && inst->klass->has_references) || mini_type_is_reference (cfg, t)) { + if ((MONO_TYPE_ISSTRUCT (type) && inst->klass->has_references) || mini_type_is_reference (cfg, type)) { inst->flags |= MONO_INST_GC_TRACK; mono_mark_vreg_as_ref (cfg, vreg); } @@ -861,7 +842,7 @@ MonoInst* mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode) { int dreg; - type = mini_replace_type (type); + type = mini_get_underlying_type (cfg, type); if (mono_type_is_long (type)) dreg = mono_alloc_dreg (cfg, STACK_I8); @@ -878,7 +859,8 @@ mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode) * Transform a MonoInst into a load from the variable of index var_index. */ void -mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index) { +mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index) +{ memset (dest, 0, sizeof (MonoInst)); dest->inst_i0 = cfg->varinfo [var_index]; dest->opcode = mini_type_to_ldind (cfg, dest->inst_i0->inst_vtype); @@ -4551,6 +4533,20 @@ mini_replace_type (MonoType *type) return mini_native_type_replace_type (type); } +/* + * mini_get_underlying_type: + * + * Return the type the JIT will use during compilation. + * Handles: byref, enums, native types, generic sharing. + * For gsharedvt types, it will return the original VAR/MVAR. + */ +MonoType* +mini_get_underlying_type (MonoCompile *cfg, MonoType *type) +{ + type = mini_type_get_underlying_type (cfg->generic_sharing_context, type); + return mini_native_type_replace_type (type); +} + void mini_jit_init (void) { diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 2821f479d3d..fcef6531e32 100755 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -2794,6 +2794,7 @@ MonoClass* mini_class_get_container_class (MonoClass *class) MONO_INTERNAL; MonoGenericContext* mini_class_get_context (MonoClass *class) MONO_INTERNAL; MonoType* mini_replace_type (MonoType *type) MONO_LLVM_INTERNAL; +MonoType* mini_get_underlying_type (MonoCompile *cfg, MonoType *type) MONO_LLVM_INTERNAL; MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL; MonoType* mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL; MonoMethod* mini_get_shared_method (MonoMethod *method) MONO_INTERNAL;