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);
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);
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;
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 */
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