[jit] Enable inlining inside gshared methods. (#4059)
authorZoltan Varga <vargaz@gmail.com>
Thu, 1 Dec 2016 07:10:07 +0000 (02:10 -0500)
committerGitHub <noreply@github.com>
Thu, 1 Dec 2016 07:10:07 +0000 (02:10 -0500)
mono/mini/method-to-ir.c
mono/mini/mini.c
mono/mini/mini.h

index fc8f816db0a09d0c3bb97b1d487379881c7edbfc..87a0974d0d62ea8ecff10fe43232a56e980cf247 100644 (file)
@@ -3501,8 +3501,8 @@ emit_get_rgctx (MonoCompile *cfg, MonoMethod *method, int context_used)
 
        if (!(method->flags & METHOD_ATTRIBUTE_STATIC) &&
                        !(context_used & MONO_GENERIC_CONTEXT_USED_METHOD) &&
-                       !method->klass->valuetype)
-               EMIT_NEW_ARGLOAD (cfg, this_ins, 0);
+               !method->klass->valuetype)
+               EMIT_NEW_VARLOAD (cfg, this_ins, cfg->this_arg, &mono_defaults.object_class->byval_arg);
 
        if (context_used & MONO_GENERIC_CONTEXT_USED_METHOD) {
                MonoInst *mrgctx_loc, *mrgctx_var;
@@ -3683,8 +3683,8 @@ static MonoInst*
 emit_get_rgctx_klass (MonoCompile *cfg, int context_used,
                                          MonoClass *klass, MonoRgctxInfoType rgctx_type)
 {
-       MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->current_method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_CLASS, klass, rgctx_type);
-       MonoInst *rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+       MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_CLASS, klass, rgctx_type);
+       MonoInst *rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
        return emit_rgctx_fetch (cfg, rgctx, entry);
 }
@@ -3693,8 +3693,8 @@ static MonoInst*
 emit_get_rgctx_sig (MonoCompile *cfg, int context_used,
                                        MonoMethodSignature *sig, MonoRgctxInfoType rgctx_type)
 {
-       MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->current_method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_SIGNATURE, sig, rgctx_type);
-       MonoInst *rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+       MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_SIGNATURE, sig, rgctx_type);
+       MonoInst *rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
        return emit_rgctx_fetch (cfg, rgctx, entry);
 }
@@ -3711,8 +3711,8 @@ emit_get_rgctx_gsharedvt_call (MonoCompile *cfg, int context_used,
        call_info->sig = sig;
        call_info->method = cmethod;
 
-       entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->current_method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_GSHAREDVT_CALL, call_info, rgctx_type);
-       rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+       entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_GSHAREDVT_CALL, call_info, rgctx_type);
+       rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
        return emit_rgctx_fetch (cfg, rgctx, entry);
 }
@@ -3734,8 +3734,8 @@ emit_get_rgctx_virt_method (MonoCompile *cfg, int context_used,
        info->klass = klass;
        info->method = virt_method;
 
-       entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->current_method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_VIRT_METHOD, info, rgctx_type);
-       rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+       entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_VIRT_METHOD, info, rgctx_type);
+       rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
        return emit_rgctx_fetch (cfg, rgctx, entry);
 }
@@ -3747,8 +3747,8 @@ emit_get_rgctx_gsharedvt_method (MonoCompile *cfg, int context_used,
        MonoJumpInfoRgctxEntry *entry;
        MonoInst *rgctx;
 
-       entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->current_method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_GSHAREDVT_METHOD, info, MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO);
-       rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+       entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_GSHAREDVT_METHOD, info, MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO);
+       rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
        return emit_rgctx_fetch (cfg, rgctx, entry);
 }
@@ -3777,8 +3777,8 @@ emit_get_rgctx_method (MonoCompile *cfg, int context_used,
                        g_assert_not_reached ();
                }
        } else {
-               MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->current_method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_METHODCONST, cmethod, rgctx_type);
-               MonoInst *rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+               MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_METHODCONST, cmethod, rgctx_type);
+               MonoInst *rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
                return emit_rgctx_fetch (cfg, rgctx, entry);
        }
@@ -3788,8 +3788,8 @@ static MonoInst*
 emit_get_rgctx_field (MonoCompile *cfg, int context_used,
                                          MonoClassField *field, MonoRgctxInfoType rgctx_type)
 {
-       MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->current_method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_FIELD, field, rgctx_type);
-       MonoInst *rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+       MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used & MONO_GENERIC_CONTEXT_USED_METHOD, MONO_PATCH_INFO_FIELD, field, rgctx_type);
+       MonoInst *rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
        return emit_rgctx_fetch (cfg, rgctx, entry);
 }
