4 * Runtime declarations for the JIT.
6 * Copyright 2002-2003 Ximian Inc
7 * Copyright 2003-2011 Novell Inc
8 * Copyright 2011 Xamarin Inc
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #ifndef __MONO_MINI_RUNTIME_H__
13 #define __MONO_MINI_RUNTIME_H__
18 /* Per-domain information maintained by the JIT */
21 /* Maps MonoMethod's to a GSList of GOT slot addresses pointing to its code */
22 GHashTable
*jump_target_got_slot_hash
;
23 GHashTable
*jump_target_hash
;
24 /* Maps methods/klasses to the address of the given type of trampoline */
25 GHashTable
*class_init_trampoline_hash
;
26 GHashTable
*jump_trampoline_hash
;
27 GHashTable
*jit_trampoline_hash
;
28 GHashTable
*delegate_trampoline_hash
;
29 /* Maps ClassMethodPair -> MonoDelegateTrampInfo */
30 GHashTable
*static_rgctx_trampoline_hash
;
31 GHashTable
*llvm_vcall_trampoline_hash
;
32 /* maps MonoMethod -> MonoJitDynamicMethodInfo */
33 GHashTable
*dynamic_code_hash
;
34 GHashTable
*method_code_hash
;
35 /* Maps methods to a RuntimeInvokeInfo structure, protected by the associated MonoDomain lock */
36 MonoConcurrentHashTable
*runtime_invoke_hash
;
37 /* Maps MonoMethod to a GPtrArray containing sequence point locations */
38 /* Protected by the domain lock */
39 GHashTable
*seq_points
;
40 /* Debugger agent data */
42 /* Maps MonoMethod to an arch-specific structure */
43 GHashTable
*arch_seq_points
;
44 /* Maps a GSharedVtTrampInfo structure to a trampoline address */
45 GHashTable
*gsharedvt_arg_tramp_hash
;
46 /* memcpy/bzero methods specialized for small constant sizes */
47 gpointer
*memcpy_addr
[17];
48 gpointer
*bzero_addr
[17];
50 /* Maps MonoMethod -> GSlist of addresses */
51 GHashTable
*llvm_jit_callees
;
52 /* Maps MonoMethod -> RuntimeMethod */
53 MonoInternalHashTable interp_code_hash
;
54 /* Maps MonoMethod -> MonoMethodRuntimeGenericContext */
55 GHashTable
*mrgctx_hash
;
56 GHashTable
*method_rgctx_hash
;
57 /* Maps gpointer -> InterpMethod */
58 GHashTable
*interp_method_pointer_hash
;
61 #define domain_jit_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
64 * Stores state need to resume exception handling when using LLVM
69 MonoContext ctx
, new_ctx
;
73 int first_filter_idx
, filter_idx
;
76 typedef void (*MonoAbortFunction
)(MonoObject
*);
78 struct MonoJitTlsData
{
79 gpointer end_of_stack
;
83 guint handling_stack_ovf
: 1;
84 gpointer signal_stack
;
85 guint32 signal_stack_size
;
86 gpointer stack_ovf_guard_base
;
87 guint32 stack_ovf_guard_size
;
88 guint stack_ovf_valloced
: 1;
89 guint stack_ovf_pending
: 1;
90 MonoAbortFunction abort_func
;
91 /* Used to implement --debug=casts */
92 MonoClass
*class_cast_from
, *class_cast_to
;
94 /* Stores state needed by handler block with a guard */
96 ResumeState resume_state
;
98 /* handler block been guarded. It's safe to store this even for dynamic methods since there
99 is an activation on stack making sure it will remain alive.*/
100 MonoJitExceptionInfo
*handler_block
;
102 /* context to be used by the guard trampoline when resuming interruption.*/
103 MonoContext handler_block_context
;
105 * Stores the state at the exception throw site to be used by mono_stack_walk ()
106 * when it is called from profiler functions during exception handling.
108 MonoContext orig_ex_ctx
;
109 gboolean orig_ex_ctx_set
;
112 * The current exception in flight
116 * If the current exception is not a subclass of Exception,
117 * the original exception.
119 guint32 thrown_non_exc
;
122 * The calling assembly in llvmonly mode.
124 MonoImage
*calling_image
;
127 * The stack frame "high water mark" for ThreadAbortExceptions.
128 * We will rethrow the exception upon exiting a catch clause that's
129 * in a function stack frame above the water mark(isn't being called by
130 * the catch block that caught the ThreadAbortException).
132 gpointer abort_exc_stack_threshold
;
135 * List of methods being JIT'd in the current thread.
137 int active_jit_methods
;
139 gpointer interp_context
;
141 #if defined(TARGET_WIN32)
142 MonoContext stack_restore_ctx
;
146 #define MONO_LMFEXT_DEBUGGER_INVOKE 1
147 #define MONO_LMFEXT_INTERP_EXIT 2
148 #define MONO_LMFEXT_INTERP_EXIT_WITH_CTX 3
151 * This structure is an extension of MonoLMF and contains extra information.
156 MonoContext ctx
; /* valid if kind == DEBUGGER_INVOKE || kind == INTERP_EXIT_WITH_CTX */
157 gpointer interp_exit_data
; /* valid if kind == INTERP_EXIT || kind == INTERP_EXIT_WITH_CTX */
158 #if defined (_MSC_VER)
159 gboolean interp_exit_label_set
;
163 typedef void (*MonoFtnPtrEHCallback
) (guint32 gchandle
);
165 typedef struct MonoDebugOptions
{
166 gboolean handle_sigint
;
167 gboolean keep_delegates
;
168 gboolean reverse_pinvoke_exceptions
;
169 gboolean collect_pagefault_stats
;
170 gboolean break_on_unverified
;
171 gboolean better_cast_details
;
172 gboolean mdb_optimizations
;
173 gboolean no_gdb_backtrace
;
174 gboolean suspend_on_native_crash
;
175 gboolean suspend_on_exception
;
176 gboolean suspend_on_unhandled
;
177 gboolean dyn_runtime_invoke
;
182 * With LLVM codegen, this option will cause methods to be called indirectly through the
183 * PLT (As they are in other FullAOT modes, without LLVM).
185 * Enable this to debug problems with direct calls in llvm
187 gboolean llvm_disable_self_init
;
189 * Prevent LLVM from inlining any methods
191 gboolean llvm_disable_inlining
;
192 gboolean use_fallback_tls
;
194 * Whenever data such as next sequence points and flags is required.
195 * Next sequence points and flags are required by the debugger agent.
197 gboolean gen_sdb_seq_points
;
198 gboolean no_seq_points_compact_data
;
200 * Setting single_imm_size should guarantee that each time managed code is compiled
201 * the same instructions and registers are used, regardless of the size of used values.
203 gboolean single_imm_size
;
204 gboolean explicit_null_checks
;
206 * Fill stack frames with 0x2a in method prologs. This helps with the
207 * debugging of the stack marking code in the GC.
209 gboolean init_stacks
;
212 * Whenever to implement single stepping and breakpoints without signals in the
213 * soft debugger. This is useful on platforms without signals, like the ps3, or during
214 * runtime debugging, since it avoids SIGSEGVs when a single step location or breakpoint
217 gboolean soft_breakpoints
;
219 * Whenever to break in the debugger using G_BREAKPOINT on unhandled exceptions.
221 gboolean break_on_exc
;
223 * Load AOT JIT info eagerly.
225 gboolean load_aot_jit_info_eagerly
;
227 * Check for pinvoke calling convention mismatches.
229 gboolean check_pinvoke_callconv
;
231 * Translate Debugger.Break () into a native breakpoint signal
233 gboolean native_debugger_break
;
235 * Disabling the frame pointer emit optimization can allow debuggers to more easily
236 * identify the stack on some platforms
238 gboolean disable_omit_fp
;
240 * Make gdb output on native crashes more verbose.
242 gboolean verbose_gdb
;
244 // Internal testing feature.
245 gboolean test_tailcall_require
;
248 * Internal testing feature
249 * Testing feature, skip loading the Nth aot loadable method.
251 gboolean aot_skip_set
;
257 * We need to store the image which the token refers to along with the token,
258 * since the image might not be the same as the image of the method which
259 * contains the relocation, because of inlining.
261 typedef struct MonoJumpInfoToken
{
264 gboolean has_context
;
265 MonoGenericContext context
;
268 typedef struct MonoJumpInfoBBTable
{
269 MonoBasicBlock
**table
;
271 } MonoJumpInfoBBTable
;
273 /* Contains information describing an LLVM IMT trampoline */
274 typedef struct MonoJumpInfoImtTramp
{
277 } MonoJumpInfoImtTramp
;
280 * Contains information for computing the
281 * property given by INFO_TYPE of the runtime
282 * object described by DATA.
284 struct MonoJumpInfoRgctxEntry
{
286 /* If in_mrgctx is TRUE */
288 /* If in_mrgctx is FALSE */
292 MonoJumpInfo
*data
; /* describes the data to be loaded */
293 MonoRgctxInfoType info_type
;
296 /* Contains information about a gsharedvt call */
297 struct MonoJumpInfoGSharedVtCall
{
298 /* The original signature of the call */
299 MonoMethodSignature
*sig
;
300 /* The method which is called */
305 * Represents the method which is called when a virtual call is made to METHOD
306 * on a receiver of type KLASS.
313 } MonoJumpInfoVirtMethod
;
315 struct MonoJumpInfo
{
317 /* Relocation type for patching */
325 MonoJumpInfoType type
;
327 // In order to allow blindly using target in mono_add_patch_info,
328 // all fields must be pointer-sized. No ints, no untyped enums.
329 gconstpointer target
;
330 gssize index
; // only 32 bits used but widened per above
331 gsize uindex
; // only 32 bits used but widened per above
336 MonoClassField
*field
;
340 #ifdef __cplusplus // MonoJitICallId has base type of gsize to widen per above.
341 MonoJitICallId jit_icall_id
;
343 gsize jit_icall_id
; // only 9 bits used but widened per above
345 MonoJumpInfoToken
*token
;
346 MonoJumpInfoBBTable
*table
;
347 MonoJumpInfoRgctxEntry
*rgctx_entry
;
348 MonoJumpInfoImtTramp
*imt_tramp
;
349 MonoJumpInfoGSharedVtCall
*gsharedvt
;
350 MonoGSharedVtMethodInfo
*gsharedvt_method
;
351 MonoMethodSignature
*sig
;
352 MonoDelegateClassMethodPair
*del_tramp
;
353 /* MONO_PATCH_INFO_VIRT_METHOD */
354 MonoJumpInfoVirtMethod
*virt_method
;
358 extern gboolean mono_break_on_exc
;
359 extern gboolean mono_compile_aot
;
360 extern gboolean mono_aot_only
;
361 extern gboolean mono_llvm_only
;
362 extern MonoAotMode mono_aot_mode
;
363 MONO_API_DATA
const char *mono_build_date
;
364 extern gboolean mono_do_signal_chaining
;
365 extern gboolean mono_do_crash_chaining
;
366 MONO_API_DATA gboolean mono_use_llvm
;
367 MONO_API_DATA gboolean mono_use_interpreter
;
368 extern const char* mono_interp_opts_string
;
369 extern gboolean mono_do_single_method_regression
;
370 extern guint32 mono_single_method_regression_opt
;
371 extern MonoMethod
*mono_current_single_method
;
372 extern GSList
*mono_single_method_list
;
373 extern GHashTable
*mono_single_method_hash
;
374 extern GList
* mono_aot_paths
;
375 extern MonoDebugOptions mini_debug_options
;
376 extern GSList
*mono_interp_only_classes
;
377 extern char *sdb_options
;
380 This struct describes what execution engine feature to use.
381 This subsume, and will eventually sunset, mono_aot_only / mono_llvm_only and friends.
382 The goal is to transition us to a place were we can more easily compose/describe what features we need for a given execution mode.
384 A good feature flag is checked alone, a bad one described many things and keeps breaking some of the modes
388 * If true, trampolines are to be fetched from the AOT runtime instead of JIT compiled
390 gboolean use_aot_trampolines
;
393 * If true, the runtime will try to use the interpreter before looking for compiled code.
395 gboolean force_use_interpreter
;
398 extern MonoEEFeatures mono_ee_features
;
400 //XXX this enum *MUST extend MonoAotMode as they are consumed together.
402 /* Always execute with interp, will use JIT to produce trampolines */
403 MONO_EE_MODE_INTERP
= MONO_AOT_MODE_LAST
,
407 static inline MonoMethod
*
408 jinfo_get_method (MonoJitInfo
*ji
)
410 return mono_jit_info_get_method (ji
);
414 MONO_API
int mono_main (int argc
, char* argv
[]);
415 MONO_API
void mono_set_defaults (int verbose_level
, guint32 opts
);
416 MONO_API
void mono_parse_env_options (int *ref_argc
, char **ref_argv
[]);
417 MONO_API
char *mono_parse_options_from (const char *options
, int *ref_argc
, char **ref_argv
[]);
418 MONO_API
int mono_regression_test_step (int verbose_level
, const char *image
, const char *method_name
);
421 void mono_interp_stub_init (void);
422 void mini_install_interp_callbacks (MonoEECallbacks
*cbs
);
423 MonoEECallbacks
* mini_get_interp_callbacks (void);
425 typedef struct _MonoDebuggerCallbacks MonoDebuggerCallbacks
;
427 void mini_install_dbg_callbacks (MonoDebuggerCallbacks
*cbs
);
428 MonoDebuggerCallbacks
*mini_get_dbg_callbacks (void);
430 MonoDomain
* mini_init (const char *filename
, const char *runtime_version
);
431 void mini_cleanup (MonoDomain
*domain
);
432 MONO_API MonoDebugOptions
*mini_get_debug_options (void);
433 MONO_API gboolean
mini_parse_debug_option (const char *option
);
436 mono_install_ftnptr_eh_callback (MonoFtnPtrEHCallback callback
);
438 void mini_jit_init (void);
439 void mini_jit_cleanup (void);
440 void mono_disable_optimizations (guint32 opts
);
441 void mono_set_optimizations (guint32 opts
);
442 void mono_precompile_assemblies (void);
443 MONO_API
int mono_parse_default_optimizations (const char* p
);
444 gboolean
mono_running_on_valgrind (void);
446 MonoLMF
* mono_get_lmf (void);
447 #define mono_get_lmf_addr mono_tls_get_lmf_addr
448 MonoLMF
** mono_get_lmf_addr (void);
449 void mono_set_lmf (MonoLMF
*lmf
);
450 void mono_push_lmf (MonoLMFExt
*ext
);
451 void mono_pop_lmf (MonoLMF
*lmf
);
452 #define mono_get_jit_tls mono_tls_get_jit_tls
453 MonoJitTlsData
* mono_get_jit_tls (void);
454 MONO_API MONO_RT_EXTERNAL_ONLY
455 MonoDomain
* mono_jit_thread_attach (MonoDomain
*domain
);
456 MONO_API
void mono_jit_set_domain (MonoDomain
*domain
);
458 gboolean
mono_method_same_domain (MonoJitInfo
*caller
, MonoJitInfo
*callee
);
459 gpointer
mono_create_ftnptr (MonoDomain
*domain
, gpointer addr
);
460 MonoMethod
* mono_icall_get_wrapper_method (MonoJitICallInfo
* callinfo
) MONO_LLVM_INTERNAL
;
461 gconstpointer
mono_icall_get_wrapper (MonoJitICallInfo
* callinfo
) MONO_LLVM_INTERNAL
;
462 gconstpointer
mono_icall_get_wrapper_full (MonoJitICallInfo
* callinfo
, gboolean do_compile
) MONO_LLVM_INTERNAL
;
464 MonoJumpInfo
* mono_patch_info_dup_mp (MonoMemPool
*mp
, MonoJumpInfo
*patch_info
);
465 guint
mono_patch_info_hash (gconstpointer data
) MONO_LLVM_INTERNAL
;
466 gint
mono_patch_info_equal (gconstpointer ka
, gconstpointer kb
) MONO_LLVM_INTERNAL
;
467 MonoJumpInfo
*mono_patch_info_list_prepend (MonoJumpInfo
*list
, int ip
, MonoJumpInfoType type
, gconstpointer target
);
468 MonoJumpInfoToken
* mono_jump_info_token_new (MonoMemPool
*mp
, MonoImage
*image
, guint32 token
);
469 MonoJumpInfoToken
* mono_jump_info_token_new2 (MonoMemPool
*mp
, MonoImage
*image
, guint32 token
, MonoGenericContext
*context
);
470 gpointer
mono_resolve_patch_target (MonoMethod
*method
, MonoDomain
*domain
, guint8
*code
, MonoJumpInfo
*patch_info
, gboolean run_cctors
, MonoError
*error
) MONO_LLVM_INTERNAL
;
471 void mini_register_jump_site (MonoDomain
*domain
, MonoMethod
*method
, gpointer ip
);
472 void mini_patch_jump_sites (MonoDomain
*domain
, MonoMethod
*method
, gpointer addr
);
473 void mini_patch_llvm_jit_callees (MonoDomain
*domain
, MonoMethod
*method
, gpointer addr
);
474 gpointer
mono_jit_search_all_backends_for_jit_info (MonoDomain
*domain
, MonoMethod
*method
, MonoJitInfo
**ji
);
475 gpointer
mono_jit_find_compiled_method_with_jit_info (MonoDomain
*domain
, MonoMethod
*method
, MonoJitInfo
**ji
);
476 gpointer
mono_jit_find_compiled_method (MonoDomain
*domain
, MonoMethod
*method
);
477 gpointer
mono_jit_compile_method (MonoMethod
*method
, MonoError
*error
);
478 gpointer
mono_jit_compile_method_jit_only (MonoMethod
*method
, MonoError
*error
);
480 void mono_set_bisect_methods (guint32 opt
, const char *method_list_filename
);
481 guint32
mono_get_optimizations_for_method (MonoMethod
*method
, guint32 default_opt
);
482 char* mono_opt_descr (guint32 flags
);
483 void mono_set_verbose_level (guint32 level
);
484 const char*mono_ji_type_to_string (MonoJumpInfoType type
) MONO_LLVM_INTERNAL
;
485 void mono_print_ji (const MonoJumpInfo
*ji
);
486 MONO_API
void mono_print_method_from_ip (void *ip
);
487 MONO_API
char *mono_pmip (void *ip
);
488 MONO_API
int mono_ee_api_version (void);
489 gboolean
mono_debug_count (void);
492 #define XDEBUG_ENABLED 1
496 /* maybe enable also for other systems? */
497 #define ENABLE_JIT_MAP 1
498 void mono_enable_jit_map (void);
499 void mono_emit_jit_map (MonoJitInfo
*jinfo
);
500 void mono_emit_jit_tramp (void *start
, int size
, const char *desc
);
501 gboolean
mono_jit_map_is_enabled (void);
503 #define mono_enable_jit_map()
504 #define mono_emit_jit_map(ji)
505 #define mono_emit_jit_tramp(s,z,d)
506 #define mono_jit_map_is_enabled() (0)
510 * Per-OS implementation functions.
513 mono_runtime_install_handlers (void);
516 mono_runtime_install_custom_handlers (const char *handlers
);
519 mono_runtime_install_custom_handlers_usage (void);
522 mono_runtime_cleanup_handlers (void);
525 mono_runtime_setup_stat_profiler (void);
528 mono_runtime_shutdown_stat_profiler (void);
531 mono_runtime_posix_install_handlers (void);
534 mono_gdb_render_native_backtraces (pid_t crashed_pid
);
537 mono_cross_helpers_run (void);
540 mono_init_native_crash_info (void);
543 mono_cleanup_native_crash_info (void);
546 mono_dump_native_crash_info (const char *signal
, MonoContext
*mctx
, MONO_SIG_HANDLER_INFO_TYPE
*info
);
549 mono_post_native_crash_handler (const char *signal
, MonoContext
*mctx
, MONO_SIG_HANDLER_INFO_TYPE
*info
, gboolean crash_chaining
);
555 #if defined(DISABLE_HW_TRAPS) || defined(MONO_ARCH_DISABLE_HW_TRAPS)
556 // Signal handlers not available
557 #define MONO_ARCH_NEED_DIV_CHECK 1
560 void MONO_SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler
) ;
561 void MONO_SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler
) ;
562 void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler
);
563 void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler
) ;
564 gboolean
MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal
);
566 #if defined (HOST_WASM)
568 #define MONO_RETURN_ADDRESS_N(N) NULL
569 #define MONO_RETURN_ADDRESS() MONO_RETURN_ADDRESS_N(0)
572 #elif defined (__GNUC__)
574 #define MONO_RETURN_ADDRESS_N(N) (__builtin_extract_return_addr (__builtin_return_address (N)))
575 #define MONO_RETURN_ADDRESS() MONO_RETURN_ADDRESS_N(0)
577 #elif defined(_MSC_VER)
580 #pragma intrinsic(_ReturnAddress)
582 #define MONO_RETURN_ADDRESS() _ReturnAddress()
583 #define MONO_RETURN_ADDRESS_N(N) NULL
587 #error "Missing return address intrinsics implementation"
591 //have a global view of sdb disable
592 #if !defined(MONO_ARCH_SOFT_DEBUG_SUPPORTED) || defined (DISABLE_DEBUGGER_AGENT)
593 #define DISABLE_SDB 1
596 void mini_register_sigterm_handler (void);
598 #endif /* __MONO_MINI_RUNTIME_H__ */