[jit] Optimize out the early pinvoke address loading done by emit_native_wrapper...
authorZoltan Varga <vargaz@gmail.com>
Tue, 15 Nov 2016 17:51:54 +0000 (12:51 -0500)
committerGitHub <noreply@github.com>
Tue, 15 Nov 2016 17:51:54 +0000 (12:51 -0500)
mono/mini/aot-compiler.c
mono/mini/method-to-ir.c
mono/mini/mini.c
mono/mini/mini.h

index 08ce2f067011cbd3024c0e9945fd235b803cf5fd..6c30c8f5bd11d92bf78f9c95192070ef72b52487 100644 (file)
@@ -7527,6 +7527,8 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
                flags = (JitFlags)(flags | JIT_FLAG_LLVM_ONLY | JIT_FLAG_EXPLICIT_NULL_CHECKS);
        if (acfg->aot_opts.no_direct_calls)
                flags = (JitFlags)(flags | JIT_FLAG_NO_DIRECT_ICALLS);
+       if (acfg->aot_opts.direct_pinvoke)
+               flags = (JitFlags)(flags | JIT_FLAG_DIRECT_PINVOKE);
 
        jit_timer = mono_time_track_start ();
        cfg = mini_method_compile (method, acfg->opts, mono_get_root_domain (), flags, 0, index);
index ee0535ec2529562119ce7996fffbe64c4477361c..de0e58ab1799364ea5c1c77f129066f37d9835c1 100644 (file)
@@ -12579,7 +12579,17 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                cmethod = (MonoMethod *)mono_method_get_wrapper_data (method, token);
 
                                if (cfg->compile_aot) {
-                                       EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_ICALL_ADDR, cmethod);
+                                       if (cfg->direct_pinvoke && ip + 6 < end && (ip [6] == CEE_POP)) {
+                                               /*
+                                                * This is generated by emit_native_wrapper () to resolve the pinvoke address
+                                                * before the call, its not needed when using direct pinvoke.
+                                                * This is not an optimization, but its used to avoid looking up pinvokes
+                                                * on platforms which don't support dlopen ().
+                                                */
+                                               EMIT_NEW_PCONST (cfg, ins, NULL);
+                                       } else {
+                                               EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_ICALL_ADDR, cmethod);
+                                       }
                                } else {
                                        ptr = mono_lookup_internal_call (cmethod);
                                        g_assert (ptr);
index e94e9fc18c00e59ca5c5b38e0295d461819bbe4c..5b42ca510f34ffa07def506ffdb86ffff3612339 100644 (file)
@@ -3315,6 +3315,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        cfg->soft_breakpoints = debug_options.soft_breakpoints;
        cfg->check_pinvoke_callconv = debug_options.check_pinvoke_callconv;
        cfg->disable_direct_icalls = disable_direct_icalls;
+       cfg->direct_pinvoke = (flags & JIT_FLAG_DIRECT_PINVOKE) != 0;
        if (try_generic_shared)
                cfg->gshared = TRUE;
        cfg->compile_llvm = try_llvm;
index 1d4184ee09c37b27229fcf76bd41e634d3416a56..9e6f8f7523f5702fccc496b9433cd0abc5a02422 100644 (file)
@@ -1513,12 +1513,14 @@ typedef enum {
        JIT_FLAG_FULL_AOT = (1 << 2),
        /* Whenever to compile with LLVM */
        JIT_FLAG_LLVM = (1 << 3),
-       /* Whenever to disable direct calls to direct calls to icall functions */
+       /* Whenever to disable direct calls to icall functions */
        JIT_FLAG_NO_DIRECT_ICALLS = (1 << 4),
        /* Emit explicit null checks */
        JIT_FLAG_EXPLICIT_NULL_CHECKS = (1 << 5),
        /* Whenever to compile in llvm-only mode */
        JIT_FLAG_LLVM_ONLY = (1 << 6),
+       /* Whenever calls to pinvoke functions are made directly */
+       JIT_FLAG_DIRECT_PINVOKE = (1 << 7)
 } JitFlags;
 
 /* Bit-fields in the MonoBasicBlock.region */
@@ -1688,6 +1690,7 @@ typedef struct {
        guint            disable_out_of_line_bblocks : 1;
        guint            disable_direct_icalls : 1;
        guint            disable_gc_safe_points : 1;
+       guint            direct_pinvoke : 1;
        guint            create_lmf_var : 1;
        /*
         * When this is set, the code to push/pop the LMF from the LMF stack is generated as IR