1 #ifndef __MONO_MINI_INTERPRETER_INTERNALS_H__
2 #define __MONO_MINI_INTERPRETER_INTERNALS_H__
6 #include <mono/metadata/loader.h>
7 #include <mono/metadata/object.h>
8 #include <mono/metadata/domain-internals.h>
9 #include <mono/metadata/class-internals.h>
10 #include <mono/metadata/debug-internals.h>
13 #define MINT_TYPE_I1 0
14 #define MINT_TYPE_U1 1
15 #define MINT_TYPE_I2 2
16 #define MINT_TYPE_U2 3
17 #define MINT_TYPE_I4 4
18 #define MINT_TYPE_I8 5
19 #define MINT_TYPE_R4 6
20 #define MINT_TYPE_R8 7
23 #define MINT_TYPE_VT 10
25 #define INLINED_METHOD_FLAG 0xffff
27 #define MINT_VT_ALIGNMENT 8
35 VAL_NATI
= 0 + VAL_POINTER
,
36 VAL_MP
= 1 + VAL_POINTER
,
37 VAL_TP
= 2 + VAL_POINTER
,
38 VAL_OBJ
= 3 + VAL_POINTER
42 INTERP_OPT_INLINE
= 1,
44 INTERP_OPT_DEFAULT
= INTERP_OPT_INLINE
| INTERP_OPT_CPROP
47 #if SIZEOF_VOID_P == 4
48 typedef guint32 mono_u
;
49 typedef gint32 mono_i
;
50 #elif SIZEOF_VOID_P == 8
51 typedef guint64 mono_u
;
52 typedef gint64 mono_i
;
59 * The interpreter executes in gc unsafe (non-preempt) mode. On wasm, the C stack is
60 * scannable but the wasm stack is not, so to make the code GC safe, the following rules
62 * - every objref handled by the code needs to either be stored volatile or stored
63 * into a volatile; volatile stores are stack packable, volatile values are not.
64 * Use either OBJREF or stackval->data.o.
65 * This will ensure the objects are pinned. A volatile local
66 * is on the stack and not in registers. Volatile stores ditto.
67 * - minimize the number of MonoObject* locals/arguments (or make them volatile).
69 * Volatile on a type/local forces all reads and writes to go to memory/stack,
70 * and each such local to have a unique address.
72 * Volatile absence on a type/local allows multiple locals to share storage,
73 * if their lifetimes do not overlap. This is called "stack packing".
75 * Volatile absence on a type/local allows the variable to live in
76 * both stack and register, for fast reads and "write through".
80 #define WASM_VOLATILE volatile
82 static inline MonoObject
* WASM_VOLATILE
*
83 mono_interp_objref (MonoObject
**o
)
88 #define OBJREF(x) (*mono_interp_objref (&x))
92 #define WASM_VOLATILE /* nothing */
100 * Value types are represented on the eval stack as pointers to the
101 * actual storage. The size field tells how much storage is allocated.
102 * A value type can't be larger than 16 MB.
114 MonoObject
* WASM_VOLATILE o
;
115 /* native size integer and pointer types */
120 #if defined(__ppc__) || defined(__powerpc__)
125 typedef struct _InterpFrame InterpFrame
;
127 typedef void (*MonoFuncV
) (void);
128 typedef void (*MonoPIFunc
) (void *callme
, void *margs
);
131 * Structure representing a method transformed for the interpreter
132 * This is domain specific
134 typedef struct _InterpMethod
136 /* NOTE: These first two elements (method and
137 next_jit_code_hash) must be in the same order and at the
138 same offset as in MonoJitInfo, because of the jit_code_hash
139 internal hash table in MonoDomain. */
141 struct _InterpMethod
*next_jit_code_hash
;
143 guint32 total_locals_size
;
145 guint32 vt_stack_size
;
147 unsigned int init_locals
: 1;
148 unsigned int vararg
: 1;
149 unsigned int needs_thread_attach
: 1;
150 unsigned short *code
;
153 MonoExceptionClause
*clauses
;
156 guint32
*local_offsets
;
157 guint32
*exvar_offsets
;
158 unsigned int param_count
;
159 unsigned int hasthis
;
160 gpointer jit_wrapper
;
162 MonoMethodSignature
*jit_sig
;
164 gpointer llvmonly_unbox_entry
;
166 MonoType
**param_types
;
169 MonoProfilerCallInstrumentationFlags prof_flags
;
172 struct _InterpFrame
{
173 InterpFrame
*parent
; /* parent */
174 InterpMethod
*imethod
; /* parent */
175 stackval
*retval
; /* parent */
176 stackval
*stack_args
; /* parent */
179 const unsigned short *ip
;
182 #define frame_locals(frame) (((guchar*)((frame)->stack)) + (frame)->imethod->stack_size + (frame)->imethod->vt_stack_size)
185 /* Lets interpreter know it has to resume execution after EH */
186 gboolean has_resume_state
;
187 /* Frame to resume execution at */
188 InterpFrame
*handler_frame
;
189 /* IP to resume execution at */
190 const guint16
*handler_ip
;
191 /* Clause that we are resuming to */
192 MonoJitExceptionInfo
*handler_ei
;
193 /* Exception that is being thrown. Set with rest of resume state */
194 guint32 exc_gchandle
;
198 gint64 transform_time
;
202 gint32 copy_propagations
;
203 gint32 killed_instructions
;
204 gint32 inlined_methods
;
205 gint32 inline_failures
;
208 extern MonoInterpStats mono_interp_stats
;
210 extern int mono_interp_traceopt
;
211 extern int mono_interp_opt
;
212 extern GSList
*mono_interp_jit_classes
;
215 mono_interp_transform_method (InterpMethod
*imethod
, ThreadContext
*context
, MonoError
*error
);
218 mono_interp_transform_init (void);
221 mono_interp_get_imethod (MonoDomain
*domain
, MonoMethod
*method
, MonoError
*error
);
224 mono_interp_print_code (InterpMethod
*imethod
);
227 mint_type(MonoType
*type_
)
229 MonoType
*type
= mini_native_type_replace_type (type_
);
233 switch (type
->type
) {
237 case MONO_TYPE_BOOLEAN
:
249 #if SIZEOF_VOID_P == 4
263 case MONO_TYPE_STRING
:
264 case MONO_TYPE_SZARRAY
:
265 case MONO_TYPE_CLASS
:
266 case MONO_TYPE_OBJECT
:
267 case MONO_TYPE_ARRAY
:
269 case MONO_TYPE_VALUETYPE
:
270 if (m_class_is_enumtype (type
->data
.klass
)) {
271 type
= mono_class_enum_basetype_internal (type
->data
.klass
);
275 case MONO_TYPE_TYPEDBYREF
:
277 case MONO_TYPE_GENERICINST
:
278 type
= m_class_get_byval_arg (type
->data
.generic_class
->container_class
);
281 g_warning ("got type 0x%02x", type
->type
);
282 g_assert_not_reached ();
287 #endif /* __MONO_MINI_INTERPRETER_INTERNALS_H__ */