3 * Copyright 2002-2003 Ximian Inc
4 * Copyright 2003-2011 Novell Inc
5 * Copyright 2011 Xamarin Inc
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
8 #ifndef __MONO_MINI_H__
9 #define __MONO_MINI_H__
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
19 #include <mono/utils/mono-forward-internal.h>
20 #include <mono/metadata/loader.h>
21 #include <mono/metadata/mempool.h>
22 #include <mono/utils/monobitset.h>
23 #include <mono/metadata/class.h>
24 #include <mono/metadata/object.h>
25 #include <mono/metadata/opcodes.h>
26 #include <mono/metadata/tabledefs.h>
27 #include <mono/metadata/domain-internals.h>
28 #include "mono/metadata/class-internals.h"
29 #include "mono/metadata/class-init.h"
30 #include "mono/metadata/object-internals.h"
31 #include <mono/metadata/profiler-private.h>
32 #include <mono/metadata/debug-helpers.h>
33 #include <mono/metadata/abi-details.h>
34 #include <mono/utils/mono-compiler.h>
35 #include <mono/utils/mono-machine.h>
36 #include <mono/utils/mono-stack-unwinding.h>
37 #include <mono/utils/mono-threads.h>
38 #include <mono/utils/mono-threads-coop.h>
39 #include <mono/utils/mono-tls.h>
40 #include <mono/utils/atomic.h>
41 #include <mono/utils/mono-jemalloc.h>
42 #include <mono/utils/mono-conc-hashtable.h>
43 #include <mono/utils/mono-signal-handler.h>
44 #include <mono/metadata/icalls.h>
46 // Forward declare so that mini-*.h can have pointers to them.
47 // CallInfo is presently architecture specific.
48 typedef struct MonoInst MonoInst
;
49 typedef struct CallInfo CallInfo
;
50 typedef struct SeqPointInfo SeqPointInfo
;
52 #include "mini-arch.h"
54 #include "mini-unwind.h"
58 #include "mono/metadata/tabledefs.h"
59 #include "mono/metadata/marshal.h"
60 #include "mono/metadata/security-manager.h"
61 #include "mono/metadata/exception.h"
62 #include "mono/metadata/callspec.h"
63 #include "mono/metadata/icall-signatures.h"
66 * The mini code should not have any compile time dependencies on the GC being used, so the same object file from mini/
67 * can be linked into both mono and mono-sgen.
69 #if !defined(MONO_DLL_EXPORT) || !defined(_MSC_VER)
70 #if defined(HAVE_BOEHM_GC) || defined(HAVE_SGEN_GC)
71 #error "The code in mini/ should not depend on these defines."
76 /*#define __alignof__(a) sizeof(a)*/
77 #define __alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
81 #define MINI_DEBUG(level,limit,code)
83 #define MINI_DEBUG(level,limit,code) do {if (G_UNLIKELY ((level) >= (limit))) code} while (0)
86 #if !defined(DISABLE_TASKLETS) && defined(MONO_ARCH_SUPPORT_TASKLETS)
88 #define MONO_SUPPORT_TASKLETS 1
89 #elif defined(HOST_WIN32)
90 #define MONO_SUPPORT_TASKLETS 1
91 // Replace some gnu intrinsics needed for tasklets with MSVC equivalents.
92 #define __builtin_extract_return_addr(x) x
93 #define __builtin_return_address(x) _ReturnAddress()
94 #define __builtin_frame_address(x) _AddressOfReturnAddress()
99 #define COMPILE_LLVM(cfg) ((cfg)->compile_llvm)
100 #define LLVM_ENABLED TRUE
102 #define COMPILE_LLVM(cfg) (0)
103 #define LLVM_ENABLED FALSE
106 #ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
107 #define COMPILE_SOFT_FLOAT(cfg) (!COMPILE_LLVM ((cfg)) && mono_arch_is_soft_float ())
109 #define COMPILE_SOFT_FLOAT(cfg) (0)
112 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
114 /* for 32 bit systems */
115 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
116 #define MINI_LS_WORD_IDX 0
117 #define MINI_MS_WORD_IDX 1
119 #define MINI_LS_WORD_IDX 1
120 #define MINI_MS_WORD_IDX 0
122 #define MINI_LS_WORD_OFFSET (MINI_LS_WORD_IDX * 4)
123 #define MINI_MS_WORD_OFFSET (MINI_MS_WORD_IDX * 4)
125 #define MONO_LVREG_LS(lvreg) ((lvreg) + 1)
126 #define MONO_LVREG_MS(lvreg) ((lvreg) + 2)
129 #define MONO_USE_AOT_COMPILER
132 //TODO: This is x86/amd64 specific.
133 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
135 /* Remap printf to g_print (we use a mix of these in the mini code) */
137 #define printf g_print
140 #define MONO_TYPE_IS_PRIMITIVE(t) ((!(t)->byref && ((((t)->type >= MONO_TYPE_BOOLEAN && (t)->type <= MONO_TYPE_R8) || ((t)->type >= MONO_TYPE_I && (t)->type <= MONO_TYPE_U)))))
141 //XXX this ignores if t is byref
142 #define MONO_TYPE_IS_PRIMITIVE_SCALAR(t) ((((((t)->type >= MONO_TYPE_BOOLEAN && (t)->type <= MONO_TYPE_U8) || ((t)->type >= MONO_TYPE_I && (t)->type <= MONO_TYPE_U)))))
148 } MonoClassMethodPair
;
155 } MonoDelegateClassMethodPair
;
159 MonoCodeManager
*code_mp
;
160 } MonoJitDynamicMethodInfo
;
162 /* An extension of MonoGenericParamFull used in generic sharing */
164 MonoGenericParamFull param
;
165 MonoGenericParam
*parent
;
166 } MonoGSharedGenericParam
;
168 /* Contains a list of ips which needs to be patched when a method is compiled */
180 MonoExceptionClause
*clause
;
184 * Information about a stack frame.
185 * FIXME This typedef exists only to avoid tons of code rewriting
187 typedef MonoStackFrameInfo StackFrameInfo
;
190 #define mono_bitset_foreach_bit(set,b,n) \
191 for (b = 0; b < n; b++)\
192 if (mono_bitset_test_fast(set,b))
194 #define mono_bitset_foreach_bit(set,b,n) \
195 for (b = mono_bitset_find_start (set); b < n && b >= 0; b = mono_bitset_find_first (set, b))
199 * Pull the list of opcodes
201 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
205 #include "mono/cil/opcode.def"
210 #define MONO_VARINFO(cfg,varnum) (&(cfg)->vars [varnum])
212 #define MONO_INST_NULLIFY_SREGS(dest) do { \
213 (dest)->sreg1 = (dest)->sreg2 = (dest)->sreg3 = -1; \
216 #define MONO_INST_NEW(cfg,dest,op) do { \
217 (dest) = (MonoInst *)mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
218 (dest)->opcode = (op); \
220 MONO_INST_NULLIFY_SREGS ((dest)); \
221 (dest)->cil_code = (cfg)->ip; \
224 #define MONO_INST_NEW_CALL(cfg,dest,op) do { \
225 (dest) = (MonoCallInst *)mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallInst)); \
226 (dest)->inst.opcode = (op); \
227 (dest)->inst.dreg = -1; \
228 MONO_INST_NULLIFY_SREGS (&(dest)->inst); \
229 (dest)->inst.cil_code = (cfg)->ip; \
232 #define MONO_ADD_INS(b,inst) do { \
233 if ((b)->last_ins) { \
234 (b)->last_ins->next = (inst); \
235 (inst)->prev = (b)->last_ins; \
236 (b)->last_ins = (inst); \
238 (b)->code = (b)->last_ins = (inst); \
242 #define NULLIFY_INS(ins) do { \
243 (ins)->opcode = OP_NOP; \
245 MONO_INST_NULLIFY_SREGS ((ins)); \
248 /* Remove INS from BB */
249 #define MONO_REMOVE_INS(bb,ins) do { \
251 (ins)->prev->next = (ins)->next; \
253 (ins)->next->prev = (ins)->prev; \
254 if ((bb)->code == (ins)) \
255 (bb)->code = (ins)->next; \
256 if ((bb)->last_ins == (ins)) \
257 (bb)->last_ins = (ins)->prev; \
260 /* Remove INS from BB and nullify it */
261 #define MONO_DELETE_INS(bb,ins) do { \
262 MONO_REMOVE_INS ((bb), (ins)); \
263 NULLIFY_INS ((ins)); \
267 * this is used to determine when some branch optimizations are possible: we exclude FP compares
268 * because they have weird semantics with NaNs.
270 #define MONO_IS_COND_BRANCH_OP(ins) (((ins)->opcode >= OP_LBEQ && (ins)->opcode <= OP_LBLT_UN) || ((ins)->opcode >= OP_FBEQ && (ins)->opcode <= OP_FBLT_UN) || ((ins)->opcode >= OP_IBEQ && (ins)->opcode <= OP_IBLT_UN))
271 #define MONO_IS_COND_BRANCH_NOFP(ins) (MONO_IS_COND_BRANCH_OP(ins) && !(((ins)->opcode >= OP_FBEQ) && ((ins)->opcode <= OP_FBLT_UN)))
273 #define MONO_IS_BRANCH_OP(ins) (MONO_IS_COND_BRANCH_OP(ins) || ((ins)->opcode == OP_BR) || ((ins)->opcode == OP_BR_REG) || ((ins)->opcode == OP_SWITCH))
275 #define MONO_IS_COND_EXC(ins) ((((ins)->opcode >= OP_COND_EXC_EQ) && ((ins)->opcode <= OP_COND_EXC_LT_UN)) || (((ins)->opcode >= OP_COND_EXC_IEQ) && ((ins)->opcode <= OP_COND_EXC_ILT_UN)))
277 #define MONO_IS_SETCC(ins) ((((ins)->opcode >= OP_CEQ) && ((ins)->opcode <= OP_CLT_UN)) || (((ins)->opcode >= OP_ICEQ) && ((ins)->opcode <= OP_ICLE_UN)) || (((ins)->opcode >= OP_LCEQ) && ((ins)->opcode <= OP_LCLT_UN)) || (((ins)->opcode >= OP_FCEQ) && ((ins)->opcode <= OP_FCLT_UN)))
279 #define MONO_HAS_CUSTOM_EMULATION(ins) (((ins)->opcode >= OP_FBEQ && (ins)->opcode <= OP_FBLT_UN) || ((ins)->opcode >= OP_FCEQ && (ins)->opcode <= OP_FCLT_UN))
281 #define MONO_IS_LOAD_MEMBASE(ins) (((ins)->opcode >= OP_LOAD_MEMBASE && (ins)->opcode <= OP_LOADV_MEMBASE) || ((ins)->opcode >= OP_ATOMIC_LOAD_I1 && (ins)->opcode <= OP_ATOMIC_LOAD_R8))
282 #define MONO_IS_STORE_MEMBASE(ins) (((ins)->opcode >= OP_STORE_MEMBASE_REG && (ins)->opcode <= OP_STOREV_MEMBASE) || ((ins)->opcode >= OP_ATOMIC_STORE_I1 && (ins)->opcode <= OP_ATOMIC_STORE_R8))
283 #define MONO_IS_STORE_MEMINDEX(ins) (((ins)->opcode >= OP_STORE_MEMINDEX) && ((ins)->opcode <= OP_STORER8_MEMINDEX))
285 // This is internal because it is easily confused with any enum or integer.
286 #define MONO_IS_TAILCALL_OPCODE_INTERNAL(opcode) ((opcode) == OP_TAILCALL || (opcode) == OP_TAILCALL_MEMBASE || (opcode) == OP_TAILCALL_REG)
288 #define MONO_IS_TAILCALL_OPCODE(call) (MONO_IS_TAILCALL_OPCODE_INTERNAL (call->inst.opcode))
290 // OP_DYN_CALL is not a MonoCallInst
291 #define MONO_IS_CALL(ins) (((ins)->opcode >= OP_VOIDCALL && (ins)->opcode <= OP_VCALL2_MEMBASE) || \
292 MONO_IS_TAILCALL_OPCODE_INTERNAL ((ins)->opcode))
294 #define MONO_IS_JUMP_TABLE(ins) (((ins)->opcode == OP_JUMP_TABLE) ? TRUE : ((((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : ((ins)->opcode == OP_SWITCH) ? TRUE : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : FALSE)))
296 #define MONO_JUMP_TABLE_FROM_INS(ins) (((ins)->opcode == OP_JUMP_TABLE) ? (ins)->inst_p0 : (((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH) ? (ins)->inst_p0 : (((ins)->opcode == OP_SWITCH) ? (ins)->inst_p0 : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? (ins)->inst_right->inst_p0 : NULL))))
298 /* FIXME: Add more instructions */
299 /* INEG sets the condition codes, and the OP_LNEG decomposition depends on this on x86 */
300 #define MONO_INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || MONO_IS_ZERO (ins) || (ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode == OP_LADD_IMM) || (ins->opcode == OP_ISUB_IMM) || (ins->opcode == OP_IADD_IMM) || (ins->opcode == OP_LNEG) || (ins->opcode == OP_ISUB) || (ins->opcode == OP_CMOV_IGE) || (ins->opcode == OP_ISHL_IMM) || (ins->opcode == OP_ISHR_IMM) || (ins->opcode == OP_ISHR_UN_IMM) || (ins->opcode == OP_IAND_IMM) || (ins->opcode == OP_ICONV_TO_U1) || (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_SEXT_I4) || (ins->opcode == OP_LCONV_TO_U1) || (ins->opcode == OP_ICONV_TO_U2) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_LCONV_TO_I2) || (ins->opcode == OP_LDADDR) || (ins->opcode == OP_PHI) || (ins->opcode == OP_NOP) || (ins->opcode == OP_ZEXT_I4) || (ins->opcode == OP_NOT_NULL) || (ins->opcode == OP_IL_SEQ_POINT) || (ins->opcode == OP_XZERO))
302 #define MONO_INS_IS_PCONST_NULL(ins) ((ins)->opcode == OP_PCONST && (ins)->inst_p0 == 0)
304 #define MONO_METHOD_IS_FINAL(m) (((m)->flags & METHOD_ATTRIBUTE_FINAL) || ((m)->klass && (mono_class_get_flags ((m)->klass) & TYPE_ATTRIBUTE_SEALED)))
306 /* Determine whenever 'ins' represents a load of the 'this' argument */
307 #define MONO_CHECK_THIS(ins) (mono_method_signature_internal (cfg->method)->hasthis && ((ins)->opcode == OP_MOVE) && ((ins)->sreg1 == cfg->args [0]->dreg))
309 #ifdef MONO_ARCH_SIMD_INTRINSICS
311 #define MONO_IS_PHI(ins) (((ins)->opcode == OP_PHI) || ((ins)->opcode == OP_FPHI) || ((ins)->opcode == OP_VPHI) || ((ins)->opcode == OP_XPHI))
312 #define MONO_IS_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_VMOVE) || ((ins)->opcode == OP_XMOVE) || ((ins)->opcode == OP_RMOVE))
313 #define MONO_IS_NON_FP_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_VMOVE) || ((ins)->opcode == OP_XMOVE))
314 #define MONO_IS_REAL_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_XMOVE) || ((ins)->opcode == OP_RMOVE))
315 #define MONO_IS_ZERO(ins) (((ins)->opcode == OP_VZERO) || ((ins)->opcode == OP_XZERO))
317 #define MONO_CLASS_IS_SIMD(cfg, klass) (((cfg)->opt & MONO_OPT_SIMD) && m_class_is_simd_type (klass))
321 #define MONO_IS_PHI(ins) (((ins)->opcode == OP_PHI) || ((ins)->opcode == OP_FPHI) || ((ins)->opcode == OP_VPHI))
322 #define MONO_IS_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_VMOVE) || ((ins)->opcode == OP_RMOVE))
323 #define MONO_IS_NON_FP_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_VMOVE))
324 /*A real MOVE is one that isn't decomposed such as a VMOVE or LMOVE*/
325 #define MONO_IS_REAL_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_RMOVE))
326 #define MONO_IS_ZERO(ins) ((ins)->opcode == OP_VZERO)
328 #define MONO_CLASS_IS_SIMD(cfg, klass) (0)
332 #if defined(TARGET_X86) || defined(TARGET_AMD64)
333 #define EMIT_NEW_X86_LEA(cfg,dest,sr1,sr2,shift,imm) do { \
334 MONO_INST_NEW (cfg, dest, OP_X86_LEA); \
335 (dest)->dreg = alloc_ireg_mp ((cfg)); \
336 (dest)->sreg1 = (sr1); \
337 (dest)->sreg2 = (sr2); \
338 (dest)->inst_imm = (imm); \
339 (dest)->backend.shift_amount = (shift); \
340 MONO_ADD_INS ((cfg)->cbb, (dest)); \
344 typedef struct MonoInstList MonoInstList
;
345 typedef struct MonoCallInst MonoCallInst
;
346 typedef struct MonoCallArgParm MonoCallArgParm
;
347 typedef struct MonoMethodVar MonoMethodVar
;
348 typedef struct MonoBasicBlock MonoBasicBlock
;
349 typedef struct MonoSpillInfo MonoSpillInfo
;
351 extern MonoCallSpec
*mono_jit_trace_calls
;
352 extern MonoMethodDesc
*mono_inject_async_exc_method
;
353 extern int mono_inject_async_exc_pos
;
354 extern MonoMethodDesc
*mono_break_at_bb_method
;
355 extern int mono_break_at_bb_bb_num
;
356 extern gboolean mono_do_x86_stack_align
;
357 extern gboolean mono_using_xdebug
;
358 extern int mini_verbose
;
359 extern int valgrind_register
;
361 #define INS_INFO(opcode) (&mini_ins_info [((opcode) - OP_START - 1) * 4])
363 extern const char mini_ins_info
[];
364 extern const gint8 mini_ins_sreg_counts
[];
367 #define mono_inst_get_num_src_registers(ins) (mini_ins_sreg_counts [(ins)->opcode - OP_START - 1])
369 #define mono_inst_get_num_src_registers(ins) 0
372 #define mono_inst_get_src_registers(ins, regs) (((regs) [0] = (ins)->sreg1), ((regs) [1] = (ins)->sreg2), ((regs) [2] = (ins)->sreg3), mono_inst_get_num_src_registers ((ins)))
374 #define MONO_BB_FOR_EACH_INS(bb, ins) for ((ins) = (bb)->code; (ins); (ins) = (ins)->next)
376 #define MONO_BB_FOR_EACH_INS_SAFE(bb, n, ins) for ((ins) = (bb)->code, n = (ins) ? (ins)->next : NULL; (ins); (ins) = (n), (n) = (ins) ? (ins)->next : NULL)
378 #define MONO_BB_FOR_EACH_INS_REVERSE(bb, ins) for ((ins) = (bb)->last_ins; (ins); (ins) = (ins)->prev)
380 #define MONO_BB_FOR_EACH_INS_REVERSE_SAFE(bb, p, ins) for ((ins) = (bb)->last_ins, p = (ins) ? (ins)->prev : NULL; (ins); (ins) = (p), (p) = (ins) ? (ins)->prev : NULL)
382 #define mono_bb_first_ins(bb) (bb)->code
385 * Iterate through all used registers in the instruction.
386 * Relies on the existing order of the MONO_INST enum: MONO_INST_{DREG,SREG1,SREG2,SREG3,LEN}
387 * INS is the instruction, IDX is the register index, REG is the pointer to a register.
389 #define MONO_INS_FOR_EACH_REG(ins, idx, reg) for ((idx) = INS_INFO ((ins)->opcode)[MONO_INST_DEST] != ' ' ? MONO_INST_DEST : \
390 (mono_inst_get_num_src_registers (ins) ? MONO_INST_SRC1 : MONO_INST_LEN); \
391 (reg) = (idx) == MONO_INST_DEST ? &(ins)->dreg : \
392 ((idx) == MONO_INST_SRC1 ? &(ins)->sreg1 : \
393 ((idx) == MONO_INST_SRC2 ? &(ins)->sreg2 : \
394 ((idx) == MONO_INST_SRC3 ? &(ins)->sreg3 : NULL))), \
395 idx < MONO_INST_LEN; \
396 (idx) = (idx) > mono_inst_get_num_src_registers (ins) + (INS_INFO ((ins)->opcode)[MONO_INST_DEST] != ' ') ? MONO_INST_LEN : (idx) + 1)
398 struct MonoSpillInfo
{
403 * Information about a call site for the GC map creation code
406 /* The next offset after the call instruction */
408 /* The basic block containing the call site */
411 * The set of variables live at the call site.
412 * Has length cfg->num_varinfo in bits.
416 * List of OP_GC_PARAM_SLOT_LIVENESS_DEF instructions defining the param slots
423 * The IR-level extended basic block.
425 * A basic block can have multiple exits just fine, as long as the point of
426 * 'departure' is the last instruction in the basic block. Extended basic
427 * blocks, on the other hand, may have instructions that leave the block
428 * midstream. The important thing is that they cannot be _entered_
429 * midstream, ie, execution of a basic block (or extened bb) always start
430 * at the beginning of the block, never in the middle.
432 struct MonoBasicBlock
{
435 /* the next basic block in the order it appears in IL */
436 MonoBasicBlock
*next_bb
;
439 * Before instruction selection it is the first tree in the
440 * forest and the first item in the list of trees. After
441 * instruction selection it is the first instruction and the
442 * first item in the list of instructions.
446 /* unique block number identification */
451 /* Basic blocks: incoming and outgoing counts and pointers */
452 /* Each bb should only appear once in each array */
453 gint16 out_count
, in_count
;
454 MonoBasicBlock
**in_bb
;
455 MonoBasicBlock
**out_bb
;
457 /* Points to the start of the CIL code that initiated this BB */
458 unsigned char* cil_code
;
460 /* Length of the CIL block */
463 /* The offset of the generated code, used for fixups */
465 /* The length of the generated code, doesn't include alignment padding */
467 /* The real native offset, which includes alignment padding too */
468 int real_native_offset
;
472 /* Visited and reachable flags */
476 * SSA and loop based flags
478 MonoBitSet
*dominators
;
479 MonoBitSet
*dfrontier
;
480 MonoBasicBlock
*idom
;
482 /* fast dominator algorithm */
483 MonoBasicBlock
*df_parent
, *ancestor
, *child
, *label
;
484 int size
, sdom
, idomn
;
486 /* loop nesting and recognition */
489 gint8 loop_body_start
;
492 * Whenever the bblock is rarely executed so it should be emitted after
493 * the function epilog.
495 guint out_of_line
: 1;
496 /* Caches the result of uselessness calculation during optimize_branches */
497 guint not_useless
: 1;
498 /* Whenever the decompose_array_access_opts () pass needs to process this bblock */
499 guint needs_decompose
: 1;
500 /* Whenever this bblock is extended, ie. it has branches inside it */
502 /* Whenever this bblock contains a OP_JUMP_TABLE instruction */
503 guint has_jump_table
: 1;
504 /* Whenever this bblock contains an OP_CALL_HANDLER instruction */
505 guint has_call_handler
: 1;
506 /* Whenever this bblock starts a try block */
510 /* The offset of the CIL instruction in this bblock which ends a try block */
515 * If this is set, extend the try range started by this bblock by an arch specific
516 * number of bytes to encompass the end of the previous bblock (e.g. a Monitor.Enter
519 guint extend_try_block
: 1;
521 /* use for liveness analysis */
523 MonoBitSet
*kill_set
;
524 MonoBitSet
*live_in_set
;
525 MonoBitSet
*live_out_set
;
527 /* fields to deal with non-empty stack slots at bb boundary */
528 guint16 out_scount
, in_scount
;
529 MonoInst
**out_stack
;
532 /* we use that to prevent merging of bblocks covered by different clauses*/
537 // The MonoInst of the last sequence point for the current basic block.
538 MonoInst
*last_seq_point
;
540 // This will hold a list of last sequence points of incoming basic blocks
541 MonoInst
**pred_seq_points
;
542 guint num_pred_seq_points
;
544 GSList
*spill_slot_defs
;
546 /* List of call sites in this bblock sorted by pc_offset */
547 GSList
*gc_callsites
;
550 * If this is not null, the basic block is a try hole for all the clauses
551 * in the list previous to this element (including the element).
556 * The region encodes whether the basic block is inside
557 * a finally, catch, filter or none of these.
559 * If the value is -1, then it is neither finally, catch nor filter
561 * Otherwise the format is:
563 * Bits: | 0-3 | 4-7 | 8-31
565 * | clause-flags | MONO_REGION | clause-index
570 /* The current symbolic register number, used in local register allocation. */
577 BB_REACHABLE
= 1 << 1,
578 BB_EXCEPTION_DEAD_OBJ
= 1 << 2,
579 BB_EXCEPTION_UNSAFE
= 1 << 3,
580 BB_EXCEPTION_HANDLER
= 1 << 4,
581 /* for Native Client, mark the blocks that can be jumped to indirectly */
582 BB_INDIRECT_JUMP_TARGET
= 1 << 5
585 typedef struct MonoMemcpyArgs
{
591 /* Scalar argument passed by value */
593 /* Only in ainfo->pair_storage */
595 /* Only in ainfo->pair_storage */
597 /* Valuetype passed in 1-2 consecutive register */
600 LLVMArgVtypeRetAddr
, /* On on cinfo->ret */
602 /* Fixed size argument passed to/returned from gsharedvt method by ref */
603 LLVMArgGsharedvtFixed
,
604 /* Fixed size vtype argument passed to/returned from gsharedvt method by ref */
605 LLVMArgGsharedvtFixedVtype
,
606 /* Variable sized argument passed to/returned from gsharedvt method by ref */
607 LLVMArgGsharedvtVariable
,
608 /* Vtype passed/returned as one int array argument */
610 /* Vtype passed as a set of fp arguments */
613 * Only for returns, a structure which
614 * consists of floats/doubles.
618 /* Vtype returned as an int */
623 LLVMArgStorage storage
;
626 * Only if storage == ArgVtypeInReg/LLVMArgAsFpArgs.
627 * This contains how the parts of the vtype are passed.
629 LLVMArgStorage pair_storage
[8];
631 * Only if storage == LLVMArgAsIArgs/LLVMArgAsFpArgs/LLVMArgFpStruct.
632 * If storage == LLVMArgAsFpArgs, this is the number of arguments
633 * used to pass the value.
634 * If storage == LLVMArgFpStruct, this is the number of fields
638 /* Only if storage == LLVMArgAsIArgs/LLVMArgAsFpArgs/LLVMArgFpStruct (4/8) */
640 /* Parameter index in the LLVM signature */
643 /* Only if storage == LLVMArgAsFpArgs. Dummy fp args to insert before this arg */
649 /* Whenever there is an rgctx argument */
651 /* Whenever there is an IMT argument */
653 /* Whenever there is a dummy extra argument */
656 * The position of the vret arg in the argument list.
657 * Only if ret->storage == ArgVtypeRetAddr.
661 /* The indexes of various special arguments in the LLVM signature */
662 int vret_arg_pindex
, this_arg_pindex
, rgctx_arg_pindex
, imt_arg_pindex
, dummy_arg_pindex
;
664 /* Inline array of argument info */
665 /* args [0] is for the this argument if it exists */
666 LLVMArgInfo args
[1];
669 #define MONO_MAX_SRC_REGS 3
673 guint8 type
; /* stack type */
676 /* used by the register allocator */
677 gint32 dreg
, sreg1
, sreg2
, sreg3
;
679 MonoInst
*next
, *prev
;
685 target_mgreg_t const_val
;
686 #if (SIZEOF_REGISTER > TARGET_SIZEOF_VOID_P) && (G_BYTE_ORDER == G_BIG_ENDIAN)
688 gpointer p
[SIZEOF_REGISTER
/TARGET_SIZEOF_VOID_P
];
694 MonoMethodSignature
*signature
;
695 MonoBasicBlock
**many_blocks
;
696 MonoBasicBlock
*target_block
;
701 MonoCallInst
*call_inst
;
702 GList
*exception_clauses
;
708 const unsigned char* cil_code
; /* for debugging and bblock splitting */
710 /* used mostly by the backend to store additional info it may need */
715 MonoMemcpyArgs
*memcpy_args
; /* in OP_MEMSET and OP_MEMCPY */
718 gboolean is_pinvoke
; /* for variables in the unmanaged marshal format */
719 gboolean record_cast_details
; /* For CEE_CASTCLASS */
720 MonoInst
*spill_var
; /* for OP_MOVE_I4_TO_F/F_TO_I4 and OP_FCONV_TO_R8_X */
721 guint16 source_opcode
; /*OP_XCONV_R8_TO_I4 needs to know which op was used to do proper widening*/
722 int pc_offset
; /* OP_GC_LIVERANGE_START/END */
725 * memory_barrier: MONO_MEMORY_BARRIER_{ACQ,REL,SEQ}
726 * atomic_load_*: MONO_MEMORY_BARRIER_{ACQ,SEQ}
727 * atomic_store_*: MONO_MEMORY_BARRIER_{REL,SEQ}
729 int memory_barrier_kind
;
735 struct MonoCallInst
{
737 MonoMethodSignature
*signature
;
744 guint stack_align_amount
;
745 guint is_virtual
: 1;
746 // FIXME tailcall field is written after read; prefer MONO_IS_TAILCALL_OPCODE.
748 /* If this is TRUE, 'fptr' points to a MonoJumpInfo instead of an address. */
749 guint fptr_is_patch
: 1;
751 * If this is true, then the call returns a vtype in a register using the same
752 * calling convention as OP_CALL.
754 guint vret_in_reg
: 1;
755 /* Whenever vret_in_reg returns fp values */
756 guint vret_in_reg_fp
: 1;
757 /* Whenever there is an IMT argument and it is dynamic */
758 guint dynamic_imt_arg
: 1;
759 /* Whenever there is an RGCTX argument */
760 guint32 rgctx_reg
: 1;
761 /* Whenever the call will need an unbox trampoline */
762 guint need_unbox_trampoline
: 1;
763 regmask_t used_iregs
;
764 regmask_t used_fregs
;
765 GSList
*out_ireg_args
;
766 GSList
*out_freg_args
;
771 int rgctx_arg_reg
, imt_arg_reg
;
774 /* See the comment in mini-arm.c!mono_arch_emit_call for RegTypeFP. */
779 struct MonoCallArgParm
{
788 * Note: some of the values overlap, because they can't appear
789 * in the same MonoInst.
792 MONO_INST_HAS_METHOD
= 1,
793 MONO_INST_INIT
= 1, /* in localloc */
794 MONO_INST_SINGLE_STEP_LOC
= 1, /* in SEQ_POINT */
795 MONO_INST_IS_DEAD
= 2,
796 MONO_INST_TAILCALL
= 4,
797 MONO_INST_VOLATILE
= 4,
798 MONO_INST_NOTYPECHECK
= 4,
799 MONO_INST_NONEMPTY_STACK
= 4, /* in SEQ_POINT */
800 MONO_INST_UNALIGNED
= 8,
801 MONO_INST_NESTED_CALL
= 8, /* in SEQ_POINT */
802 MONO_INST_CFOLD_TAKEN
= 8, /* On branches */
803 MONO_INST_CFOLD_NOT_TAKEN
= 16, /* On branches */
804 MONO_INST_DEFINITION_HAS_SIDE_EFFECTS
= 8,
805 /* the address of the variable has been taken */
806 MONO_INST_INDIRECT
= 16,
807 MONO_INST_NORANGECHECK
= 16,
808 /* On loads, the source address can be null */
809 MONO_INST_FAULT
= 32,
811 * On variables, identifies LMF variables. These variables have a dummy type (int), but
812 * require stack space for a MonoLMF struct.
815 /* On loads, the source address points to a constant value */
816 MONO_INST_INVARIANT_LOAD
= 64,
817 /* On variables, the variable needs GC tracking */
818 MONO_INST_GC_TRACK
= 128,
820 * Set on instructions during code emission which make calls, i.e. OP_CALL, OP_THROW.
821 * backend.pc_offset will be set to the pc offset at the end of the native call instructions.
823 MONO_INST_GC_CALLSITE
= 128,
824 /* On comparisons, mark the branch following the condition as likely to be taken */
825 MONO_INST_LIKELY
= 128,
828 #define inst_c0 data.op[0].const_val
829 #define inst_c1 data.op[1].const_val
830 #define inst_i0 data.op[0].src
831 #define inst_i1 data.op[1].src
832 #if (SIZEOF_REGISTER > TARGET_SIZEOF_VOID_P) && (G_BYTE_ORDER == G_BIG_ENDIAN)
833 #define inst_p0 data.op[0].pdata.p[SIZEOF_REGISTER/TARGET_SIZEOF_VOID_P - 1]
834 #define inst_p1 data.op[1].pdata.p[SIZEOF_REGISTER/TARGET_SIZEOF_VOID_P - 1]
836 #define inst_p0 data.op[0].p
837 #define inst_p1 data.op[1].p
839 #define inst_l data.i8const
840 #define inst_r data.r8const
841 #define inst_left data.op[0].src
842 #define inst_right data.op[1].src
844 #define inst_newa_len data.op[0].src
845 #define inst_newa_class data.op[1].klass
847 #define inst_var data.op[0].var
848 #define inst_vtype data.op[1].vtype
849 /* in branch instructions */
850 #define inst_many_bb data.op[1].many_blocks
851 #define inst_target_bb data.op[0].target_block
852 #define inst_true_bb data.op[1].many_blocks[0]
853 #define inst_false_bb data.op[1].many_blocks[1]
855 #define inst_basereg sreg1
856 #define inst_indexreg sreg2
857 #define inst_destbasereg dreg
858 #define inst_offset data.op[0].const_val
859 #define inst_imm data.op[1].const_val
860 #define inst_call data.op[1].call_inst
862 #define inst_phi_args data.op[1].phi_args
863 #define inst_eh_blocks data.op[1].exception_clauses
865 /* Return the lower 32 bits of the 64 bit immediate in INS */
866 static inline guint32
867 ins_get_l_low (MonoInst
*ins
)
869 return (guint32
)(ins
->data
.i8const
& 0xffffffff);
872 /* Return the higher 32 bits of the 64 bit immediate in INS */
873 static inline guint32
874 ins_get_l_high (MonoInst
*ins
)
876 return (guint32
)((ins
->data
.i8const
>> 32) & 0xffffffff);
880 mono_inst_set_src_registers (MonoInst
*ins
, int *regs
)
882 ins
->sreg1
= regs
[0];
883 ins
->sreg2
= regs
[1];
884 ins
->sreg3
= regs
[2];
887 /* instruction description for use in regalloc/scheduling */
890 MONO_INST_SRC1
, /* we depend on the SRCs to be consecutive */
895 /* Unused, commented out to reduce the size of the mdesc tables
906 guint16 tid
; /* tree number */
907 guint16 bid
; /* block number */
913 MonoPosition first_use
, last_use
;
916 typedef struct MonoLiveRange2 MonoLiveRange2
;
918 struct MonoLiveRange2
{
920 MonoLiveRange2
*next
;
924 /* List of live ranges sorted by 'from' */
925 MonoLiveRange2
*range
;
926 MonoLiveRange2
*last_range
;
930 * Additional information about a variable
932 struct MonoMethodVar
{
933 guint idx
; /* inside cfg->varinfo, cfg->vars */
934 MonoLiveRange range
; /* generated by liveness analysis */
935 MonoLiveInterval
*interval
; /* generated by liveness analysis */
936 int reg
; /* != -1 if allocated into a register */
938 MonoBitSet
*def_in
; /* used by SSA */
939 MonoInst
*def
; /* used by SSA */
940 MonoBasicBlock
*def_bb
; /* used by SSA */
941 GList
*uses
; /* used by SSA */
942 char cpstate
; /* used by SSA conditional constant propagation */
943 /* The native offsets corresponding to the live range of the variable */
944 gint32 live_range_start
, live_range_end
;
946 * cfg->varinfo [idx]->dreg could be replaced for OP_REGVAR, this contains the
952 /* Generic sharing */
955 * Flags for which contexts were used in inflating a generic.
958 MONO_GENERIC_CONTEXT_USED_CLASS
= 1,
959 MONO_GENERIC_CONTEXT_USED_METHOD
= 2
963 /* Cannot be 0 since this is stored in rgctx slots, and 0 means an unitialized rgctx slot */
964 MONO_GSHAREDVT_BOX_TYPE_VTYPE
= 1,
965 MONO_GSHAREDVT_BOX_TYPE_REF
= 2,
966 MONO_GSHAREDVT_BOX_TYPE_NULLABLE
= 3
970 MONO_RGCTX_INFO_STATIC_DATA
= 0,
971 MONO_RGCTX_INFO_KLASS
= 1,
972 MONO_RGCTX_INFO_ELEMENT_KLASS
= 2,
973 MONO_RGCTX_INFO_VTABLE
= 3,
974 MONO_RGCTX_INFO_TYPE
= 4,
975 MONO_RGCTX_INFO_REFLECTION_TYPE
= 5,
976 MONO_RGCTX_INFO_METHOD
= 6,
977 MONO_RGCTX_INFO_GENERIC_METHOD_CODE
= 7,
978 MONO_RGCTX_INFO_GSHAREDVT_OUT_WRAPPER
= 8,
979 MONO_RGCTX_INFO_CLASS_FIELD
= 9,
980 MONO_RGCTX_INFO_METHOD_RGCTX
= 10,
981 MONO_RGCTX_INFO_METHOD_CONTEXT
= 11,
982 MONO_RGCTX_INFO_REMOTING_INVOKE_WITH_CHECK
= 12,
983 MONO_RGCTX_INFO_METHOD_DELEGATE_CODE
= 13,
984 MONO_RGCTX_INFO_CAST_CACHE
= 14,
985 MONO_RGCTX_INFO_ARRAY_ELEMENT_SIZE
= 15,
986 MONO_RGCTX_INFO_VALUE_SIZE
= 16,
987 /* +1 to avoid zero values in rgctx slots */
988 MONO_RGCTX_INFO_FIELD_OFFSET
= 17,
989 /* Either the code for a gsharedvt method, or the address for a gsharedvt-out trampoline for the method */
990 /* In llvmonly mode, this is a function descriptor */
991 MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE
= 18,
992 /* Same for virtual calls */
993 /* In llvmonly mode, this is a function descriptor */
994 MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT
= 19,
995 /* Same for calli, associated with a signature */
996 MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI
= 20,
997 MONO_RGCTX_INFO_SIG_GSHAREDVT_IN_TRAMPOLINE_CALLI
= 21,
998 /* One of MONO_GSHAREDVT_BOX_TYPE */
999 MONO_RGCTX_INFO_CLASS_BOX_TYPE
= 22,
1000 /* Resolves to a MonoGSharedVtMethodRuntimeInfo */
1001 MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO
= 23,
1002 MONO_RGCTX_INFO_LOCAL_OFFSET
= 24,
1003 MONO_RGCTX_INFO_MEMCPY
= 25,
1004 MONO_RGCTX_INFO_BZERO
= 26,
1005 /* The address of Nullable<T>.Box () */
1006 /* In llvmonly mode, this is a function descriptor */
1007 MONO_RGCTX_INFO_NULLABLE_CLASS_BOX
= 27,
1008 MONO_RGCTX_INFO_NULLABLE_CLASS_UNBOX
= 28,
1009 /* MONO_PATCH_INFO_VCALL_METHOD */
1010 /* In llvmonly mode, this is a function descriptor */
1011 MONO_RGCTX_INFO_VIRT_METHOD_CODE
= 29,
1013 * MONO_PATCH_INFO_VCALL_METHOD
1014 * Same as MONO_RGCTX_INFO_CLASS_BOX_TYPE, but for the class
1015 * which implements the method.
1017 MONO_RGCTX_INFO_VIRT_METHOD_BOX_TYPE
= 30,
1018 /* Resolve to 2 (TRUE) or 1 (FALSE) */
1019 MONO_RGCTX_INFO_CLASS_IS_REF_OR_CONTAINS_REFS
= 31,
1020 /* The MonoDelegateTrampInfo instance */
1021 MONO_RGCTX_INFO_DELEGATE_TRAMP_INFO
= 32,
1022 /* Same as MONO_PATCH_INFO_METHOD_FTNDESC */
1023 MONO_RGCTX_INFO_METHOD_FTNDESC
= 33,
1024 /* mono_type_size () for a class */
1025 MONO_RGCTX_INFO_CLASS_SIZEOF
= 34
1026 } MonoRgctxInfoType
;
1028 typedef struct _MonoRuntimeGenericContextInfoTemplate
{
1029 MonoRgctxInfoType info_type
;
1031 struct _MonoRuntimeGenericContextInfoTemplate
*next
;
1032 } MonoRuntimeGenericContextInfoTemplate
;
1035 MonoClass
*next_subclass
;
1036 MonoRuntimeGenericContextInfoTemplate
*infos
;
1037 GSList
*method_templates
;
1038 } MonoRuntimeGenericContextTemplate
;
1041 MonoVTable
*class_vtable
; /* must be the first element */
1042 MonoGenericInst
*method_inst
;
1043 gpointer infos
[MONO_ZERO_LEN_ARRAY
];
1044 } MonoMethodRuntimeGenericContext
;
1046 #define MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT (MONO_ABI_SIZEOF (MonoMethodRuntimeGenericContext) - MONO_ZERO_LEN_ARRAY * TARGET_SIZEOF_VOID_P)
1048 #define MONO_RGCTX_SLOT_MAKE_RGCTX(i) (i)
1049 #define MONO_RGCTX_SLOT_MAKE_MRGCTX(i) ((i) | 0x80000000)
1050 #define MONO_RGCTX_SLOT_INDEX(s) ((s) & 0x7fffffff)
1051 #define MONO_RGCTX_SLOT_IS_MRGCTX(s) (((s) & 0x80000000) ? TRUE : FALSE)
1053 #define MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET -2
1057 MonoRuntimeGenericContextInfoTemplate
*entries
;
1058 int num_entries
, count_entries
;
1059 } MonoGSharedVtMethodInfo
;
1061 /* This is used by gsharedvt methods to allocate locals and compute local offsets */
1065 * The results of resolving the entries in MOonGSharedVtMethodInfo->entries.
1066 * We use this instead of rgctx slots since these can be loaded using a load instead
1067 * of a call to an rgctx fetch trampoline.
1069 gpointer entries
[MONO_ZERO_LEN_ARRAY
];
1070 } MonoGSharedVtMethodRuntimeInfo
;
1076 MonoMethodSignature
*invoke_sig
;
1077 MonoMethodSignature
*sig
;
1078 gpointer method_ptr
;
1079 gpointer invoke_impl
;
1081 gpointer impl_nothis
;
1082 gboolean need_rgctx_tramp
;
1083 } MonoDelegateTrampInfo
;
1086 * A function descriptor, which is a function address + argument pair.
1087 * In llvm-only mode, these are used instead of trampolines to pass
1088 * extra arguments to runtime functions/methods.
1097 #define PATCH_INFO(a,b) MONO_PATCH_INFO_ ## a,
1098 #include "patch-info.h"
1103 typedef struct MonoJumpInfoRgctxEntry MonoJumpInfoRgctxEntry
;
1104 typedef struct MonoJumpInfo MonoJumpInfo
;
1105 typedef struct MonoJumpInfoGSharedVtCall MonoJumpInfoGSharedVtCall
;
1108 MONO_TRAMPOLINE_JIT
= 0,
1109 MONO_TRAMPOLINE_JUMP
= 1,
1110 MONO_TRAMPOLINE_RGCTX_LAZY_FETCH
= 2,
1111 MONO_TRAMPOLINE_AOT
= 3,
1112 MONO_TRAMPOLINE_AOT_PLT
= 4,
1113 MONO_TRAMPOLINE_DELEGATE
= 5,
1114 MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING
= 6,
1115 MONO_TRAMPOLINE_VCALL
= 7,
1116 MONO_TRAMPOLINE_NUM
= 8,
1117 } MonoTrampolineType
;
1119 /* These trampolines return normally to their caller */
1120 #define MONO_TRAMPOLINE_TYPE_MUST_RETURN(t) \
1121 ((t) == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH)
1123 /* These trampolines receive an argument directly in a register */
1124 #define MONO_TRAMPOLINE_TYPE_HAS_ARG(t) \
1127 /* optimization flags */
1128 #define OPTFLAG(id,shift,name,descr) MONO_OPT_ ## id = 1 << shift,
1130 #include "optflags-def.h"
1135 * This structure represents a JIT backend.
1138 guint have_card_table_wb
: 1;
1139 guint have_op_generic_class_init
: 1;
1140 guint emulate_mul_div
: 1;
1141 guint emulate_div
: 1;
1142 guint emulate_long_shift_opts
: 1;
1143 guint have_objc_get_selector
: 1;
1144 guint have_generalized_imt_trampoline
: 1;
1145 gboolean have_op_tailcall_membase
: 1;
1146 gboolean have_op_tailcall_reg
: 1;
1147 gboolean have_volatile_non_param_register
: 1;
1148 guint gshared_supported
: 1;
1149 guint use_fpstack
: 1;
1151 guint need_got_var
: 1;
1152 guint need_div_check
: 1;
1153 guint no_unaligned_access
: 1;
1154 guint disable_div_with_mul
: 1;
1155 guint explicit_null_checks
: 1;
1156 guint optimized_div
: 1;
1157 int monitor_enter_adjustment
;
1158 int dyn_call_param_area
;
1161 /* Flags for mini_method_compile () */
1163 /* Whenever to run cctors during JITting */
1164 JIT_FLAG_RUN_CCTORS
= (1 << 0),
1165 /* Whenever this is an AOT compilation */
1166 JIT_FLAG_AOT
= (1 << 1),
1167 /* Whenever this is a full AOT compilation */
1168 JIT_FLAG_FULL_AOT
= (1 << 2),
1169 /* Whenever to compile with LLVM */
1170 JIT_FLAG_LLVM
= (1 << 3),
1171 /* Whenever to disable direct calls to icall functions */
1172 JIT_FLAG_NO_DIRECT_ICALLS
= (1 << 4),
1173 /* Emit explicit null checks */
1174 JIT_FLAG_EXPLICIT_NULL_CHECKS
= (1 << 5),
1175 /* Whenever to compile in llvm-only mode */
1176 JIT_FLAG_LLVM_ONLY
= (1 << 6),
1177 /* Whenever calls to pinvoke functions are made directly */
1178 JIT_FLAG_DIRECT_PINVOKE
= (1 << 7),
1179 /* Whenever this is a compile-all run and the result should be discarded */
1180 JIT_FLAG_DISCARD_RESULTS
= (1 << 8),
1181 /* Whenever to generate code which can work with the interpreter */
1182 JIT_FLAG_INTERP
= (1 << 9),
1185 /* Bit-fields in the MonoBasicBlock.region */
1186 #define MONO_REGION_TRY 0
1187 #define MONO_REGION_FINALLY 16
1188 #define MONO_REGION_CATCH 32
1189 #define MONO_REGION_FAULT 64
1190 #define MONO_REGION_FILTER 128
1192 #define MONO_BBLOCK_IS_IN_REGION(bblock, regtype) (((bblock)->region & (0xf << 4)) == (regtype))
1194 #define MONO_REGION_FLAGS(region) ((region) & 0x7)
1195 #define MONO_REGION_CLAUSE_INDEX(region) (((region) >> 8) - 1)
1197 #define get_vreg_to_inst(cfg, vreg) ((vreg) < (cfg)->vreg_to_inst_len ? (cfg)->vreg_to_inst [(vreg)] : NULL)
1199 #define vreg_is_volatile(cfg, vreg) (G_UNLIKELY (get_vreg_to_inst ((cfg), (vreg)) && (get_vreg_to_inst ((cfg), (vreg))->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT))))
1201 #define vreg_is_ref(cfg, vreg) ((vreg) < (cfg)->vreg_is_ref_len ? (cfg)->vreg_is_ref [(vreg)] : 0)
1202 #define vreg_is_mp(cfg, vreg) ((vreg) < (cfg)->vreg_is_mp_len ? (cfg)->vreg_is_mp [(vreg)] : 0)
1205 * Control Flow Graph and compilation unit information
1209 MonoMethodHeader
*header
;
1210 MonoMemPool
*mempool
;
1212 MonoMethodVar
*vars
;
1214 MonoBasicBlock
*bb_entry
;
1215 MonoBasicBlock
*bb_exit
;
1216 MonoBasicBlock
*bb_init
;
1217 MonoBasicBlock
**bblocks
;
1218 MonoBasicBlock
**cil_offset_to_bb
;
1219 MonoMemPool
*state_pool
; /* used by instruction selection */
1220 MonoBasicBlock
*cbb
; /* used by instruction selection */
1221 MonoInst
*prev_ins
; /* in decompose */
1222 MonoJumpInfo
*patch_info
;
1223 MonoJitInfo
*jit_info
;
1224 MonoJitDynamicMethodInfo
*dynamic_info
;
1225 guint num_bblocks
, max_block_num
;
1227 guint num_varinfo
; /* used items in varinfo */
1228 guint varinfo_count
; /* total storage in varinfo */
1231 gint cil_offset_to_bb_len
;
1233 MonoSpillInfo
*spill_info
[16]; /* machine register spills */
1235 gint spill_info_len
[16];
1236 /* unsigned char *cil_code; */
1237 MonoInst
*domainvar
; /* a cache for the current domain */
1238 MonoInst
*got_var
; /* Global Offset Table variable */
1240 MonoInst
*rgctx_var
; /* Runtime generic context variable (for static generic methods) */
1242 MonoType
**arg_types
;
1243 MonoMethod
*current_method
; /* The method currently processed by method_to_ir () */
1244 MonoMethod
*method_to_register
; /* The method to register in JIT info tables */
1245 MonoGenericContext
*generic_context
;
1248 MonoBackend
*backend
;
1251 * This variable represents the hidden argument holding the vtype
1252 * return address. If the method returns something other than a vtype, or
1253 * the vtype is returned in registers this is NULL.
1255 MonoInst
*vret_addr
;
1258 * This is used to initialize the cil_code field of MonoInst's.
1260 const unsigned char *ip
;
1262 struct MonoAliasingInformation
*aliasing_info
;
1264 /* A hashtable of region ID-> SP var mappings */
1265 /* An SP var is a place to store the stack pointer (used by handlers)*/
1267 * FIXME We can potentially get rid of this, since it was mainly used
1268 * for hijacking return address for handler.
1273 * A hashtable of region ID -> EX var mappings
1274 * An EX var stores the exception object passed to catch/filter blocks
1275 * For finally blocks, it is set to TRUE if we should throw an abort
1276 * once the execution of the finally block is over.
1280 GList
*ldstr_list
; /* used by AOT */
1285 GHashTable
*cbb_hash
;
1287 /* The current virtual register number */
1290 MonoGenericSharingContext gsctx
;
1291 MonoGenericContext
*gsctx_context
;
1293 MonoGSharedVtMethodInfo
*gsharedvt_info
;
1295 /* Points to the gsharedvt locals area at runtime */
1296 MonoInst
*gsharedvt_locals_var
;
1298 /* The localloc instruction used to initialize gsharedvt_locals_var */
1299 MonoInst
*gsharedvt_locals_var_ins
;
1301 /* Points to a MonoGSharedVtMethodRuntimeInfo at runtime */
1302 MonoInst
*gsharedvt_info_var
;
1304 /* For native-to-managed wrappers, CEE_MONO_JIT_(AT|DE)TACH opcodes */
1305 MonoInst
*orig_domain_var
;
1308 MonoInst
*lmf_addr_var
;
1310 MonoInst
*stack_inbalance_var
;
1312 unsigned char *cil_start
;
1313 unsigned char *native_code
;
1319 regmask_t used_int_regs
;
1323 guint32 verbose_level
;
1324 guint32 stack_usage
;
1328 guint disable_aot
: 1;
1329 guint disable_ssa
: 1;
1330 guint disable_llvm
: 1;
1331 guint enable_extended_bblocks
: 1;
1332 guint run_cctors
: 1;
1333 guint need_lmf_area
: 1;
1334 guint compile_aot
: 1;
1336 guint compile_llvm
: 1;
1337 guint got_var_allocated
: 1;
1338 guint ret_var_is_local
: 1;
1339 guint ret_var_set
: 1;
1340 guint unverifiable
: 1;
1341 guint skip_visibility
: 1;
1342 guint disable_reuse_registers
: 1;
1343 guint disable_reuse_stack_slots
: 1;
1344 guint disable_reuse_ref_stack_slots
: 1;
1345 guint disable_ref_noref_stack_slot_share
: 1;
1346 guint disable_initlocals_opt
: 1;
1347 guint disable_initlocals_opt_refs
: 1;
1348 guint disable_omit_fp
: 1;
1349 guint disable_vreg_to_lvreg
: 1;
1350 guint disable_deadce_vars
: 1;
1351 guint disable_out_of_line_bblocks
: 1;
1352 guint disable_direct_icalls
: 1;
1353 guint disable_gc_safe_points
: 1;
1354 guint direct_pinvoke
: 1;
1355 guint create_lmf_var
: 1;
1357 * When this is set, the code to push/pop the LMF from the LMF stack is generated as IR
1358 * instead of being generated in emit_prolog ()/emit_epilog ().
1362 * Whenever to use the mono_lmf TLS variable instead of indirection through the
1363 * mono_lmf_addr TLS variable.
1365 guint gen_write_barriers
: 1;
1366 guint init_ref_vars
: 1;
1367 guint extend_live_ranges
: 1;
1368 guint compute_precise_live_ranges
: 1;
1369 guint has_got_slots
: 1;
1370 guint uses_rgctx_reg
: 1;
1371 guint uses_vtable_reg
: 1;
1372 guint keep_cil_nops
: 1;
1373 guint gen_seq_points
: 1;
1374 /* Generate seq points for use by the debugger */
1375 guint gen_sdb_seq_points
: 1;
1376 guint explicit_null_checks
: 1;
1377 guint compute_gc_maps
: 1;
1378 guint soft_breakpoints
: 1;
1379 guint arch_eh_jit_info
: 1;
1380 guint has_calls
: 1;
1381 guint has_emulated_ops
: 1;
1382 guint has_indirection
: 1;
1383 guint has_atomic_add_i4
: 1;
1384 guint has_atomic_exchange_i4
: 1;
1385 guint has_atomic_cas_i4
: 1;
1386 guint check_pinvoke_callconv
: 1;
1387 guint has_unwind_info_for_epilog
: 1;
1388 guint disable_inline
: 1;
1389 /* Disable inlining into caller */
1390 guint no_inline
: 1;
1392 guint gsharedvt
: 1;
1394 guint llvm_only
: 1;
1396 guint domainvar_inited
: 1;
1397 guint8 uses_simd_intrinsics
;
1399 gpointer debug_info
;
1402 MonoProfilerCoverageInfo
*coverage_info
;
1403 GHashTable
*token_info_hash
;
1404 MonoCompileArch arch
;
1405 guint32 inline_depth
;
1406 /* Size of memory reserved for thunks */
1410 /* Offset between the start of code and the thunks area */
1412 MonoExceptionType exception_type
; /* MONO_EXCEPTION_* */
1413 guint32 exception_data
;
1414 char* exception_message
;
1415 gpointer exception_ptr
;
1417 guint8
* encoded_unwind_ops
;
1418 guint32 encoded_unwind_ops_len
;
1423 /* Fields used by the local reg allocator */
1427 /* Maps vregs to their associated MonoInst's */
1428 /* vregs with an associated MonoInst are 'global' while others are 'local' */
1429 MonoInst
**vreg_to_inst
;
1431 /* Size of above array */
1432 guint32 vreg_to_inst_len
;
1434 /* Marks vregs which hold a GC ref */
1435 /* FIXME: Use a bitmap */
1436 gboolean
*vreg_is_ref
;
1438 /* Size of above array */
1439 guint32 vreg_is_ref_len
;
1441 /* Marks vregs which hold a managed pointer */
1442 /* FIXME: Use a bitmap */
1443 gboolean
*vreg_is_mp
;
1445 /* Size of above array */
1446 guint32 vreg_is_mp_len
;
1449 * The original method to compile, differs from 'method' when doing generic
1452 MonoMethod
*orig_method
;
1454 /* Patches which describe absolute addresses embedded into the native code */
1455 GHashTable
*abs_patches
;
1457 /* Used to implement move_i4_to_f on archs that can't do raw
1458 copy between an ireg and a freg. This is an int32 var.*/
1459 MonoInst
*iconv_raw_var
;
1461 /* Used to implement fconv_to_r8_x. This is a double (8 bytes) var.*/
1462 MonoInst
*fconv_to_r8_x_var
;
1464 /*Use to implement simd constructors. This is a vector (16 bytes) var.*/
1465 MonoInst
*simd_ctor_var
;
1467 /* Used to implement dyn_call */
1468 MonoInst
*dyn_call_var
;
1470 MonoInst
*last_seq_point
;
1472 * List of sequence points represented as IL offset+native offset pairs.
1473 * Allocated using glib.
1474 * IL offset can be -1 or 0xffffff to refer to the sequence points
1475 * inside the prolog and epilog used to implement method entry/exit events.
1477 GPtrArray
*seq_points
;
1479 /* The encoded sequence point info */
1480 struct MonoSeqPointInfo
*seq_point_info
;
1482 /* Method headers which need to be freed after compilation */
1483 GSList
*headers_to_free
;
1486 guint32 got_offset
, ex_info_offset
, method_info_offset
, method_index
;
1488 guint32 got_access_count
;
1489 gpointer llvmonly_init_cond
;
1490 /* Symbol used to refer to this method in generated assembly */
1492 char *asm_debug_symbol
;
1493 char *llvm_method_name
;
1494 int castclass_cache_index
;
1496 MonoJitExceptionInfo
*llvm_ex_info
;
1497 guint32 llvm_ex_info_len
;
1498 int llvm_this_reg
, llvm_this_offset
;
1500 GSList
*try_block_holes
;
1502 /* DWARF location list for 'this' */
1503 GSList
*this_loclist
;
1505 /* DWARF location list for 'rgctx_var' */
1506 GSList
*rgctx_loclist
;
1508 int *gsharedvt_vreg_to_idx
;
1511 GSList
*interp_in_signatures
;
1515 /* The offsets of the locals area relative to the frame pointer */
1516 gint locals_min_stack_offset
, locals_max_stack_offset
;
1518 /* The current CFA rule */
1519 int cur_cfa_reg
, cur_cfa_offset
;
1521 /* The final CFA rule at the end of the prolog */
1522 int cfa_reg
, cfa_offset
;
1524 /* Points to a MonoCompileGC */
1528 * The encoded GC map along with its size. This contains binary data so it can be saved in an AOT
1529 * image etc, but it requires a 4 byte alignment.
1532 guint32 gc_map_size
;
1534 /* Error handling */
1537 /* pointer to context datastructure used for graph dumping */
1538 MonoGraphDumper
*gdump_ctx
;
1541 int stat_allocate_var
;
1542 int stat_locals_stack_size
;
1543 int stat_basic_blocks
;
1544 int stat_cil_code_size
;
1546 int stat_inlineable_methods
;
1547 int stat_inlined_methods
;
1548 int stat_code_reallocs
;
1550 MonoProfilerCallInstrumentationFlags prof_flags
;
1551 gboolean prof_coverage
;
1553 /* For deduplication */
1557 #define MONO_CFG_PROFILE(cfg, flag) \
1558 G_UNLIKELY ((cfg)->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_ ## flag)
1560 #define MONO_CFG_PROFILE_CALL_CONTEXT(cfg) \
1561 (MONO_CFG_PROFILE (cfg, ENTER_CONTEXT) || MONO_CFG_PROFILE (cfg, LEAVE_CONTEXT))
1564 MONO_CFG_HAS_ALLOCA
= 1 << 0,
1565 MONO_CFG_HAS_CALLS
= 1 << 1,
1566 MONO_CFG_HAS_LDELEMA
= 1 << 2,
1567 MONO_CFG_HAS_VARARGS
= 1 << 3,
1568 MONO_CFG_HAS_TAILCALL
= 1 << 4,
1569 MONO_CFG_HAS_FPOUT
= 1 << 5, /* there are fp values passed in int registers */
1570 MONO_CFG_HAS_SPILLUP
= 1 << 6, /* spill var slots are allocated from bottom to top */
1571 MONO_CFG_HAS_CHECK_THIS
= 1 << 7,
1572 MONO_CFG_NEEDS_DECOMPOSE
= 1 << 8,
1573 MONO_CFG_HAS_TYPE_CHECK
= 1 << 9
1577 MONO_CFG_USES_SIMD_INTRINSICS
= 1 << 0,
1578 MONO_CFG_USES_SIMD_INTRINSICS_SIMPLIFY_INDIRECTION
= 1 << 1,
1579 MONO_CFG_USES_SIMD_INTRINSICS_DECOMPOSE_VTYPE
= 1 << 2
1580 } MonoSimdIntrinsicsFlags
;
1583 gint32 methods_compiled
;
1585 gint32 methods_lookups
;
1586 gint32 allocate_var
;
1587 gint32 cil_code_size
;
1588 gint32 native_code_size
;
1589 gint32 code_reallocs
;
1590 gint32 max_code_size_ratio
;
1591 gint32 biggest_method_size
;
1592 gint32 allocated_code_size
;
1593 gint32 allocated_seq_points_size
;
1594 gint32 inlineable_methods
;
1595 gint32 inlined_methods
;
1596 gint32 basic_blocks
;
1597 gint32 max_basic_blocks
;
1598 gint32 locals_stack_size
;
1600 gint32 generic_virtual_invocations
;
1602 gint32 alias_removed
;
1603 gint32 loads_eliminated
;
1604 gint32 stores_eliminated
;
1605 gint32 optimized_divisions
;
1606 gint32 methods_with_llvm
;
1607 gint32 methods_without_llvm
;
1608 gint32 methods_with_interp
;
1609 char *max_ratio_method
;
1610 char *biggest_method
;
1611 gint64 jit_method_to_ir
;
1612 gint64 jit_liveness_handle_exception_clauses
;
1613 gint64 jit_handle_out_of_line_bblock
;
1614 gint64 jit_decompose_long_opts
;
1615 gint64 jit_decompose_typechecks
;
1616 gint64 jit_local_cprop
;
1617 gint64 jit_local_emulate_ops
;
1618 gint64 jit_optimize_branches
;
1619 gint64 jit_handle_global_vregs
;
1620 gint64 jit_local_deadce
;
1621 gint64 jit_local_alias_analysis
;
1622 gint64 jit_if_conversion
;
1623 gint64 jit_bb_ordering
;
1624 gint64 jit_compile_dominator_info
;
1625 gint64 jit_compute_natural_loops
;
1626 gint64 jit_insert_safepoints
;
1627 gint64 jit_ssa_compute
;
1628 gint64 jit_ssa_cprop
;
1629 gint64 jit_ssa_deadce
;
1630 gint64 jit_perform_abc_removal
;
1631 gint64 jit_ssa_remove
;
1632 gint64 jit_local_cprop2
;
1633 gint64 jit_handle_global_vregs2
;
1634 gint64 jit_local_deadce2
;
1635 gint64 jit_optimize_branches2
;
1636 gint64 jit_decompose_vtype_opts
;
1637 gint64 jit_decompose_array_access_opts
;
1638 gint64 jit_liveness_handle_exception_clauses2
;
1639 gint64 jit_analyze_liveness
;
1640 gint64 jit_linear_scan
;
1641 gint64 jit_arch_allocate_vars
;
1642 gint64 jit_spill_global_vars
;
1643 gint64 jit_local_cprop3
;
1644 gint64 jit_local_deadce3
;
1646 gint64 jit_create_jit_info
;
1647 gint64 jit_gc_create_gc_map
;
1648 gint64 jit_save_seq_point_info
;
1653 extern MonoJitStats mono_jit_stats
;
1655 /* opcodes: value assigned after all the CIL opcodes */
1662 #define MINI_OP(a,b,dest,src1,src2) a,
1663 #define MINI_OP3(a,b,dest,src1,src2,src3) a,
1665 OP_START
= MONO_CEE_LAST
- 1,
1666 #include "mini-ops.h"
1672 #if TARGET_SIZEOF_VOID_P == 8
1673 #define OP_PCONST OP_I8CONST
1674 #define OP_DUMMY_PCONST OP_DUMMY_I8CONST
1675 #define OP_PADD OP_LADD
1676 #define OP_PADD_IMM OP_LADD_IMM
1677 #define OP_PSUB_IMM OP_LSUB_IMM
1678 #define OP_PAND_IMM OP_LAND_IMM
1679 #define OP_PXOR_IMM OP_LXOR_IMM
1680 #define OP_PSUB OP_LSUB
1681 #define OP_PMUL OP_LMUL
1682 #define OP_PMUL_IMM OP_LMUL_IMM
1683 #define OP_PNEG OP_LNEG
1684 #define OP_PCONV_TO_I1 OP_LCONV_TO_I1
1685 #define OP_PCONV_TO_U1 OP_LCONV_TO_U1
1686 #define OP_PCONV_TO_I2 OP_LCONV_TO_I2
1687 #define OP_PCONV_TO_U2 OP_LCONV_TO_U2
1688 #define OP_PCONV_TO_OVF_I1_UN OP_LCONV_TO_OVF_I1_UN
1689 #define OP_PCONV_TO_OVF_I1 OP_LCONV_TO_OVF_I1
1690 #define OP_PBEQ OP_LBEQ
1691 #define OP_PCEQ OP_LCEQ
1692 #define OP_PCLT OP_LCLT
1693 #define OP_PCGT OP_LCGT
1694 #define OP_PBNE_UN OP_LBNE_UN
1695 #define OP_PBGE_UN OP_LBGE_UN
1696 #define OP_PBLT_UN OP_LBLT_UN
1697 #define OP_PBGE OP_LBGE
1698 #define OP_STOREP_MEMBASE_REG OP_STOREI8_MEMBASE_REG
1699 #define OP_STOREP_MEMBASE_IMM OP_STOREI8_MEMBASE_IMM
1701 #define OP_PCONST OP_ICONST
1702 #define OP_DUMMY_PCONST OP_DUMMY_ICONST
1703 #define OP_PADD OP_IADD
1704 #define OP_PADD_IMM OP_IADD_IMM
1705 #define OP_PSUB_IMM OP_ISUB_IMM
1706 #define OP_PAND_IMM OP_IAND_IMM
1707 #define OP_PXOR_IMM OP_IXOR_IMM
1708 #define OP_PSUB OP_ISUB
1709 #define OP_PMUL OP_IMUL
1710 #define OP_PMUL_IMM OP_IMUL_IMM
1711 #define OP_PNEG OP_INEG
1712 #define OP_PCONV_TO_I1 OP_ICONV_TO_I1
1713 #define OP_PCONV_TO_U1 OP_ICONV_TO_U1
1714 #define OP_PCONV_TO_I2 OP_ICONV_TO_I2
1715 #define OP_PCONV_TO_U2 OP_ICONV_TO_U2
1716 #define OP_PCONV_TO_OVF_I1_UN OP_ICONV_TO_OVF_I1_UN
1717 #define OP_PCONV_TO_OVF_I1 OP_ICONV_TO_OVF_I1
1718 #define OP_PBEQ OP_IBEQ
1719 #define OP_PCEQ OP_ICEQ
1720 #define OP_PCLT OP_ICLT
1721 #define OP_PCGT OP_ICGT
1722 #define OP_PBNE_UN OP_IBNE_UN
1723 #define OP_PBGE_UN OP_IBGE_UN
1724 #define OP_PBLT_UN OP_IBLT_UN
1725 #define OP_PBGE OP_IBGE
1726 #define OP_STOREP_MEMBASE_REG OP_STOREI4_MEMBASE_REG
1727 #define OP_STOREP_MEMBASE_IMM OP_STOREI4_MEMBASE_IMM
1730 /* Opcodes to load/store regsize quantities */
1731 #if defined (MONO_ARCH_ILP32)
1732 #define OP_LOADR_MEMBASE OP_LOADI8_MEMBASE
1733 #define OP_STORER_MEMBASE_REG OP_STOREI8_MEMBASE_REG
1735 #define OP_LOADR_MEMBASE OP_LOAD_MEMBASE
1736 #define OP_STORER_MEMBASE_REG OP_STORE_MEMBASE_REG
1763 extern const char MONO_ARCH_CPU_SPEC
[];
1764 #define MONO_ARCH_CPU_SPEC_IDX_COMBINE(a) a ## _idx
1765 #define MONO_ARCH_CPU_SPEC_IDX(a) MONO_ARCH_CPU_SPEC_IDX_COMBINE(a)
1766 extern const guint16
MONO_ARCH_CPU_SPEC_IDX(MONO_ARCH_CPU_SPEC
) [];
1767 #define ins_get_spec(op) ((const char*)&MONO_ARCH_CPU_SPEC + MONO_ARCH_CPU_SPEC_IDX(MONO_ARCH_CPU_SPEC)[(op) - OP_LOAD])
1772 ins_get_size (int opcode
)
1774 return ((guint8
*)ins_get_spec (opcode
))[MONO_INST_LEN
];
1778 mini_realloc_code_slow (MonoCompile
*cfg
, int size
);
1780 static inline guint8
*
1781 realloc_code (MonoCompile
*cfg
, int size
)
1783 const int EXTRA_CODE_SPACE
= 16;
1784 const int code_len
= cfg
->code_len
;
1786 if (G_UNLIKELY (code_len
+ size
> (cfg
->code_size
- EXTRA_CODE_SPACE
)))
1787 return mini_realloc_code_slow (cfg
, size
);
1788 return cfg
->native_code
+ code_len
;
1792 set_code_len (MonoCompile
*cfg
, int len
)
1794 g_assert (len
<= cfg
->code_size
);
1795 cfg
->code_len
= len
;
1799 set_code_cursor (MonoCompile
*cfg
, void* void_code
)
1801 guint8
* code
= (guint8
*)void_code
;
1802 g_assert (code
<= (cfg
->native_code
+ cfg
->code_size
));
1803 set_code_len (cfg
, code
- cfg
->native_code
);
1811 MONO_COMP_DFRONTIER
= 4,
1812 MONO_COMP_DOM_REV
= 8,
1813 MONO_COMP_LIVENESS
= 16,
1815 MONO_COMP_SSA_DEF_USE
= 64,
1816 MONO_COMP_REACHABILITY
= 128,
1817 MONO_COMP_LOOPS
= 256
1822 MONO_GRAPH_DTREE
= 2,
1823 MONO_GRAPH_CFG_CODE
= 4,
1824 MONO_GRAPH_CFG_SSA
= 8,
1825 MONO_GRAPH_CFG_OPTCODE
= 16
1832 } MonoJitArgumentInfo
;
1859 /* Implicit exceptions */
1861 MONO_EXC_INDEX_OUT_OF_RANGE
,
1863 MONO_EXC_ARITHMETIC
,
1864 MONO_EXC_DIVIDE_BY_ZERO
,
1865 MONO_EXC_INVALID_CAST
,
1867 MONO_EXC_ARRAY_TYPE_MISMATCH
,
1869 MONO_EXC_INTRINS_NUM
1873 * Information about a trampoline function.
1875 struct MonoTrampInfo
1878 * The native code of the trampoline. Not owned by this structure.
1883 * The name of the trampoline which can be used in AOT/xdebug. Owned by this
1888 * Patches required by the trampoline when aot-ing. Owned by this structure.
1892 * Unwind information. Owned by this structure.
1897 * Encoded unwind info loaded from AOT images
1900 guint32 uw_info_len
;
1901 /* Whenever uw_info is owned by this structure */
1902 gboolean owns_uw_info
;
1905 typedef void (*MonoInstFunc
) (MonoInst
*tree
, gpointer data
);
1908 FILTER_IL_SEQ_POINT
= 1 << 0,
1909 FILTER_NOP
= 1 << 1,
1912 static inline gboolean
1913 mono_inst_filter (MonoInst
*ins
, int filter
)
1915 if (!ins
|| !filter
)
1918 if ((filter
& FILTER_IL_SEQ_POINT
) && ins
->opcode
== OP_IL_SEQ_POINT
)
1921 if ((filter
& FILTER_NOP
) && ins
->opcode
== OP_NOP
)
1927 static inline MonoInst
*
1928 mono_inst_next (MonoInst
*ins
, int filter
)
1932 } while (mono_inst_filter (ins
, filter
));
1937 static inline MonoInst
*
1938 mono_inst_prev (MonoInst
*ins
, int filter
)
1942 } while (mono_inst_filter (ins
, filter
));
1947 static inline MonoInst
*
1948 mono_bb_first_inst (MonoBasicBlock
*bb
, int filter
)
1950 MonoInst
*ins
= bb
->code
;
1951 if (mono_inst_filter (ins
, filter
))
1952 ins
= mono_inst_next (ins
, filter
);
1957 static inline MonoInst
*
1958 mono_bb_last_inst (MonoBasicBlock
*bb
, int filter
)
1960 MonoInst
*ins
= bb
->last_ins
;
1961 if (mono_inst_filter (ins
, filter
))
1962 ins
= mono_inst_prev (ins
, filter
);
1967 /* profiler support */
1968 void mini_add_profiler_argument (const char *desc
);
1969 void mini_profiler_emit_enter (MonoCompile
*cfg
);
1970 void mini_profiler_emit_leave (MonoCompile
*cfg
, MonoInst
*ret
);
1971 void mini_profiler_emit_tail_call (MonoCompile
*cfg
, MonoMethod
*target
);
1972 void mini_profiler_emit_call_finally (MonoCompile
*cfg
, MonoMethodHeader
*header
, unsigned char *ip
, guint32 index
, MonoExceptionClause
*clause
);
1973 void mini_profiler_context_enable (void);
1974 gpointer
mini_profiler_context_get_this (MonoProfilerCallContext
*ctx
);
1975 gpointer
mini_profiler_context_get_argument (MonoProfilerCallContext
*ctx
, guint32 pos
);
1976 gpointer
mini_profiler_context_get_local (MonoProfilerCallContext
*ctx
, guint32 pos
);
1977 gpointer
mini_profiler_context_get_result (MonoProfilerCallContext
*ctx
);
1978 void mini_profiler_context_free_buffer (gpointer buffer
);
1981 void mono_cfg_dump_create_context (MonoCompile
*cfg
);
1982 void mono_cfg_dump_begin_group (MonoCompile
*cfg
);
1983 void mono_cfg_dump_close_group (MonoCompile
*cfg
);
1984 void mono_cfg_dump_ir (MonoCompile
*cfg
, const char *phase_name
);
1986 /* helper methods */
1987 MonoInst
* mono_find_spvar_for_region (MonoCompile
*cfg
, int region
);
1988 MonoInst
* mono_find_exvar_for_offset (MonoCompile
*cfg
, int offset
);
1989 int mono_get_block_region_notry (MonoCompile
*cfg
, int region
) MONO_LLVM_INTERNAL
;
1991 void mono_bblock_add_inst (MonoBasicBlock
*bb
, MonoInst
*inst
) MONO_LLVM_INTERNAL
;
1992 void mono_bblock_insert_after_ins (MonoBasicBlock
*bb
, MonoInst
*ins
, MonoInst
*ins_to_insert
);
1993 void mono_bblock_insert_before_ins (MonoBasicBlock
*bb
, MonoInst
*ins
, MonoInst
*ins_to_insert
);
1994 void mono_verify_bblock (MonoBasicBlock
*bb
);
1995 void mono_verify_cfg (MonoCompile
*cfg
);
1996 void mono_constant_fold (MonoCompile
*cfg
);
1997 MonoInst
* mono_constant_fold_ins (MonoCompile
*cfg
, MonoInst
*ins
, MonoInst
*arg1
, MonoInst
*arg2
, gboolean overwrite
);
1998 int mono_eval_cond_branch (MonoInst
*branch
);
1999 int mono_is_power_of_two (guint32 val
) MONO_LLVM_INTERNAL
;
2000 void mono_cprop_local (MonoCompile
*cfg
, MonoBasicBlock
*bb
, MonoInst
**acp
, int acp_size
);
2001 MonoInst
* mono_compile_create_var (MonoCompile
*cfg
, MonoType
*type
, int opcode
);
2002 MonoInst
* mono_compile_create_var_for_vreg (MonoCompile
*cfg
, MonoType
*type
, int opcode
, int vreg
);
2003 void mono_compile_make_var_load (MonoCompile
*cfg
, MonoInst
*dest
, gssize var_index
);
2004 MonoInst
* mini_get_int_to_float_spill_area (MonoCompile
*cfg
);
2005 MonoType
* mono_type_from_stack_type (MonoInst
*ins
);
2006 guint32
mono_alloc_ireg (MonoCompile
*cfg
) MONO_LLVM_INTERNAL
;
2007 guint32
mono_alloc_lreg (MonoCompile
*cfg
) MONO_LLVM_INTERNAL
;
2008 guint32
mono_alloc_freg (MonoCompile
*cfg
) MONO_LLVM_INTERNAL
;
2009 guint32
mono_alloc_preg (MonoCompile
*cfg
) MONO_LLVM_INTERNAL
;
2010 guint32
mono_alloc_dreg (MonoCompile
*cfg
, MonoStackType stack_type
);
2011 guint32
mono_alloc_ireg_ref (MonoCompile
*cfg
) MONO_LLVM_INTERNAL
;
2012 guint32
mono_alloc_ireg_mp (MonoCompile
*cfg
) MONO_LLVM_INTERNAL
;
2013 guint32
mono_alloc_ireg_copy (MonoCompile
*cfg
, guint32 vreg
) MONO_LLVM_INTERNAL
;
2014 void mono_mark_vreg_as_ref (MonoCompile
*cfg
, int vreg
);
2015 void mono_mark_vreg_as_mp (MonoCompile
*cfg
, int vreg
);
2017 void mono_link_bblock (MonoCompile
*cfg
, MonoBasicBlock
*from
, MonoBasicBlock
* to
);
2018 void mono_unlink_bblock (MonoCompile
*cfg
, MonoBasicBlock
*from
, MonoBasicBlock
* to
);
2019 gboolean
mono_bblocks_linked (MonoBasicBlock
*bb1
, MonoBasicBlock
*bb2
);
2020 void mono_remove_bblock (MonoCompile
*cfg
, MonoBasicBlock
*bb
);
2021 void mono_nullify_basic_block (MonoBasicBlock
*bb
);
2022 void mono_merge_basic_blocks (MonoCompile
*cfg
, MonoBasicBlock
*bb
, MonoBasicBlock
*bbn
);
2023 void mono_optimize_branches (MonoCompile
*cfg
);
2025 void mono_blockset_print (MonoCompile
*cfg
, MonoBitSet
*set
, const char *name
, guint idom
);
2026 void mono_print_ins_index (int i
, MonoInst
*ins
);
2027 GString
*mono_print_ins_index_strbuf (int i
, MonoInst
*ins
);
2028 void mono_print_ins (MonoInst
*ins
);
2029 void mono_print_bb (MonoBasicBlock
*bb
, const char *msg
);
2030 void mono_print_code (MonoCompile
*cfg
, const char *msg
);
2031 MONO_LLVM_INTERNAL
const char* mono_inst_name (int op
);
2032 int mono_op_to_op_imm (int opcode
);
2033 int mono_op_imm_to_op (int opcode
);
2034 int mono_load_membase_to_load_mem (int opcode
);
2035 guint
mono_type_to_load_membase (MonoCompile
*cfg
, MonoType
*type
);
2036 guint
mono_type_to_store_membase (MonoCompile
*cfg
, MonoType
*type
);
2037 guint32
mono_type_to_stloc_coerce (MonoType
*type
);
2038 guint
mini_type_to_stind (MonoCompile
* cfg
, MonoType
*type
);
2039 MonoJitInfo
* mini_lookup_method (MonoDomain
*domain
, MonoMethod
*method
, MonoMethod
*shared
);
2040 guint32
mono_reverse_branch_op (guint32 opcode
);
2041 void mono_disassemble_code (MonoCompile
*cfg
, guint8
*code
, int size
, char *id
);
2042 void mono_add_patch_info (MonoCompile
*cfg
, int ip
, MonoJumpInfoType type
, gconstpointer target
) MONO_LLVM_INTERNAL
;
2043 void mono_add_patch_info_rel (MonoCompile
*cfg
, int ip
, MonoJumpInfoType type
, gconstpointer target
, int relocation
) MONO_LLVM_INTERNAL
;
2044 void mono_remove_patch_info (MonoCompile
*cfg
, int ip
);
2045 gpointer
mono_jit_compile_method_inner (MonoMethod
*method
, MonoDomain
*target_domain
, int opt
, MonoError
*error
);
2046 GList
*mono_varlist_insert_sorted (MonoCompile
*cfg
, GList
*list
, MonoMethodVar
*mv
, int sort_type
);
2047 GList
*mono_varlist_sort (MonoCompile
*cfg
, GList
*list
, int sort_type
);
2048 void mono_analyze_liveness (MonoCompile
*cfg
);
2049 void mono_analyze_liveness_gc (MonoCompile
*cfg
);
2050 void mono_linear_scan (MonoCompile
*cfg
, GList
*vars
, GList
*regs
, regmask_t
*used_mask
);
2051 void mono_global_regalloc (MonoCompile
*cfg
);
2052 void mono_create_jump_table (MonoCompile
*cfg
, MonoInst
*label
, MonoBasicBlock
**bbs
, int num_blocks
);
2053 MonoCompile
*mini_method_compile (MonoMethod
*method
, guint32 opts
, MonoDomain
*domain
, JitFlags flags
, int parts
, int aot_method_index
);
2054 void mono_destroy_compile (MonoCompile
*cfg
);
2055 void mono_empty_compile (MonoCompile
*cfg
);
2056 MonoJitICallInfo
*mono_find_jit_opcode_emulation (int opcode
);
2057 void mono_print_ins_index (int i
, MonoInst
*ins
);
2058 void mono_print_ins (MonoInst
*ins
);
2059 gboolean
mini_assembly_can_skip_verification (MonoDomain
*domain
, MonoMethod
*method
);
2060 gboolean
mono_compile_is_broken (MonoCompile
*cfg
, MonoMethod
*method
, gboolean fail_compile
);
2061 MonoInst
*mono_get_got_var (MonoCompile
*cfg
);
2062 void mono_add_seq_point (MonoCompile
*cfg
, MonoBasicBlock
*bb
, MonoInst
*ins
, int native_offset
);
2063 void mono_add_var_location (MonoCompile
*cfg
, MonoInst
*var
, gboolean is_reg
, int reg
, int offset
, int from
, int to
);
2064 MonoInst
* mono_emit_jit_icall (MonoCompile
*cfg
, gconstpointer func
, MonoInst
**args
);
2067 template <typename T
>
2069 mono_emit_jit_icall (MonoCompile
*cfg
, T func
, MonoInst
**args
)
2071 return mono_emit_jit_icall (cfg
, (gconstpointer
)func
, args
);
2073 #endif // __cplusplus
2075 MonoInst
* mono_emit_jit_icall_by_info (MonoCompile
*cfg
, int il_offset
, MonoJitICallInfo
*info
, MonoInst
**args
);
2076 MonoInst
* mono_emit_method_call (MonoCompile
*cfg
, MonoMethod
*method
, MonoInst
**args
, MonoInst
*this_ins
);
2077 MonoInst
* mono_emit_native_call (MonoCompile
*cfg
, gconstpointer func
, MonoMethodSignature
*sig
, MonoInst
**args
);
2078 gboolean
mini_should_insert_breakpoint (MonoMethod
*method
);
2079 int mono_target_pagesize (void);
2081 gboolean
mini_class_is_system_array (MonoClass
*klass
);
2083 void mono_linterval_add_range (MonoCompile
*cfg
, MonoLiveInterval
*interval
, int from
, int to
);
2084 void mono_linterval_print (MonoLiveInterval
*interval
);
2085 void mono_linterval_print_nl (MonoLiveInterval
*interval
);
2086 gboolean
mono_linterval_covers (MonoLiveInterval
*interval
, int pos
);
2087 gint32
mono_linterval_get_intersect_pos (MonoLiveInterval
*i1
, MonoLiveInterval
*i2
);
2088 void mono_linterval_split (MonoCompile
*cfg
, MonoLiveInterval
*interval
, MonoLiveInterval
**i1
, MonoLiveInterval
**i2
, int pos
);
2089 void mono_liveness_handle_exception_clauses (MonoCompile
*cfg
);
2091 gpointer
mono_realloc_native_code (MonoCompile
*cfg
);
2093 void mono_xdebug_init (const char *xdebug_opts
);
2094 void mono_save_xdebug_info (MonoCompile
*cfg
);
2095 void mono_save_trampoline_xdebug_info (MonoTrampInfo
*info
);
2096 /* This is an exported function */
2097 void mono_xdebug_flush (void);
2099 void mono_register_opcode_emulation (int opcode
, const char* name
, MonoMethodSignature
*sig
, gpointer func
, gboolean no_throw
);
2100 void mono_draw_graph (MonoCompile
*cfg
, MonoGraphOptions draw_options
);
2101 void mono_add_ins_to_end (MonoBasicBlock
*bb
, MonoInst
*inst
);
2103 void mono_replace_ins (MonoCompile
*cfg
, MonoBasicBlock
*bb
, MonoInst
*ins
, MonoInst
**prev
, MonoBasicBlock
*first_bb
, MonoBasicBlock
*last_bb
);
2105 void mini_register_opcode_emulation (int opcode
, const char *name
, MonoMethodSignature
*sig
, gpointer func
, const char *symbol
, gboolean no_throw
);
2108 template <typename T
>
2110 mini_register_opcode_emulation (int opcode
, const char *name
, MonoMethodSignature
*sig
, T func
, const char *symbol
, gboolean no_throw
)
2112 mini_register_opcode_emulation (opcode
, name
, sig
, (gpointer
)func
, symbol
, no_throw
);
2114 #endif // __cplusplus
2116 void mono_trampolines_init (void);
2117 void mono_trampolines_cleanup (void);
2118 guint8
* mono_get_trampoline_code (MonoTrampolineType tramp_type
);
2119 gpointer
mono_create_specific_trampoline (gpointer arg1
, MonoTrampolineType tramp_type
, MonoDomain
*domain
, guint32
*code_len
);
2120 gpointer
mono_create_jump_trampoline (MonoDomain
*domain
,
2122 gboolean add_sync_wrapper
,
2124 gpointer
mono_create_class_init_trampoline (MonoVTable
*vtable
);
2125 gpointer
mono_create_jit_trampoline (MonoDomain
*domain
, MonoMethod
*method
, MonoError
*error
) MONO_LLVM_INTERNAL
;
2126 gpointer
mono_create_jit_trampoline_from_token (MonoImage
*image
, guint32 token
);
2127 gpointer
mono_create_delegate_trampoline (MonoDomain
*domain
, MonoClass
*klass
);
2128 MonoDelegateTrampInfo
* mono_create_delegate_trampoline_info (MonoDomain
*domain
, MonoClass
*klass
, MonoMethod
*method
);
2129 gpointer
mono_create_delegate_virtual_trampoline (MonoDomain
*domain
, MonoClass
*klass
, MonoMethod
*method
);
2130 gpointer
mono_create_rgctx_lazy_fetch_trampoline (guint32 offset
);
2131 gpointer
mono_create_monitor_enter_trampoline (void);
2132 gpointer
mono_create_monitor_enter_v4_trampoline (void);
2133 gpointer
mono_create_monitor_exit_trampoline (void);
2134 gpointer
mono_create_static_rgctx_trampoline (MonoMethod
*m
, gpointer addr
);
2135 gpointer
mono_create_ftnptr_arg_trampoline (gpointer arg
, gpointer addr
);
2136 MonoVTable
* mono_find_class_init_trampoline_by_addr (gconstpointer addr
);
2137 guint32
mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr
);
2138 gpointer
mono_magic_trampoline (host_mgreg_t
*regs
, guint8
*code
, gpointer arg
, guint8
* tramp
);
2139 #ifndef DISABLE_REMOTING
2140 gpointer
mono_generic_virtual_remoting_trampoline (host_mgreg_t
*regs
, guint8
*code
, MonoMethod
*m
, guint8
*tramp
);
2142 gpointer
mono_delegate_trampoline (host_mgreg_t
*regs
, guint8
*code
, gpointer
*tramp_data
, guint8
* tramp
);
2143 gpointer
mono_aot_trampoline (host_mgreg_t
*regs
, guint8
*code
, guint8
*token_info
,
2145 gpointer
mono_aot_plt_trampoline (host_mgreg_t
*regs
, guint8
*code
, guint8
*token_info
,
2147 void mono_class_init_trampoline (host_mgreg_t
*regs
, guint8
*code
, MonoVTable
*vtable
, guint8
*tramp
);
2148 void mono_generic_class_init_trampoline (host_mgreg_t
*regs
, guint8
*code
, MonoVTable
*vtable
, guint8
*tramp
);
2149 void mono_monitor_enter_trampoline (host_mgreg_t
*regs
, guint8
*code
, MonoObject
*obj
, guint8
*tramp
);
2150 void mono_monitor_enter_v4_trampoline (host_mgreg_t
*regs
, guint8
*code
, MonoObject
*obj
, guint8
*tramp
);
2151 void mono_monitor_exit_trampoline (host_mgreg_t
*regs
, guint8
*code
, MonoObject
*obj
, guint8
*tramp
);
2152 gconstpointer
mono_get_trampoline_func (MonoTrampolineType tramp_type
);
2153 gpointer
mini_get_vtable_trampoline (MonoVTable
*vt
, int slot_index
);
2154 const char* mono_get_generic_trampoline_simple_name (MonoTrampolineType tramp_type
);
2155 char* mono_get_generic_trampoline_name (MonoTrampolineType tramp_type
);
2156 char* mono_get_rgctx_fetch_trampoline_name (int slot
);
2157 gpointer
mini_get_nullified_class_init_trampoline (void);
2158 gpointer
mini_get_single_step_trampoline (void);
2159 gpointer
mini_get_breakpoint_trampoline (void);
2160 gpointer
mini_add_method_trampoline (MonoMethod
*m
, gpointer compiled_method
, gboolean add_static_rgctx_tramp
, gboolean add_unbox_tramp
);
2161 gboolean
mini_jit_info_is_gsharedvt (MonoJitInfo
*ji
);
2162 gpointer
* mini_resolve_imt_method (MonoVTable
*vt
, gpointer
*vtable_slot
, MonoMethod
*imt_method
, MonoMethod
**impl_method
, gpointer
*out_aot_addr
,
2163 gboolean
*out_need_rgctx_tramp
, MonoMethod
**variant_iface
,
2166 void* mono_global_codeman_reserve (int size
);
2168 #define mono_global_codeman_reserve(size) (g_cast (mono_global_codeman_reserve ((size))))
2170 void mono_global_codeman_foreach (MonoCodeManagerFunc func
, void *user_data
);
2171 const char *mono_regname_full (int reg
, int bank
);
2172 gint32
* mono_allocate_stack_slots (MonoCompile
*cfg
, gboolean backward
, guint32
*stack_size
, guint32
*stack_align
);
2173 void mono_local_regalloc (MonoCompile
*cfg
, MonoBasicBlock
*bb
);
2174 MonoInst
*mono_branch_optimize_exception_target (MonoCompile
*cfg
, MonoBasicBlock
*bb
, const char * exname
);
2175 void mono_remove_critical_edges (MonoCompile
*cfg
);
2176 gboolean
mono_is_regsize_var (MonoType
*t
);
2177 MonoJumpInfo
* mono_patch_info_new (MonoMemPool
*mp
, int ip
, MonoJumpInfoType type
, gconstpointer target
);
2178 int mini_class_check_context_used (MonoCompile
*cfg
, MonoClass
*klass
);
2179 int mini_method_check_context_used (MonoCompile
*cfg
, MonoMethod
*method
);
2180 void mini_type_from_op (MonoCompile
*cfg
, MonoInst
*ins
, MonoInst
*src1
, MonoInst
*src2
);
2181 void mini_set_inline_failure (MonoCompile
*cfg
, const char *msg
);
2182 void mini_test_tailcall (MonoCompile
*cfg
, gboolean tailcall
);
2183 gboolean
mini_should_check_stack_pointer (MonoCompile
*cfg
);
2184 MonoInst
* mini_emit_box (MonoCompile
*cfg
, MonoInst
*val
, MonoClass
*klass
, int context_used
);
2185 void mini_emit_memcpy (MonoCompile
*cfg
, int destreg
, int doffset
, int srcreg
, int soffset
, int size
, int align
);
2186 void mini_emit_memset (MonoCompile
*cfg
, int destreg
, int offset
, int size
, int val
, int align
);
2187 void mini_emit_stobj (MonoCompile
*cfg
, MonoInst
*dest
, MonoInst
*src
, MonoClass
*klass
, gboolean native
);
2188 void mini_emit_initobj (MonoCompile
*cfg
, MonoInst
*dest
, const guchar
*ip
, MonoClass
*klass
);
2189 int mini_emit_sext_index_reg (MonoCompile
*cfg
, MonoInst
*index
);
2190 MonoInst
* mini_emit_ldelema_1_ins (MonoCompile
*cfg
, MonoClass
*klass
, MonoInst
*arr
, MonoInst
*index
, gboolean bcheck
);
2191 MonoInst
* mini_emit_get_gsharedvt_info_klass (MonoCompile
*cfg
, MonoClass
*klass
, MonoRgctxInfoType rgctx_type
);
2192 MonoInst
* mini_emit_get_rgctx_method (MonoCompile
*cfg
, int context_used
,
2193 MonoMethod
*cmethod
, MonoRgctxInfoType rgctx_type
);
2194 void mini_emit_tailcall_parameters (MonoCompile
*cfg
, MonoMethodSignature
*sig
);
2195 MonoCallInst
* mini_emit_call_args (MonoCompile
*cfg
, MonoMethodSignature
*sig
,
2196 MonoInst
**args
, gboolean calli
, gboolean virtual_
, gboolean tailcall
,
2197 gboolean rgctx
, gboolean unbox_trampoline
, MonoMethod
*target
);
2198 MonoInst
* mini_emit_calli (MonoCompile
*cfg
, MonoMethodSignature
*sig
, MonoInst
**args
, MonoInst
*addr
, MonoInst
*imt_arg
, MonoInst
*rgctx_arg
);
2199 MonoInst
* mini_emit_calli_full (MonoCompile
*cfg
, MonoMethodSignature
*sig
, MonoInst
**args
, MonoInst
*addr
,
2200 MonoInst
*imt_arg
, MonoInst
*rgctx_arg
, gboolean tailcall
);
2201 MonoInst
* mini_emit_method_call_full (MonoCompile
*cfg
, MonoMethod
*method
, MonoMethodSignature
*sig
, gboolean tailcall
,
2202 MonoInst
**args
, MonoInst
*this_ins
, MonoInst
*imt_arg
, MonoInst
*rgctx_arg
);
2203 MonoInst
* mini_emit_abs_call (MonoCompile
*cfg
, MonoJumpInfoType patch_type
, gconstpointer data
,
2204 MonoMethodSignature
*sig
, MonoInst
**args
);
2205 MonoInst
* mini_emit_extra_arg_calli (MonoCompile
*cfg
, MonoMethodSignature
*fsig
, MonoInst
**orig_args
, int arg_reg
, MonoInst
*call_target
);
2206 MonoInst
* mini_emit_llvmonly_calli (MonoCompile
*cfg
, MonoMethodSignature
*fsig
, MonoInst
**args
, MonoInst
*addr
);
2207 MonoInst
* mini_emit_llvmonly_virtual_call (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, int context_used
, MonoInst
**sp
);
2208 MonoInst
* mini_emit_memory_barrier (MonoCompile
*cfg
, int kind
);
2209 void mini_emit_write_barrier (MonoCompile
*cfg
, MonoInst
*ptr
, MonoInst
*value
);
2210 MonoInst
* mini_emit_memory_load (MonoCompile
*cfg
, MonoType
*type
, MonoInst
*src
, int offset
, int ins_flag
);
2211 void mini_emit_memory_store (MonoCompile
*cfg
, MonoType
*type
, MonoInst
*dest
, MonoInst
*value
, int ins_flag
);
2212 void mini_emit_memory_copy_bytes (MonoCompile
*cfg
, MonoInst
*dest
, MonoInst
*src
, MonoInst
*size
, int ins_flag
);
2213 void mini_emit_memory_init_bytes (MonoCompile
*cfg
, MonoInst
*dest
, MonoInst
*value
, MonoInst
*size
, int ins_flag
);
2214 void mini_emit_memory_copy (MonoCompile
*cfg
, MonoInst
*dest
, MonoInst
*src
, MonoClass
*klass
, gboolean native
, int ins_flag
);
2215 MonoInst
* mini_emit_array_store (MonoCompile
*cfg
, MonoClass
*klass
, MonoInst
**sp
, gboolean safety_checks
);
2216 MonoInst
* mini_emit_inst_for_method (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**args
);
2217 MonoInst
* mini_emit_inst_for_ctor (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**args
);
2218 MonoInst
* mini_emit_inst_for_sharable_method (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**args
);
2219 MonoInst
* mini_emit_inst_for_field_load (MonoCompile
*cfg
, MonoClassField
*field
);
2220 MonoInst
* mini_handle_enum_has_flag (MonoCompile
*cfg
, MonoClass
*klass
, MonoInst
*enum_this
, int enum_val_reg
, MonoInst
*enum_flag
);
2222 MonoMethod
* mini_get_memcpy_method (void);
2223 MonoMethod
* mini_get_memset_method (void);
2224 int mini_class_check_context_used (MonoCompile
*cfg
, MonoClass
*klass
);
2226 CompRelation
mono_opcode_to_cond (int opcode
) MONO_LLVM_INTERNAL
;
2227 CompType
mono_opcode_to_type (int opcode
, int cmp_opcode
);
2228 CompRelation
mono_negate_cond (CompRelation cond
);
2229 int mono_op_imm_to_op (int opcode
);
2230 void mono_decompose_op_imm (MonoCompile
*cfg
, MonoBasicBlock
*bb
, MonoInst
*ins
);
2231 void mono_peephole_ins (MonoBasicBlock
*bb
, MonoInst
*ins
);
2232 MonoUnwindOp
*mono_create_unwind_op (int when
,
2235 void mono_emit_unwind_op (MonoCompile
*cfg
, int when
,
2238 MonoTrampInfo
* mono_tramp_info_create (const char *name
, guint8
*code
, guint32 code_size
, MonoJumpInfo
*ji
, GSList
*unwind_ops
);
2239 void mono_tramp_info_free (MonoTrampInfo
*info
);
2240 void mono_aot_tramp_info_register (MonoTrampInfo
*info
, MonoDomain
*domain
);
2241 void mono_tramp_info_register (MonoTrampInfo
*info
, MonoDomain
*domain
);
2242 int mini_exception_id_by_name (const char *name
);
2243 gboolean
mini_type_is_hfa (MonoType
*t
, int *out_nfields
, int *out_esize
) MONO_LLVM_INTERNAL
;
2245 int mono_method_to_ir (MonoCompile
*cfg
, MonoMethod
*method
, MonoBasicBlock
*start_bblock
, MonoBasicBlock
*end_bblock
,
2246 MonoInst
*return_var
, MonoInst
**inline_args
,
2247 guint inline_offset
, gboolean is_virtual_call
);
2249 //the following methods could just be renamed/moved from method-to-ir.c
2250 int mini_inline_method (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**sp
, guchar
*ip
,
2251 guint real_offset
, gboolean inline_always
);
2253 MonoInst
* mini_emit_get_rgctx_klass (MonoCompile
*cfg
, int context_used
, MonoClass
*klass
, MonoRgctxInfoType rgctx_type
);
2254 MonoInst
* mini_emit_runtime_constant (MonoCompile
*cfg
, MonoJumpInfoType patch_type
, gpointer data
);
2255 void mini_save_cast_details (MonoCompile
*cfg
, MonoClass
*klass
, int obj_reg
, gboolean null_check
);
2256 void mini_reset_cast_details (MonoCompile
*cfg
);
2257 void mini_emit_class_check (MonoCompile
*cfg
, int klass_reg
, MonoClass
*klass
);
2259 gboolean
mini_class_has_reference_variant_generic_argument (MonoCompile
*cfg
, MonoClass
*klass
, int context_used
);
2261 MonoInst
*mono_decompose_opcode (MonoCompile
*cfg
, MonoInst
*ins
);
2262 void mono_decompose_long_opts (MonoCompile
*cfg
);
2263 void mono_decompose_vtype_opts (MonoCompile
*cfg
);
2264 void mono_decompose_array_access_opts (MonoCompile
*cfg
);
2265 void mono_decompose_soft_float (MonoCompile
*cfg
);
2266 void mono_local_emulate_ops (MonoCompile
*cfg
);
2267 void mono_handle_global_vregs (MonoCompile
*cfg
);
2268 void mono_spill_global_vars (MonoCompile
*cfg
, gboolean
*need_local_opts
);
2269 void mono_allocate_gsharedvt_vars (MonoCompile
*cfg
);
2270 void mono_if_conversion (MonoCompile
*cfg
);
2273 char* mono_get_delegate_virtual_invoke_impl_name (gboolean load_imt_reg
, int offset
);
2274 gpointer
mono_get_delegate_virtual_invoke_impl (MonoMethodSignature
*sig
, MonoMethod
*method
);
2276 void mono_codegen (MonoCompile
*cfg
);
2277 void mono_call_inst_add_outarg_reg (MonoCompile
*cfg
, MonoCallInst
*call
, int vreg
, int hreg
, int bank
) MONO_LLVM_INTERNAL
;
2278 void mono_call_inst_add_outarg_vt (MonoCompile
*cfg
, MonoCallInst
*call
, MonoInst
*outarg_vt
);
2280 /* methods that must be provided by the arch-specific port */
2281 void mono_arch_init (void);
2282 void mono_arch_finish_init (void);
2283 void mono_arch_cleanup (void);
2284 void mono_arch_cpu_init (void);
2285 guint32
mono_arch_cpu_optimizations (guint32
*exclude_mask
);
2286 const char *mono_arch_regname (int reg
);
2287 const char *mono_arch_fregname (int reg
);
2288 void mono_arch_exceptions_init (void);
2289 guchar
* mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type
, MonoTrampInfo
**info
, gboolean aot
);
2290 gpointer
mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot
, MonoTrampInfo
**info
, gboolean aot
);
2291 gpointer
mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo
**info
, gboolean aot
);
2292 gpointer
mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo
**info
);
2293 guint8
* mono_arch_create_sdb_trampoline (gboolean single_step
, MonoTrampInfo
**info
, gboolean aot
);
2294 gpointer
mono_arch_create_monitor_enter_trampoline (MonoTrampInfo
**info
, gboolean is_v4
, gboolean aot
);
2295 gpointer
mono_arch_create_monitor_exit_trampoline (MonoTrampInfo
**info
, gboolean aot
);
2296 guint8
*mono_arch_create_llvm_native_thunk (MonoDomain
*domain
, guint8
* addr
) MONO_LLVM_INTERNAL
;
2297 gpointer
mono_arch_get_get_tls_tramp (void);
2298 GList
*mono_arch_get_allocatable_int_vars (MonoCompile
*cfg
);
2299 GList
*mono_arch_get_global_int_regs (MonoCompile
*cfg
);
2300 guint32
mono_arch_regalloc_cost (MonoCompile
*cfg
, MonoMethodVar
*vmv
);
2301 void mono_arch_patch_code (MonoCompile
*cfg
, MonoMethod
*method
, MonoDomain
*domain
, guint8
*code
, MonoJumpInfo
*ji
, gboolean run_cctors
, MonoError
*error
);
2302 void mono_arch_patch_code_new (MonoCompile
*cfg
, MonoDomain
*domain
, guint8
*code
, MonoJumpInfo
*ji
, gpointer target
);
2303 void mono_arch_flush_icache (guint8
*code
, gint size
);
2304 guint8
*mono_arch_emit_prolog (MonoCompile
*cfg
);
2305 void mono_arch_emit_epilog (MonoCompile
*cfg
);
2306 void mono_arch_emit_exceptions (MonoCompile
*cfg
);
2307 void mono_arch_lowering_pass (MonoCompile
*cfg
, MonoBasicBlock
*bb
);
2308 void mono_arch_peephole_pass_1 (MonoCompile
*cfg
, MonoBasicBlock
*bb
);
2309 void mono_arch_peephole_pass_2 (MonoCompile
*cfg
, MonoBasicBlock
*bb
);
2310 void mono_arch_output_basic_block (MonoCompile
*cfg
, MonoBasicBlock
*bb
);
2311 void mono_arch_free_jit_tls_data (MonoJitTlsData
*tls
);
2312 void mono_arch_fill_argument_info (MonoCompile
*cfg
);
2313 void mono_arch_allocate_vars (MonoCompile
*m
);
2314 int mono_arch_get_argument_info (MonoMethodSignature
*csig
, int param_count
, MonoJitArgumentInfo
*arg_info
);
2315 void mono_arch_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
);
2316 void mono_arch_emit_outarg_vt (MonoCompile
*cfg
, MonoInst
*ins
, MonoInst
*src
);
2317 void mono_arch_emit_setret (MonoCompile
*cfg
, MonoMethod
*method
, MonoInst
*val
);
2318 MonoDynCallInfo
*mono_arch_dyn_call_prepare (MonoMethodSignature
*sig
);
2319 void mono_arch_dyn_call_free (MonoDynCallInfo
*info
);
2320 int mono_arch_dyn_call_get_buf_size (MonoDynCallInfo
*info
);
2321 void mono_arch_start_dyn_call (MonoDynCallInfo
*info
, gpointer
**args
, guint8
*ret
, guint8
*buf
);
2322 void mono_arch_finish_dyn_call (MonoDynCallInfo
*info
, guint8
*buf
);
2323 MonoInst
*mono_arch_emit_inst_for_method (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**args
);
2324 void mono_arch_decompose_opts (MonoCompile
*cfg
, MonoInst
*ins
);
2325 void mono_arch_decompose_long_opts (MonoCompile
*cfg
, MonoInst
*ins
);
2326 GSList
* mono_arch_get_delegate_invoke_impls (void);
2327 LLVMCallInfo
* mono_arch_get_llvm_call_info (MonoCompile
*cfg
, MonoMethodSignature
*sig
) MONO_LLVM_INTERNAL
;
2328 guint8
* mono_arch_emit_load_got_addr (guint8
*start
, guint8
*code
, MonoCompile
*cfg
, MonoJumpInfo
**ji
);
2329 guint8
* mono_arch_emit_load_aotconst (guint8
*start
, guint8
*code
, MonoJumpInfo
**ji
, MonoJumpInfoType tramp_type
, gconstpointer target
);
2330 GSList
* mono_arch_get_cie_program (void);
2331 void mono_arch_set_target (char *mtriple
);
2332 gboolean
mono_arch_gsharedvt_sig_supported (MonoMethodSignature
*sig
);
2333 gpointer
mono_arch_get_gsharedvt_trampoline (MonoTrampInfo
**info
, gboolean aot
);
2334 gpointer
mono_arch_get_gsharedvt_call_info (gpointer addr
, MonoMethodSignature
*normal_sig
, MonoMethodSignature
*gsharedvt_sig
, gboolean gsharedvt_in
, gint32 vcall_offset
, gboolean calli
);
2335 gboolean
mono_arch_opcode_needs_emulation (MonoCompile
*cfg
, int opcode
);
2336 gboolean
mono_arch_tailcall_supported (MonoCompile
*cfg
, MonoMethodSignature
*caller_sig
, MonoMethodSignature
*callee_sig
, gboolean virtual_
);
2337 int mono_arch_translate_tls_offset (int offset
);
2338 gboolean
mono_arch_opcode_supported (int opcode
);
2339 void mono_arch_setup_resume_sighandler_ctx (MonoContext
*ctx
, gpointer func
);
2340 gboolean
mono_arch_have_fast_tls (void);
2342 #ifdef MONO_ARCH_HAS_REGISTER_ICALL
2343 void mono_arch_register_icall (void);
2346 #ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
2347 gboolean
mono_arch_is_soft_float (void);
2349 static inline MONO_ALWAYS_INLINE gboolean
2350 mono_arch_is_soft_float (void)
2356 /* Soft Debug support */
2357 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
2358 void mono_arch_set_breakpoint (MonoJitInfo
*ji
, guint8
*ip
);
2359 void mono_arch_clear_breakpoint (MonoJitInfo
*ji
, guint8
*ip
);
2360 void mono_arch_start_single_stepping (void);
2361 void mono_arch_stop_single_stepping (void);
2362 gboolean
mono_arch_is_single_step_event (void *info
, void *sigctx
);
2363 gboolean
mono_arch_is_breakpoint_event (void *info
, void *sigctx
);
2364 void mono_arch_skip_breakpoint (MonoContext
*ctx
, MonoJitInfo
*ji
);
2365 void mono_arch_skip_single_step (MonoContext
*ctx
);
2366 SeqPointInfo
*mono_arch_get_seq_point_info (MonoDomain
*domain
, guint8
*code
);
2370 mono_arch_unwind_frame (MonoDomain
*domain
, MonoJitTlsData
*jit_tls
,
2371 MonoJitInfo
*ji
, MonoContext
*ctx
,
2372 MonoContext
*new_ctx
, MonoLMF
**lmf
,
2373 host_mgreg_t
**save_locations
,
2374 StackFrameInfo
*frame_info
);
2375 gpointer
mono_arch_get_throw_exception_by_name (void);
2376 gpointer
mono_arch_get_call_filter (MonoTrampInfo
**info
, gboolean aot
);
2377 gpointer
mono_arch_get_restore_context (MonoTrampInfo
**info
, gboolean aot
);
2378 gpointer
mono_arch_get_throw_exception (MonoTrampInfo
**info
, gboolean aot
);
2379 gpointer
mono_arch_get_rethrow_exception (MonoTrampInfo
**info
, gboolean aot
);
2380 gpointer
mono_arch_get_rethrow_preserve_exception (MonoTrampInfo
**info
, gboolean aot
);
2381 gpointer
mono_arch_get_throw_corlib_exception (MonoTrampInfo
**info
, gboolean aot
);
2382 gpointer
mono_arch_get_throw_pending_exception (MonoTrampInfo
**info
, gboolean aot
);
2383 gboolean
mono_arch_handle_exception (void *sigctx
, gpointer obj
);
2384 void mono_arch_handle_altstack_exception (void *sigctx
, MONO_SIG_HANDLER_INFO_TYPE
*siginfo
, gpointer fault_addr
, gboolean stack_ovf
);
2385 gboolean
mono_handle_soft_stack_ovf (MonoJitTlsData
*jit_tls
, MonoJitInfo
*ji
, void *ctx
, MONO_SIG_HANDLER_INFO_TYPE
*siginfo
, guint8
* fault_addr
);
2386 void mono_handle_hard_stack_ovf (MonoJitTlsData
*jit_tls
, MonoJitInfo
*ji
, MonoContext
*mctx
, guint8
* fault_addr
);
2387 void mono_arch_undo_ip_adjustment (MonoContext
*ctx
);
2388 void mono_arch_do_ip_adjustment (MonoContext
*ctx
);
2389 gpointer
mono_arch_ip_from_context (void *sigctx
);
2390 host_mgreg_t
mono_arch_context_get_int_reg (MonoContext
*ctx
, int reg
);
2391 void mono_arch_context_set_int_reg (MonoContext
*ctx
, int reg
, host_mgreg_t val
);
2392 void mono_arch_flush_register_windows (void);
2393 gboolean
mono_arch_is_inst_imm (int opcode
, int imm_opcode
, gint64 imm
);
2394 gboolean
mono_arch_is_int_overflow (void *sigctx
, void *info
);
2395 void mono_arch_invalidate_method (MonoJitInfo
*ji
, void *func
, gpointer func_arg
);
2396 guint32
mono_arch_get_patch_offset (guint8
*code
);
2397 gpointer
*mono_arch_get_delegate_method_ptr_addr (guint8
* code
, host_mgreg_t
*regs
);
2398 void mono_arch_create_vars (MonoCompile
*cfg
) MONO_LLVM_INTERNAL
;
2399 void mono_arch_save_unwind_info (MonoCompile
*cfg
);
2400 void mono_arch_register_lowlevel_calls (void);
2401 gpointer
mono_arch_get_unbox_trampoline (MonoMethod
*m
, gpointer addr
);
2402 gpointer
mono_arch_get_static_rgctx_trampoline (gpointer arg
, gpointer addr
);
2403 gpointer
mono_arch_get_ftnptr_arg_trampoline (gpointer arg
, gpointer addr
);
2404 gpointer
mono_arch_get_llvm_imt_trampoline (MonoDomain
*domain
, MonoMethod
*method
, int vt_offset
);
2405 gpointer
mono_arch_get_gsharedvt_arg_trampoline (MonoDomain
*domain
, gpointer arg
, gpointer addr
);
2406 void mono_arch_patch_callsite (guint8
*method_start
, guint8
*code
, guint8
*addr
);
2407 void mono_arch_patch_plt_entry (guint8
*code
, gpointer
*got
, host_mgreg_t
*regs
, guint8
*addr
);
2408 void mono_arch_nullify_class_init_trampoline(guint8
*code
, host_mgreg_t
*regs
);
2409 int mono_arch_get_this_arg_reg (guint8
*code
);
2410 gpointer
mono_arch_get_this_arg_from_call (host_mgreg_t
*regs
, guint8
*code
);
2411 gpointer
mono_arch_get_delegate_invoke_impl (MonoMethodSignature
*sig
, gboolean has_target
);
2412 gpointer
mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature
*sig
, MonoMethod
*method
, int offset
, gboolean load_imt_reg
);
2413 gpointer
mono_arch_create_specific_trampoline (gpointer arg1
, MonoTrampolineType tramp_type
, MonoDomain
*domain
, guint32
*code_len
);
2414 MonoMethod
* mono_arch_find_imt_method (host_mgreg_t
*regs
, guint8
*code
);
2415 MonoVTable
* mono_arch_find_static_call_vtable (host_mgreg_t
*regs
, guint8
*code
);
2416 gpointer
mono_arch_build_imt_trampoline (MonoVTable
*vtable
, MonoDomain
*domain
, MonoIMTCheckItem
**imt_entries
, int count
, gpointer fail_tramp
);
2417 void mono_arch_notify_pending_exc (MonoThreadInfo
*info
);
2418 guint8
* mono_arch_get_call_target (guint8
*code
);
2419 guint32
mono_arch_get_plt_info_offset (guint8
*plt_entry
, host_mgreg_t
*regs
, guint8
*code
);
2420 GSList
*mono_arch_get_trampolines (gboolean aot
);
2421 gpointer
mono_arch_get_interp_to_native_trampoline (MonoTrampInfo
**info
);
2422 gpointer
mono_arch_get_native_to_interp_trampoline (MonoTrampInfo
**info
);
2424 #ifdef MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP
2425 void mono_arch_set_native_call_context_args (CallContext
*ccontext
, gpointer frame
, MonoMethodSignature
*sig
);
2426 void mono_arch_set_native_call_context_ret (CallContext
*ccontext
, gpointer frame
, MonoMethodSignature
*sig
);
2427 void mono_arch_get_native_call_context_args (CallContext
*ccontext
, gpointer frame
, MonoMethodSignature
*sig
);
2428 void mono_arch_get_native_call_context_ret (CallContext
*ccontext
, gpointer frame
, MonoMethodSignature
*sig
);
2431 /*New interruption machinery */
2433 mono_setup_async_callback (MonoContext
*ctx
, void (*async_cb
)(void *fun
), gpointer user_data
);
2436 mono_arch_setup_async_callback (MonoContext
*ctx
, void (*async_cb
)(void *fun
), gpointer user_data
);
2439 mono_thread_state_init_from_handle (MonoThreadUnwindState
*tctx
, MonoThreadInfo
*info
, /*optional*/ void *sigctx
);
2442 /* Exception handling */
2443 typedef gboolean (*MonoJitStackWalk
) (StackFrameInfo
*frame
, MonoContext
*ctx
, gpointer data
);
2445 void mono_exceptions_init (void);
2446 gboolean
mono_handle_exception (MonoContext
*ctx
, gpointer obj
);
2447 void mono_handle_native_crash (const char *signal
, MonoContext
*mctx
, MONO_SIG_HANDLER_INFO_TYPE
*siginfo
);
2448 MONO_API
void mono_print_thread_dump (void *sigctx
);
2449 MONO_API
void mono_print_thread_dump_from_ctx (MonoContext
*ctx
);
2450 void mono_walk_stack_with_ctx (MonoJitStackWalk func
, MonoContext
*start_ctx
, MonoUnwindOptions unwind_options
, void *user_data
);
2451 void mono_walk_stack_with_state (MonoJitStackWalk func
, MonoThreadUnwindState
*state
, MonoUnwindOptions unwind_options
, void *user_data
);
2452 void mono_walk_stack (MonoJitStackWalk func
, MonoUnwindOptions options
, void *user_data
);
2453 gboolean
mono_thread_state_init_from_sigctx (MonoThreadUnwindState
*ctx
, void *sigctx
);
2454 void mono_thread_state_init (MonoThreadUnwindState
*ctx
);
2455 gboolean
mono_thread_state_init_from_current (MonoThreadUnwindState
*ctx
);
2456 gboolean
mono_thread_state_init_from_monoctx (MonoThreadUnwindState
*ctx
, MonoContext
*mctx
);
2458 void mono_setup_altstack (MonoJitTlsData
*tls
);
2459 void mono_free_altstack (MonoJitTlsData
*tls
);
2460 gpointer
mono_altstack_restore_prot (host_mgreg_t
*regs
, guint8
*code
, gpointer
*tramp_data
, guint8
* tramp
);
2461 MonoJitInfo
* mini_jit_info_table_find (MonoDomain
*domain
, gpointer addr
, MonoDomain
**out_domain
);
2462 MonoJitInfo
* mini_jit_info_table_find_ext (MonoDomain
*domain
, gpointer addr
, gboolean allow_trampolines
, MonoDomain
**out_domain
);
2463 G_EXTERN_C
void mono_resume_unwind (MonoContext
*ctx
) MONO_LLVM_INTERNAL
;
2465 MonoJitInfo
* mono_find_jit_info (MonoDomain
*domain
, MonoJitTlsData
*jit_tls
, MonoJitInfo
*res
, MonoJitInfo
*prev_ji
, MonoContext
*ctx
, MonoContext
*new_ctx
, char **trace
, MonoLMF
**lmf
, int *native_offset
, gboolean
*managed
);
2467 typedef gboolean (*MonoExceptionFrameWalk
) (MonoMethod
*method
, gpointer ip
, size_t native_offset
, gboolean managed
, gpointer user_data
);
2468 MONO_API gboolean
mono_exception_walk_trace (MonoException
*ex
, MonoExceptionFrameWalk func
, gpointer user_data
);
2469 void mono_restore_context (MonoContext
*ctx
);
2470 guint8
* mono_jinfo_get_unwind_info (MonoJitInfo
*ji
, guint32
*unwind_info_len
);
2471 int mono_jinfo_get_epilog_size (MonoJitInfo
*ji
);
2472 G_EXTERN_C
void mono_llvm_rethrow_exception (MonoObject
*ex
);
2473 G_EXTERN_C
void mono_llvm_throw_exception (MonoObject
*ex
);
2474 G_EXTERN_C
void mono_llvm_throw_corlib_exception (guint32 ex_token_index
);
2475 G_EXTERN_C
void mono_llvm_resume_exception (void);
2476 G_EXTERN_C
void mono_llvm_clear_exception (void);
2477 G_EXTERN_C MonoObject
*mono_llvm_load_exception (void);
2478 void mono_llvm_reset_exception (void);
2479 void mono_llvm_raise_exception (MonoException
*e
);
2480 void mono_llvm_reraise_exception (MonoException
*e
);
2481 G_EXTERN_C gint32
mono_llvm_match_exception (MonoJitInfo
*jinfo
, guint32 region_start
, guint32 region_end
, gpointer rgctx
, MonoObject
*this_obj
);
2484 mono_find_jit_info_ext (MonoDomain
*domain
, MonoJitTlsData
*jit_tls
,
2485 MonoJitInfo
*prev_ji
, MonoContext
*ctx
,
2486 MonoContext
*new_ctx
, char **trace
, MonoLMF
**lmf
,
2487 host_mgreg_t
**save_locations
,
2488 StackFrameInfo
*frame
);
2490 gpointer
mono_get_throw_exception (void);
2491 gpointer
mono_get_rethrow_exception (void);
2492 gpointer
mono_get_rethrow_preserve_exception (void);
2493 gpointer
mono_get_call_filter (void);
2494 gpointer
mono_get_restore_context (void);
2495 gpointer
mono_get_throw_corlib_exception (void);
2496 gpointer
mono_get_throw_exception_addr (void);
2497 gpointer
mono_get_rethrow_preserve_exception_addr (void);
2499 MonoArray
*ves_icall_get_trace (MonoException
*exc
, gint32 skip
, MonoBoolean need_file_info
);
2502 MonoBoolean
ves_icall_get_frame_info (gint32 skip
, MonoBoolean need_file_info
,
2503 MonoReflectionMethod
**method
,
2504 gint32
*iloffset
, gint32
*native_offset
,
2505 MonoString
**file
, gint32
*line
, gint32
*column
);
2506 void mono_set_cast_details (MonoClass
*from
, MonoClass
*to
);
2508 void mono_decompose_typechecks (MonoCompile
*cfg
);
2509 /* Dominator/SSA methods */
2510 void mono_compile_dominator_info (MonoCompile
*cfg
, int dom_flags
);
2511 void mono_compute_natural_loops (MonoCompile
*cfg
);
2512 MonoBitSet
* mono_compile_iterated_dfrontier (MonoCompile
*cfg
, MonoBitSet
*set
);
2513 void mono_ssa_compute (MonoCompile
*cfg
);
2514 void mono_ssa_remove (MonoCompile
*cfg
);
2515 void mono_ssa_remove_gsharedvt (MonoCompile
*cfg
);
2516 void mono_ssa_cprop (MonoCompile
*cfg
);
2517 void mono_ssa_deadce (MonoCompile
*cfg
);
2518 void mono_ssa_strength_reduction (MonoCompile
*cfg
);
2519 void mono_free_loop_info (MonoCompile
*cfg
);
2520 void mono_ssa_loop_invariant_code_motion (MonoCompile
*cfg
);
2522 void mono_ssa_compute2 (MonoCompile
*cfg
);
2523 void mono_ssa_remove2 (MonoCompile
*cfg
);
2524 void mono_ssa_cprop2 (MonoCompile
*cfg
);
2525 void mono_ssa_deadce2 (MonoCompile
*cfg
);
2527 /* debugging support */
2528 void mono_debug_init_method (MonoCompile
*cfg
, MonoBasicBlock
*start_block
,
2529 guint32 breakpoint_id
);
2530 void mono_debug_open_method (MonoCompile
*cfg
);
2531 void mono_debug_close_method (MonoCompile
*cfg
);
2532 void mono_debug_free_method (MonoCompile
*cfg
);
2533 void mono_debug_open_block (MonoCompile
*cfg
, MonoBasicBlock
*bb
, guint32 address
);
2534 void mono_debug_record_line_number (MonoCompile
*cfg
, MonoInst
*ins
, guint32 address
);
2535 void mono_debug_serialize_debug_info (MonoCompile
*cfg
, guint8
**out_buf
, guint32
*buf_len
);
2536 void mono_debug_add_aot_method (MonoDomain
*domain
,
2537 MonoMethod
*method
, guint8
*code_start
,
2538 guint8
*debug_info
, guint32 debug_info_len
);
2539 MONO_API
void mono_debug_print_vars (gpointer ip
, gboolean only_arguments
);
2540 MONO_API
void mono_debugger_run_finally (MonoContext
*start_ctx
);
2542 MONO_API gboolean
mono_breakpoint_clean_code (guint8
*method_start
, guint8
*code
, int offset
, guint8
*buf
, int size
);
2545 MonoCallSpec
*mono_trace_set_options (const char *options
);
2546 gboolean
mono_trace_eval (MonoMethod
*method
);
2549 mono_tailcall_print_enabled (void);
2552 mono_tailcall_print (const char *format
, ...);
2555 mono_is_supported_tailcall_helper (gboolean value
, const char *svalue
);
2557 #define IS_SUPPORTED_TAILCALL(x) (mono_is_supported_tailcall_helper((x), #x))
2560 mono_perform_abc_removal (MonoCompile
*cfg
);
2562 mono_perform_abc_removal (MonoCompile
*cfg
);
2564 mono_local_cprop (MonoCompile
*cfg
);
2566 mono_local_cprop (MonoCompile
*cfg
);
2568 mono_local_deadce (MonoCompile
*cfg
);
2570 mono_local_alias_analysis (MonoCompile
*cfg
);
2572 /* Generic sharing */
2575 mono_set_generic_sharing_supported (gboolean supported
);
2578 mono_set_generic_sharing_vt_supported (gboolean supported
);
2581 mono_set_partial_sharing_supported (gboolean supported
);
2584 mono_class_generic_sharing_enabled (MonoClass
*klass
);
2587 mono_class_fill_runtime_generic_context (MonoVTable
*class_vtable
, guint32 slot
, MonoError
*error
);
2590 mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext
*mrgctx
, guint32 slot
, MonoError
*error
);
2593 mono_rgctx_info_type_to_str (MonoRgctxInfoType type
);
2596 mini_rgctx_info_type_to_patch_info_type (MonoRgctxInfoType info_type
);
2599 mono_method_needs_static_rgctx_invoke (MonoMethod
*method
, gboolean allow_type_vars
);
2602 mono_class_rgctx_get_array_size (int n
, gboolean mrgctx
);
2605 mono_method_construct_object_context (MonoMethod
*method
);
2608 mono_method_get_declaring_generic_method (MonoMethod
*method
);
2611 mono_generic_context_check_used (MonoGenericContext
*context
);
2614 mono_class_check_context_used (MonoClass
*klass
);
2617 mono_generic_context_is_sharable (MonoGenericContext
*context
, gboolean allow_type_vars
);
2620 mono_generic_context_is_sharable_full (MonoGenericContext
*context
, gboolean allow_type_vars
, gboolean allow_partial
);
2623 mono_method_is_generic_impl (MonoMethod
*method
);
2626 mono_method_is_generic_sharable (MonoMethod
*method
, gboolean allow_type_vars
);
2629 mono_method_is_generic_sharable_full (MonoMethod
*method
, gboolean allow_type_vars
, gboolean allow_partial
, gboolean allow_gsharedvt
);
2632 mini_class_is_generic_sharable (MonoClass
*klass
);
2635 mini_generic_inst_is_sharable (MonoGenericInst
*inst
, gboolean allow_type_vars
, gboolean allow_partial
);
2638 mono_class_get_method_generic (MonoClass
*klass
, MonoMethod
*method
, MonoError
*error
);
2641 mono_is_partially_sharable_inst (MonoGenericInst
*inst
);
2644 mini_is_gsharedvt_gparam (MonoType
*t
);
2646 MonoGenericContext
* mini_method_get_context (MonoMethod
*method
);
2648 int mono_method_check_context_used (MonoMethod
*method
);
2650 gboolean
mono_generic_context_equal_deep (MonoGenericContext
*context1
, MonoGenericContext
*context2
);
2652 gpointer
mono_helper_get_rgctx_other_ptr (MonoClass
*caller_class
, MonoVTable
*vtable
,
2653 guint32 token
, guint32 token_source
, guint32 rgctx_type
,
2654 gint32 rgctx_index
);
2656 void mono_generic_sharing_init (void);
2657 void mono_generic_sharing_cleanup (void);
2659 MonoClass
* mini_class_get_container_class (MonoClass
*klass
);
2660 MonoGenericContext
* mini_class_get_context (MonoClass
*klass
);
2663 SHARE_MODE_NONE
= 0x0,
2664 SHARE_MODE_GSHAREDVT
= 0x1,
2665 } GetSharedMethodFlags
;
2667 MonoType
* mini_get_underlying_type (MonoType
*type
) MONO_LLVM_INTERNAL
;
2668 MonoType
* mini_type_get_underlying_type (MonoType
*type
);
2669 MonoClass
* mini_get_class (MonoMethod
*method
, guint32 token
, MonoGenericContext
*context
);
2670 MonoMethod
* mini_get_shared_method_to_register (MonoMethod
*method
);
2671 MonoMethod
* mini_get_shared_method_full (MonoMethod
*method
, GetSharedMethodFlags flags
, MonoError
*error
);
2672 MonoType
* mini_get_shared_gparam (MonoType
*t
, MonoType
*constraint
);
2673 int mini_get_rgctx_entry_slot (MonoJumpInfoRgctxEntry
*entry
);
2675 int mini_type_stack_size (MonoType
*t
, int *align
);
2676 int mini_type_stack_size_full (MonoType
*t
, guint32
*align
, gboolean pinvoke
);
2677 void mini_type_to_eval_stack_type (MonoCompile
*cfg
, MonoType
*type
, MonoInst
*inst
);
2678 guint
mono_type_to_regmove (MonoCompile
*cfg
, MonoType
*type
) MONO_LLVM_INTERNAL
;
2680 void mono_cfg_add_try_hole (MonoCompile
*cfg
, MonoExceptionClause
*clause
, guint8
*start
, MonoBasicBlock
*bb
);
2682 void mono_cfg_set_exception (MonoCompile
*cfg
, MonoExceptionType type
);
2683 void mono_cfg_set_exception_invalid_program (MonoCompile
*cfg
, char *msg
);
2685 #define MONO_TIME_TRACK(a, phase) \
2687 gint64 start = mono_time_track_start (); \
2689 mono_time_track_end (&(a), start); \
2692 gint64
mono_time_track_start (void);
2693 void mono_time_track_end (gint64
*time
, gint64 start
);
2695 void mono_update_jit_stats (MonoCompile
*cfg
);
2697 gboolean
mini_type_is_reference (MonoType
*type
);
2698 gboolean
mini_type_is_vtype (MonoType
*t
) MONO_LLVM_INTERNAL
;
2699 gboolean
mini_type_var_is_vt (MonoType
*type
) MONO_LLVM_INTERNAL
;
2700 gboolean
mini_is_gsharedvt_type (MonoType
*t
);
2701 gboolean
mini_is_gsharedvt_klass (MonoClass
*klass
) MONO_LLVM_INTERNAL
;
2702 gboolean
mini_is_gsharedvt_signature (MonoMethodSignature
*sig
);
2703 gboolean
mini_is_gsharedvt_variable_type (MonoType
*t
) MONO_LLVM_INTERNAL
;
2704 gboolean
mini_is_gsharedvt_variable_klass (MonoClass
*klass
) MONO_LLVM_INTERNAL
;
2705 gboolean
mini_is_gsharedvt_sharable_method (MonoMethod
*method
);
2706 gboolean
mini_is_gsharedvt_variable_signature (MonoMethodSignature
*sig
);
2707 gboolean
mini_is_gsharedvt_sharable_inst (MonoGenericInst
*inst
);
2708 gboolean
mini_method_is_default_method (MonoMethod
*m
);
2709 gboolean
mini_method_needs_mrgctx (MonoMethod
*m
);
2710 gpointer
mini_method_get_rgctx (MonoMethod
*m
);
2711 void mini_init_gsctx (MonoDomain
*domain
, MonoMemPool
*mp
, MonoGenericContext
*context
, MonoGenericSharingContext
*gsctx
);
2713 gpointer
mini_get_gsharedvt_wrapper (gboolean gsharedvt_in
, gpointer addr
, MonoMethodSignature
*normal_sig
, MonoMethodSignature
*gsharedvt_sig
,
2714 gint32 vcall_offset
, gboolean calli
);
2715 MonoMethod
* mini_get_gsharedvt_in_sig_wrapper (MonoMethodSignature
*sig
);
2716 MonoMethod
* mini_get_gsharedvt_out_sig_wrapper (MonoMethodSignature
*sig
);
2717 MonoMethodSignature
* mini_get_gsharedvt_out_sig_wrapper_signature (gboolean has_this
, gboolean has_ret
, int param_count
);
2718 gboolean
mini_gsharedvt_runtime_invoke_supported (MonoMethodSignature
*sig
);
2719 G_EXTERN_C
void mono_interp_entry_from_trampoline (gpointer ccontext
, gpointer imethod
);
2720 G_EXTERN_C
void mono_interp_to_native_trampoline (gpointer addr
, gpointer ccontext
);
2721 MonoMethod
* mini_get_interp_in_wrapper (MonoMethodSignature
*sig
);
2722 MonoMethod
* mini_get_interp_lmf_wrapper (const char *name
, gpointer target
);
2723 char* mono_get_method_from_ip (void *ip
);
2728 This enum MUST be kept in sync with its managed mirror Mono.Simd.AccelMode.
2731 SIMD_VERSION_SSE1
= 1 << 0,
2732 SIMD_VERSION_SSE2
= 1 << 1,
2733 SIMD_VERSION_SSE3
= 1 << 2,
2734 SIMD_VERSION_SSSE3
= 1 << 3,
2735 SIMD_VERSION_SSE41
= 1 << 4,
2736 SIMD_VERSION_SSE42
= 1 << 5,
2737 SIMD_VERSION_SSE4a
= 1 << 6,
2738 SIMD_VERSION_ALL
= SIMD_VERSION_SSE1
| SIMD_VERSION_SSE2
|
2739 SIMD_VERSION_SSE3
| SIMD_VERSION_SSSE3
|
2740 SIMD_VERSION_SSE41
| SIMD_VERSION_SSE42
|
2743 /* this value marks the end of the bit indexes used in
2746 SIMD_VERSION_INDEX_END
= 6
2761 SIMD_PREFETCH_MODE_NTA
,
2762 SIMD_PREFETCH_MODE_0
,
2763 SIMD_PREFETCH_MODE_1
,
2764 SIMD_PREFETCH_MODE_2
,
2767 const char *mono_arch_xregname (int reg
);
2768 guint32
mono_arch_cpu_enumerate_simd_versions (void);
2770 #ifdef MONO_ARCH_SIMD_INTRINSICS
2771 void mono_simd_simplify_indirection (MonoCompile
*cfg
);
2772 void mono_simd_decompose_intrinsic (MonoCompile
*cfg
, MonoBasicBlock
*bb
, MonoInst
*ins
);
2773 void mono_simd_decompose_intrinsics (MonoCompile
*cfg
);
2774 MonoInst
* mono_emit_simd_intrinsics (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**args
);
2775 MonoInst
* mono_emit_simd_field_load (MonoCompile
*cfg
, MonoClassField
*field
, MonoInst
*addr
);
2776 void mono_simd_intrinsics_init (void);
2779 gboolean
mono_class_is_magic_int (MonoClass
*klass
);
2780 gboolean
mono_class_is_magic_float (MonoClass
*klass
);
2781 MonoInst
* mono_emit_native_types_intrinsics (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**args
);
2782 gsize
mini_magic_type_size (MonoCompile
*cfg
, MonoType
*type
);
2783 gboolean
mini_magic_is_int_type (MonoType
*t
);
2784 gboolean
mini_magic_is_float_type (MonoType
*t
);
2785 MonoType
* mini_native_type_replace_type (MonoType
*type
) MONO_LLVM_INTERNAL
;
2788 mini_method_to_shared (MonoMethod
*method
); // null if not shared
2790 static inline gboolean
2791 mini_safepoints_enabled (void)
2793 #if defined (TARGET_WASM)
2800 #endif /* __MONO_MINI_H__ */