@@ -4059,7 +4059,7 @@ handle_unbox_nullable (MonoCompile* cfg, MonoInst* val, MonoClass* klass, int co
                        cfg->signatures = g_slist_prepend_mempool (cfg->mempool, cfg->signatures, mono_method_signature (method));
                        return emit_llvmonly_calli (cfg, mono_method_signature (method), &val, addr);
                } else {
-                       rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+                       rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
                        return mono_emit_calli (cfg, mono_method_signature (method), &val, addr, NULL, rgctx);
                }
@@ -4326,7 +4326,7 @@ handle_box (MonoCompile *cfg, MonoInst *val, MonoClass *klass, int context_used)
                                   have to get the method address from the RGCTX. */
                                MonoInst *addr = emit_get_rgctx_method (cfg, context_used, method,
                                                                                                                MONO_RGCTX_INFO_GENERIC_METHOD_CODE);
-                               MonoInst *rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+                               MonoInst *rgctx = emit_get_rgctx (cfg, cfg->method, context_used);
 
                                return mono_emit_calli (cfg, mono_method_signature (method), &val, addr, NULL, rgctx);
                        }
@@ -5317,7 +5317,7 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
 
        if (cfg->disable_inline)
                return FALSE;
-       if (cfg->gshared)
+       if (cfg->gsharedvt)
                return FALSE;
 
        if (cfg->inline_depth > 10)
@@ -5351,17 +5351,22 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
         * since it would mean inserting a call to mono_runtime_class_init()
         * inside the inlined code
         */
+       if (cfg->gshared && method->klass->has_cctor && mini_class_check_context_used (cfg, method->klass))
+               return FALSE;
+
        if (!(cfg->opt & MONO_OPT_SHARED)) {
                /* The AggressiveInlining hint is a good excuse to force that cctor to run. */
                if (method->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING) {
-                       vtable = mono_class_vtable (cfg->domain, method->klass);
-                       if (!vtable)
-                               return FALSE;
-                       if (!cfg->compile_aot) {
-                               MonoError error;
-                               if (!mono_runtime_class_init_full (vtable, &error)) {
-                                       mono_error_cleanup (&error);
+                       if (method->klass->has_cctor) {
+                               vtable = mono_class_vtable (cfg->domain, method->klass);
+                               if (!vtable)
                                        return FALSE;
+                               if (!cfg->compile_aot) {
+                                       MonoError error;
+                                       if (!mono_runtime_class_init_full (vtable, &error)) {
+                                               mono_error_cleanup (&error);
+                                               return FALSE;
+                                       }
                                }
                        }
                } else if (mono_class_is_before_field_init (method->klass)) {
@@ -7216,7 +7221,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
        if ((costs >= 0 && costs < 60) || inline_always || (costs >= 0 && (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING))) {
                if (cfg->verbose_level > 2)
                        printf ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
-               
+
                cfg->stat_inlined_methods++;
 
                /* always add some code to avoid block split failures */
index 486a5d58171fe73326cb248bb96d67d3735711c2..fa01d62cfe790eefc1e5a0edcafec2cb4dd2d041 100644 (file)
@@ -2146,8 +2146,10 @@ mono_compile_create_vars (MonoCompile *cfg)
 
        cfg->args = (MonoInst **)mono_mempool_alloc0 (cfg->mempool, (sig->param_count + sig->hasthis) * sizeof (MonoInst*));
 
-       if (sig->hasthis)
+       if (sig->hasthis) {
                cfg->args [0] = mono_compile_create_var (cfg, &cfg->method->klass->this_arg, OP_ARG);
+               cfg->this_arg = cfg->args [0];
+       }
 
        for (i = 0; i < sig->param_count; ++i) {
                cfg->args [i + sig->hasthis] = mono_compile_create_var (cfg, sig->params [i], OP_ARG);
index e0388c536677f7ec992132995cc6d9b7d3036487..66b87a1025cb1e30169eb1eec872f661ef25d7df 100644 (file)
@@ -1593,6 +1593,7 @@ typedef struct {
        MonoMethod      *current_method; /* The method currently processed by method_to_ir () */
        MonoMethod      *method_to_register; /* The method to register in JIT info tables */
        MonoGenericContext *generic_context;
+       MonoInst        *this_arg;
 
        MonoBackend *backend;