New tests.
[mono.git] / mono / mini / mini.h
index f558326baa180bc3ce187a6c5f6243c620e27f97..5d9c7658998c6b32fbdace3cfe338e28e1ac7f3e 100644 (file)
@@ -66,6 +66,12 @@ typedef gint64 mgreg_t;
 #define LLVM_ENABLED FALSE
 #endif
 
+#ifdef MONO_ARCH_SOFT_FLOAT
+#define COMPILE_SOFT_FLOAT(cfg) (!COMPILE_LLVM ((cfg)))
+#else
+#define COMPILE_SOFT_FLOAT(cfg) 0
+#endif
+
 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
 
 /* for 32 bit systems */
@@ -89,7 +95,7 @@ typedef gint64 mgreg_t;
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "67"
+#define MONO_AOT_FILE_VERSION "68"
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -459,8 +465,9 @@ struct MonoBasicBlock {
        /* Length of the CIL block */
        gint32 cil_length;
 
-       /* The address of the generated code, used for fixups */
+       /* The offset of the generated code, used for fixups */
        int native_offset;
+       int native_length;
        int max_offset;
        int max_length;
 
@@ -603,6 +610,7 @@ struct MonoInst {
                        MonoClass *klass;
                        int *phi_args;
                        MonoCallInst *call_inst;
+                       MonoExceptionClause *exception_clause;
                } op [2];
                gint64 i8const;
                double r8const;
@@ -672,8 +680,6 @@ struct MonoCallArgParm {
  */
 enum {
        MONO_INST_HAS_METHOD = 1,
-       /* temp local created by a DUP: used only within a BB */
-       MONO_INST_IS_TEMP    = 1,
        MONO_INST_INIT       = 1, /* in localloc */
        MONO_INST_SINGLE_STEP_LOC = 1, /* in SEQ_POINT */
        MONO_INST_IS_DEAD    = 2,
@@ -687,6 +693,8 @@ enum {
        /* the address of the variable has been taken */
        MONO_INST_INDIRECT   = 16,
        MONO_INST_NORANGECHECK   = 16,
+       /* On loads, the source address can be null */
+       MONO_INST_FAULT = 32
 };
 
 #define inst_c0 data.op[0].const_val
@@ -724,6 +732,7 @@ enum {
 #define inst_call   data.op[1].call_inst
 
 #define inst_phi_args   data.op[1].phi_args
+#define inst_eh_block   data.op[1].exception_clause
 
 /* instruction description for use in regalloc/scheduling */
 enum {
@@ -803,14 +812,19 @@ typedef struct {
        guint32          signal_stack_size;
        gpointer         stack_ovf_guard_base;
        guint32          stack_ovf_guard_size;
+       guint            stack_ovf_valloced : 1;
        void            (*abort_func) (MonoObject *object);
        /* Used to implement --debug=casts */
        MonoClass       *class_cast_from, *class_cast_to;
 
-       /* Stores state needed by mono_resume_unwind () */
+       /* Stores state needed by mono_resume_unwind () and the handler block with a guard */
        MonoContext     ex_ctx;
        /* FIXME: GC */
        gpointer        ex_obj;
+       /* handle block return address */
+       gpointer handler_block_return_address;
+       /* handler block been guarded */
+       MonoJitExceptionInfo *handler_block;
 } MonoJitTlsData;
 
 typedef enum {
@@ -900,6 +914,9 @@ typedef enum {
        MONO_TRAMPOLINE_MONITOR_EXIT,
 #ifdef MONO_ARCH_LLVM_SUPPORTED
        MONO_TRAMPOLINE_LLVM_VCALL,
+#endif
+#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
+       MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD,
 #endif
        MONO_TRAMPOLINE_NUM
 } MonoTrampolineType;
@@ -937,6 +954,7 @@ enum {
  */
 typedef struct {
        MonoMethod      *method;
+       MonoMethodHeader *header;
        MonoMemPool     *mempool;
        MonoInst       **varinfo;
        MonoMethodVar   *vars;
@@ -1042,12 +1060,16 @@ typedef struct {
        guint            skip_visibility : 1;
        guint            disable_reuse_registers : 1;
        guint            disable_reuse_stack_slots : 1;
+       guint            disable_reuse_ref_stack_slots : 1;
        guint            disable_initlocals_opt : 1;
+       guint            disable_initlocals_opt_refs : 1;
        guint            disable_omit_fp : 1;
        guint            disable_vreg_to_lvreg : 1;
        guint            disable_deadce_vars : 1;
        guint            disable_out_of_line_bblocks : 1;
+       guint            init_ref_vars : 1;
        guint            extend_live_ranges : 1;
+       guint            compute_precise_live_ranges : 1;
        guint            has_got_slots : 1;
        guint            uses_rgctx_reg : 1;
        guint            uses_vtable_reg : 1;
@@ -1125,9 +1147,13 @@ typedef struct {
 
        /* Used by AOT */
        guint32 got_offset, ex_info_offset, method_info_offset;
+       /* Symbol used to refer to this method in generated assembly */
+       char *asm_symbol;
 
        MonoJitExceptionInfo *llvm_ex_info;
        guint32 llvm_ex_info_len;
+
+       GSList *try_block_holes;
 } MonoCompile;
 
 typedef enum {
@@ -1320,6 +1346,11 @@ typedef struct {
        gboolean gdb;
        gboolean gen_seq_points;
        gboolean explicit_null_checks;
+       /*
+        * Fill stack frames with 0x2a in method prologs. This helps with the
+        * debugging of the stack marking code in the GC.
+        */
+       gboolean init_stacks;
 } MonoDebugOptions;
 
 enum {
@@ -1462,6 +1493,7 @@ gint32    mono_get_lmf_tls_offset           (void) MONO_INTERNAL;
 gint32    mono_get_lmf_addr_tls_offset      (void) MONO_INTERNAL;
 MonoInst* mono_get_jit_tls_intrinsic        (MonoCompile *cfg) MONO_INTERNAL;
 MonoInst* mono_get_domain_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
+MonoInst* mono_get_thread_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
 GList    *mono_varlist_insert_sorted        (MonoCompile *cfg, GList *list, MonoMethodVar *mv, gboolean sort_end) MONO_INTERNAL;
 GList    *mono_varlist_sort                 (MonoCompile *cfg, GList *list, int sort_type) MONO_INTERNAL;
 void      mono_analyze_liveness             (MonoCompile *cfg) MONO_INTERNAL;
@@ -1478,6 +1510,9 @@ gboolean  mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *m
 gboolean  mini_method_verify (MonoCompile *cfg, MonoMethod *method) MONO_INTERNAL;
 MonoInst *mono_get_got_var (MonoCompile *cfg) MONO_INTERNAL;
 void      mono_add_seq_point (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int native_offset) MONO_INTERNAL;
+MonoInst* mono_emit_jit_icall (MonoCompile *cfg, gconstpointer func, MonoInst **args) MONO_INTERNAL;
+MonoInst* mono_emit_method_call (MonoCompile *cfg, MonoMethod *method, MonoInst **args, MonoInst *this) MONO_INTERNAL;
+
 
 gboolean  mini_class_is_system_array (MonoClass *klass) MONO_INTERNAL;
 MonoMethodSignature *mono_get_element_address_signature (int arity) MONO_INTERNAL;
@@ -1504,6 +1539,7 @@ gboolean  mono_aot_get_cached_class_info    (MonoClass *klass, MonoCachedClassIn
 gboolean  mono_aot_get_class_from_name      (MonoImage *image, const char *name_space, const char *name, MonoClass **klass) MONO_INTERNAL;
 MonoJitInfo* mono_aot_find_jit_info         (MonoDomain *domain, MonoImage *image, gpointer addr) MONO_INTERNAL;
 gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code) MONO_INTERNAL;
+void     mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) MONO_INTERNAL;
 gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot) MONO_INTERNAL;
 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
 gpointer mono_aot_get_named_code            (const char *name) MONO_INTERNAL;
@@ -1521,6 +1557,9 @@ char*    mono_aot_get_method_name           (MonoCompile *cfg) MONO_INTERNAL;
 char*    mono_aot_get_plt_symbol            (MonoJumpInfoType type, gconstpointer data) MONO_INTERNAL;
 char*    mono_aot_get_method_debug_name     (MonoCompile *cfg) MONO_INTERNAL;
 MonoJumpInfo* mono_aot_patch_info_dup       (MonoJumpInfo* ji) MONO_INTERNAL;
+void     mono_aot_set_make_unreadable       (gboolean unreadable) MONO_INTERNAL;
+gboolean mono_aot_is_pagefault              (void *ptr) MONO_INTERNAL;
+void     mono_aot_handle_pagefault          (void *ptr) MONO_INTERNAL;
 
 /* This is an exported function */
 void     mono_aot_register_globals          (gpointer *globals);
@@ -1590,7 +1629,7 @@ void              mono_generic_class_init_trampoline (mgreg_t *regs, guint8 *cod
 void              mono_monitor_enter_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
 void              mono_monitor_exit_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
 gconstpointer     mono_get_trampoline_func (MonoTrampolineType tramp_type);
-gpointer          mini_get_vtable_trampoline (void) MONO_INTERNAL;
+gpointer          mini_get_vtable_trampoline (int slot_index) MONO_INTERNAL;
 gpointer*         mono_get_vcall_slot_addr (guint8* code, mgreg_t *regs) MONO_INTERNAL;
 
 gboolean          mono_running_on_valgrind (void) MONO_INTERNAL;
@@ -1769,6 +1808,12 @@ MonoVTable* mono_arch_find_static_call_vtable   (mgreg_t *regs, guint8 *code) MO
 gpointer    mono_arch_build_imt_thunk           (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp) MONO_INTERNAL;
 void    mono_arch_notify_pending_exc            (void) MONO_INTERNAL;
 
+/* Handle block guard */
+gpointer mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value) MONO_INTERNAL;
+gpointer mono_arch_create_handler_block_trampoline (void) MONO_INTERNAL;
+gpointer mono_create_handler_block_trampoline (void) MONO_INTERNAL;
+gboolean mono_install_handler_block_guard (MonoInternalThread *thread, MonoContext *ctx) MONO_INTERNAL;
+
 /* Exception handling */
 
 /* Same as MonoStackWalk, but pass the context/frame type as well */
@@ -1884,6 +1929,59 @@ MonoArray* ves_icall_System_Security_SecurityFrame_GetSecurityStack (gint32 skip
 
 /* Generic sharing */
 
+
+void
+mono_set_generic_sharing_supported (gboolean supported) MONO_INTERNAL;
+
+gboolean
+mono_class_generic_sharing_enabled (MonoClass *class) MONO_INTERNAL;
+
+gpointer
+mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot) MONO_INTERNAL;
+
+gpointer
+mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot) MONO_INTERNAL;
+
+MonoMethodRuntimeGenericContext*
+mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst) MONO_INTERNAL;
+
+gboolean
+mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
+
+int
+mono_class_rgctx_get_array_size (int n, gboolean mrgctx) MONO_INTERNAL;
+
+guint32
+mono_method_lookup_or_register_other_info (MonoMethod *method, gboolean in_mrgctx, gpointer data,
+       int info_type, MonoGenericContext *generic_context) MONO_INTERNAL;
+
+MonoGenericContext
+mono_method_construct_object_context (MonoMethod *method) MONO_INTERNAL;
+
+int
+mono_generic_context_check_used (MonoGenericContext *context) MONO_INTERNAL;
+
+int
+mono_class_check_context_used (MonoClass *class) MONO_INTERNAL;
+
+gboolean
+mono_generic_context_is_sharable (MonoGenericContext *context, gboolean allow_type_vars) MONO_INTERNAL;
+
+gboolean
+mono_generic_context_is_sharable_full (MonoGenericContext *context, gboolean allow_type_vars, gboolean allow_partial) MONO_INTERNAL;
+
+gboolean
+mono_method_is_generic_impl (MonoMethod *method) MONO_INTERNAL;
+
+gboolean
+mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
+
+gboolean
+mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_type_vars, gboolean allow_partial) MONO_INTERNAL;
+
+gboolean
+mono_is_partially_sharable_inst (MonoGenericInst *inst) MONO_INTERNAL;
+
 MonoGenericSharingContext* mono_get_generic_context_from_code (guint8 *code) MONO_INTERNAL;
 
 MonoGenericContext* mini_method_get_context (MonoMethod *method) MONO_INTERNAL;
@@ -1903,12 +2001,16 @@ MonoGenericContext* mini_class_get_context (MonoClass *class) MONO_INTERNAL;
 
 MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
 MonoType* mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
+MonoMethod* mini_get_shared_method (MonoMethod *method) MONO_INTERNAL;
+MonoMethod* mini_get_shared_method_to_register (MonoMethod *method) MONO_INTERNAL;
 
 int mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align) MONO_INTERNAL;
 int mini_type_stack_size_full (MonoGenericSharingContext *gsctx, MonoType *t, guint32 *align, gboolean pinvoke) MONO_INTERNAL;
 void type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst) MONO_INTERNAL;
 guint mono_type_to_regmove (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
 
+void mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb) MONO_INTERNAL;
+
 /* wapihandles.c */
 int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;
 
@@ -1920,18 +2022,28 @@ int mini_wapi_seminfo (int argc, char **argv) MONO_INTERNAL;
 
 /*
 This enum MUST be kept in sync with its managed mirror Mono.Simd.AccelMode.
-The AccelMode values are masks while the ones here are the bit indexes.
  */
 enum {
-       SIMD_VERSION_SSE1       = 0,
-       SIMD_VERSION_SSE2       = 1,
-       SIMD_VERSION_SSE3       = 2,
-       SIMD_VERSION_SSSE3      = 3,
-       SIMD_VERSION_SSE41      = 4,
-       SIMD_VERSION_SSE42      = 5,
-       SIMD_VERSION_SSE4a      = 6,
+       SIMD_VERSION_SSE1       = 1 << 0,
+       SIMD_VERSION_SSE2       = 1 << 1,
+       SIMD_VERSION_SSE3       = 1 << 2,
+       SIMD_VERSION_SSSE3      = 1 << 3,
+       SIMD_VERSION_SSE41      = 1 << 4,
+       SIMD_VERSION_SSE42      = 1 << 5,
+       SIMD_VERSION_SSE4a      = 1 << 6,
+       SIMD_VERSION_ALL        = SIMD_VERSION_SSE1 | SIMD_VERSION_SSE2 |
+                         SIMD_VERSION_SSE3 | SIMD_VERSION_SSSE3 |
+                         SIMD_VERSION_SSE41 | SIMD_VERSION_SSE42 |
+                         SIMD_VERSION_SSE4a,
+
+       /* this value marks the end of the bit indexes used in 
+        * this emum.
+        */
+       SIMD_VERSION_INDEX_END = 6 
 };
 
+#define MASK(x) (1 << x)
+
 enum {
        SIMD_COMP_EQ,
        SIMD_COMP_LT,
@@ -1956,6 +2068,18 @@ MonoInst*   mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, Mo
 guint32     mono_arch_cpu_enumerate_simd_versions (void) MONO_INTERNAL;
 void        mono_simd_intrinsics_init (void) MONO_INTERNAL;
 
+#ifdef __linux__
+/* maybe enable also for other systems? */
+#define ENABLE_JIT_MAP 1
+void mono_enable_jit_map (void) MONO_INTERNAL;
+void mono_emit_jit_map   (MonoJitInfo *jinfo) MONO_INTERNAL;
+void mono_emit_jit_tramp (void *start, int size, const char *desc) MONO_INTERNAL;
+#else
+#define mono_enable_jit_map()
+#define mono_emit_jit_map(ji)
+#define mono_emit_jit_tramp(s,z,d)
+#endif
+
 /*
  * Per-OS implementation functions.
  */
@@ -1982,9 +2106,9 @@ gboolean mono_gdb_render_native_backtraces (void) MONO_INTERNAL;
 #ifdef MONO_ARCH_USE_SIGACTION
 #define GET_CONTEXT \
     void *ctx = context;
-#elif defined(__sparc__)
+#elif defined(__HAIKU__)
 #define GET_CONTEXT \
-    void *ctx = sigctx;
+       void *ctx = &regs;
 #else
 #define GET_CONTEXT \
        void **_p = (void **)&_dummy; \
@@ -1999,9 +2123,9 @@ gboolean mono_gdb_render_native_backtraces (void) MONO_INTERNAL;
 #elif defined(HOST_WIN32)
 #define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_RECORD *info, void *context)
 #define SIG_HANDLER_PARAMS _dummy, info, context
-#elif defined(__sparc__)
-#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, void *sigctx)
-#define SIG_HANDLER_PARAMS _dummy, sigctx
+#elif defined(__HAIKU__)
+#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, void *userData, vregs regs)
+#define SIG_HANDLER_PARAMS _dummy, userData, regs
 #else
 #define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy)
 #define SIG_HANDLER_PARAMS _dummy