X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=3db26016be6916051fc83df8484df66823b41208;hb=07956c6dc20ce785cd45c2ec1c654a1421f0ef72;hp=7cb99a22ca87f2462dcbcf3bfcbbc12ef8cd46ee;hpb=fbda8be0cff175efe8892ccac812668429bc0b99;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 7cb99a22ca8..3db26016be6 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -22,6 +22,10 @@ #include #endif +#ifdef PLATFORM_WIN32 +#define _WIN32_WINNT 0x0500 +#endif + #ifdef HAVE_VALGRIND_MEMCHECK_H #include #endif @@ -92,6 +96,7 @@ static gpointer mono_jit_compile_method_with_opt (MonoMethod *method, guint32 op static gpointer mono_jit_compile_method (MonoMethod *method); static gpointer mono_jit_find_compiled_method (MonoDomain *domain, MonoMethod *method); static gpointer mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method); +inline static int mono_emit_jit_icall (MonoCompile *cfg, MonoBasicBlock *bblock, gconstpointer func, MonoInst **args, const guint8 *ip); static void handle_stobj (MonoCompile *cfg, MonoBasicBlock *bblock, MonoInst *dest, MonoInst *src, const unsigned char *ip, MonoClass *klass, gboolean to_end, gboolean native, gboolean write_barrier); @@ -1410,8 +1415,12 @@ type_from_op (MonoInst *ins) { ins->type = STACK_PTR; switch (ins->inst_i0->type) { case STACK_I4: + break; case STACK_PTR: case STACK_MP: +#if SIZEOF_VOID_P == 8 + ins->opcode = OP_LCONV_TO_U; +#endif break; case STACK_I8: ins->opcode = OP_LCONV_TO_U; @@ -1627,7 +1636,8 @@ mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode) MONO_INIT_VARINFO (cfg->vars [num], num); cfg->num_varinfo++; - //g_print ("created temp %d of type %s\n", num, mono_type_get_name (type)); + if (cfg->verbose_level > 2) + g_print ("created temp %d of type %s\n", num, mono_type_get_name (type)); return inst; } @@ -1680,7 +1690,14 @@ type_from_stack_type (MonoInst *ins) { return &ins->klass->this_arg; else return &mono_defaults.object_class->this_arg; - case STACK_OBJ: return &mono_defaults.object_class->byval_arg; + case STACK_OBJ: + /* ins->klass may not be set for ldnull. + * Also, if we have a boxed valuetype, we want an object lass, + * not the valuetype class + */ + if (ins->klass && !ins->klass->valuetype) + return &ins->klass->byval_arg; + return &mono_defaults.object_class->byval_arg; case STACK_VTYPE: return &ins->klass->byval_arg; default: g_error ("stack type %d to montype not handled\n", ins->type); @@ -1694,7 +1711,7 @@ mono_type_from_stack_type (MonoInst *ins) { } static MonoClass* -array_access_to_klass (int opcode) +array_access_to_klass (int opcode, MonoInst *array_obj) { switch (opcode) { case CEE_LDELEM_U1: @@ -1725,8 +1742,13 @@ array_access_to_klass (int opcode) case CEE_STELEM_R8: return mono_defaults.double_class; case CEE_LDELEM_REF: - case CEE_STELEM_REF: + case CEE_STELEM_REF: { + MonoClass *klass = array_obj->klass; + /* FIXME: add assert */ + if (klass && klass->rank) + return klass->element_class; return mono_defaults.object_class; + } default: g_assert_not_reached (); } @@ -1986,11 +2008,16 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun * in the inlined methods do not inherit their in_stack from * the bblock they are inlined to. See bug #58863 for an * example. + * This hack is disabled since it also prevents proper tracking of types. */ +#if 1 + bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL); +#else if (cfg->inlined_method) bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL); else bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]); +#endif } } } @@ -2218,9 +2245,20 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg) if (arg->type != STACK_I4 && arg->type != STACK_PTR) return 1; return 0; - case MONO_TYPE_CLASS: - case MONO_TYPE_STRING: case MONO_TYPE_OBJECT: + if (arg->type != STACK_OBJ) + return 1; + return 0; + case MONO_TYPE_STRING: + if (arg->type != STACK_OBJ) + return 1; + /* ldnull has arg->klass unset */ + /*if (arg->klass && arg->klass != mono_defaults.string_class) { + G_BREAKPOINT (); + return 1; + }*/ + return 0; + case MONO_TYPE_CLASS: case MONO_TYPE_SZARRAY: case MONO_TYPE_ARRAY: if (arg->type != STACK_OBJ) @@ -2253,9 +2291,11 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg) return 0; case MONO_TYPE_GENERICINST: if (mono_type_generic_inst_is_valuetype (simple_type)) { + klass = mono_class_from_mono_type (simple_type); + if (klass->enumtype) + return target_type_is_incompatible (cfg, klass->enum_basetype, arg); if (arg->type != STACK_VTYPE) return 1; - klass = mono_class_from_mono_type (simple_type); if (klass != arg->klass) return 1; return 0; @@ -2708,10 +2748,19 @@ handle_load_float (MonoCompile *cfg, MonoBasicBlock *bblock, MonoInst *ptr, cons NEW_TEMPLOAD (cfg, (ins), temp); \ } \ } while (0) +#define STARG_SOFT_FLOAT(cfg,ins,idx,ip) do {\ + if (param_types [(idx)]->type == MONO_TYPE_R4 && !param_types [(idx)]->byref) { \ + int temp; \ + NEW_ARGLOADA (cfg, (ins), (idx)); \ + handle_store_float (cfg, bblock, (ins), *sp, (ip)); \ + MONO_INST_NEW (cfg, (ins), CEE_NOP); \ + } \ + } while (0) #else #define LDLOC_SOFT_FLOAT(cfg,ins,idx,ip) #define STLOC_SOFT_FLOAT(cfg,ins,idx,ip) #define LDARG_SOFT_FLOAT(cfg,ins,idx,ip) +#define STARG_SOFT_FLOAT(cfg,ins,idx,ip) #endif static MonoMethod* @@ -3027,6 +3076,11 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method) MONO_TYPE_ISSTRUCT (signature->ret)) return FALSE; +#ifdef MONO_ARCH_SOFT_FLOAT + /* this complicates things, fix later */ + if (signature->ret->type == MONO_TYPE_R4) + return FALSE; +#endif /* its not worth to inline methods with valuetype arguments?? */ for (i = 0; i < signature->param_count; i++) { if (MONO_TYPE_ISSTRUCT (signature->params [i])) { @@ -3261,6 +3315,15 @@ mini_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSigna MONO_INST_NEW (cfg, ins, CEE_BREAK); return ins; } + if (cmethod->name [0] == 'g' && strcmp (cmethod->name, "get_IsRunningOnWindows") == 0 + && strcmp (cmethod->klass->name, "Environment") == 0) { +#ifdef PLATFORM_WIN32 + NEW_ICONST (cfg, ins, 1); +#else + NEW_ICONST (cfg, ins, 0); +#endif + return ins; + } } return mono_arch_get_inst_for_method (cfg, cmethod, fsig, args); @@ -3697,6 +3760,13 @@ can_access_internals (MonoAssembly *accessing, MonoAssembly* accessed) static gboolean can_access_member (MonoClass *access_klass, MonoClass *member_klass, int access_level) { + if (access_klass->generic_class && member_klass->generic_class && + access_klass->generic_class->container_class && member_klass->generic_class->container_class) { + if (can_access_member (access_klass->generic_class->container_class, + member_klass->generic_class->container_class, access_level)) + return TRUE; + } + /* Partition I 8.5.3.2 */ /* the access level values are the same for fields and methods */ switch (access_level) { @@ -3707,7 +3777,7 @@ can_access_member (MonoClass *access_klass, MonoClass *member_klass, int access_ return access_klass == member_klass; case FIELD_ATTRIBUTE_FAM_AND_ASSEM: if (mono_class_has_parent (access_klass, member_klass) && - can_access_internals (access_klass->image->assembly, member_klass->image->assembly)) + can_access_internals (access_klass->image->assembly, member_klass->image->assembly)) return TRUE; return FALSE; case FIELD_ATTRIBUTE_ASSEMBLY: @@ -3768,6 +3838,73 @@ can_access_method (MonoMethod *method, MonoMethod *called) return can; } +/* + * Check that the IL instructions at ip are the array initialization + * sequence and return the pointer to the data and the size. + */ +static const char* +initialize_array_data (MonoMethod *method, gboolean aot, unsigned char *ip, MonoInst *newarr, int *out_size) +{ + /* + * newarr[System.Int32] + * dup + * ldtoken field valuetype ... + * call void class [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle) + */ + if (ip [0] == CEE_DUP && ip [1] == CEE_LDTOKEN && ip [5] == 0x4 && ip [6] == CEE_CALL) { + MonoClass *klass = newarr->inst_newa_class; + guint32 token = read32 (ip + 7); + guint32 rva, field_index; + const char *data_ptr; + int size = 0; + MonoMethod *cmethod; + + if (newarr->inst_newa_len->opcode != OP_ICONST) + return NULL; + cmethod = mini_get_method (method, token, NULL, NULL); + if (strcmp (cmethod->name, "InitializeArray") || strcmp (cmethod->klass->name, "RuntimeHelpers") || cmethod->klass->image != mono_defaults.corlib) + return NULL; + switch (mono_type_get_underlying_type (&klass->byval_arg)->type) { + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_I1: + case MONO_TYPE_U1: + size = 1; break; + /* we need to swap on big endian, so punt. Should we handle R4 and R8 as well? */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + case MONO_TYPE_CHAR: + case MONO_TYPE_I2: + case MONO_TYPE_U2: + size = 2; break; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + case MONO_TYPE_R4: + size = 4; break; + case MONO_TYPE_R8: +#ifdef ARM_FPU_FPA + return NULL; /* stupid ARM FP swapped format */ +#endif + case MONO_TYPE_I8: + case MONO_TYPE_U8: + size = 8; break; +#endif + default: + return NULL; + } + size *= newarr->inst_newa_len->inst_c0; + *out_size = size; + /*g_print ("optimized in %s: size: %d, numelems: %d\n", method->name, size, newarr->inst_newa_len->inst_c0);*/ + field_index = read32 (ip + 2) & 0xffffff; + mono_metadata_field_info (method->klass->image, field_index - 1, NULL, &rva, NULL); + data_ptr = mono_image_rva_map (method->klass->image, rva); + /*g_print ("field: 0x%08x, rva: %d, rva_ptr: %p\n", read32 (ip + 2), rva, data_ptr);*/ + /* for aot code we do the lookup on load */ + if (aot && data_ptr) + return GUINT_TO_POINTER (rva); + return data_ptr; + } + return NULL; +} + /* * mono_method_to_ir: translates IL into basic blocks containing trees */ @@ -3831,7 +3968,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b mono_jit_stats.cil_code_size += header->code_size; if (sig->is_inflated) - generic_context = ((MonoMethodInflated *) method)->context; + generic_context = mono_method_get_context (method); else if (generic_container) generic_context = &generic_container->context; @@ -4247,6 +4384,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b ins->cil_code = ip; if (!dont_verify_stloc && target_type_is_incompatible (cfg, param_types [ip [1]], *sp)) UNVERIFIED; + STARG_SOFT_FLOAT (cfg, ins, ip [1], ip); if (ins->opcode == CEE_STOBJ) { NEW_ARGLOADA (cfg, ins, ip [1]); handle_stobj (cfg, bblock, ins, *sp, ip, ins->klass, FALSE, FALSE, FALSE); @@ -4487,6 +4625,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } else if (constrained_call) { cmethod = mono_get_method_constrained (image, token, constrained_call, generic_context, &cil_method); cmethod = mono_get_inflated_method (cmethod); + cil_method = cmethod; } else { cmethod = mini_get_method (method, token, NULL, generic_context); cil_method = cmethod; @@ -4607,7 +4746,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b NEW_TEMPLOAD (cfg, iargs [0], this_temp->inst_c0); NEW_PCONST (cfg, iargs [1], cmethod); - NEW_PCONST (cfg, iargs [2], ((MonoMethodInflated *) cmethod)->context); + NEW_PCONST (cfg, iargs [2], mono_method_get_context (cmethod)); NEW_TEMPLOADA (cfg, iargs [3], this_arg_temp->inst_c0); temp = mono_emit_jit_icall (cfg, bblock, mono_helper_compile_generic_method, iargs, ip); @@ -5412,6 +5551,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b n = read32 (ip + 1); if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) { + /* FIXME: moving GC */ NEW_PCONST (cfg, ins, mono_method_get_wrapper_data (method, n)); ins->cil_code = ip; ins->type = STACK_OBJ; @@ -6314,6 +6454,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b link_bblock (cfg, bblock, tblock); CHECK_BBLOCK (target, ip, tblock); ins->inst_target_bb = tblock; + GET_BBLOCK (cfg, bbhash, tblock, ip); + link_bblock (cfg, bblock, tblock); if (sp != stack_start) { handle_stack_args (cfg, bblock, stack_start, sp - stack_start); sp = stack_start; @@ -6351,7 +6493,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b ins->inst_newa_class = klass; ins->inst_newa_len = *sp; ins->type = STACK_OBJ; - ins->klass = klass; + ins->klass = mono_array_class_get (klass, 1); ip += 5; *sp++ = ins; /* @@ -6360,11 +6502,40 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b */ if (1) { MonoInst *store, *temp, *load; + const char *data_ptr; + int data_size = 0; --sp; temp = mono_compile_create_var (cfg, type_from_stack_type (ins), OP_LOCAL); NEW_TEMPSTORE (cfg, store, temp->inst_c0, ins); store->cil_code = ins->cil_code; MONO_ADD_INS (bblock, store); + /* + * we inline/optimize the initialization sequence if possible. + * we should also allocate the array as not cleared, since we spend as much time clearing to 0 as initializing + * for small sizes open code the memcpy + * ensure the rva field is big enough + */ + if ((cfg->opt & MONO_OPT_INTRINS) && ip_in_bb (cfg, bblock, ip + 6) && (data_ptr = initialize_array_data (method, cfg->compile_aot, ip, ins, &data_size))) { + MonoMethod *memcpy_method = get_memcpy_method (); + MonoInst *data_offset, *add; + MonoInst *iargs [3]; + NEW_ICONST (cfg, iargs [2], data_size); + NEW_TEMPLOAD (cfg, load, temp->inst_c0); + load->cil_code = ins->cil_code; + NEW_ICONST (cfg, data_offset, G_STRUCT_OFFSET (MonoArray, vector)); + MONO_INST_NEW (cfg, add, OP_PADD); + add->inst_left = load; + add->inst_right = data_offset; + add->cil_code = ip; + iargs [0] = add; + if (cfg->compile_aot) { + NEW_AOTCONST_TOKEN (cfg, iargs [1], MONO_PATCH_INFO_RVA, method->klass->image, GPOINTER_TO_UINT(data_ptr), STACK_PTR, NULL); + } else { + NEW_PCONST (cfg, iargs [1], (char*)data_ptr); + } + mono_emit_method_call_spilled (cfg, bblock, memcpy_method, memcpy_method->signature, iargs, ip, NULL); + ip += 11; + } NEW_TEMPLOAD (cfg, load, temp->inst_c0); load->cil_code = ins->cil_code; *sp++ = load; @@ -6397,6 +6568,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b */ if (!klass->valuetype && method->wrapper_type == MONO_WRAPPER_NONE) { MonoInst* check; + + /* Needed by the code generated in inssel.brg */ + mono_get_got_var (cfg); + MONO_INST_NEW (cfg, check, OP_CHECK_ARRAY_TYPE); check->cil_code = ip; check->klass = klass; @@ -6454,7 +6629,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b sp -= 2; if (sp [0]->type != STACK_OBJ) UNVERIFIED; - klass = array_access_to_klass (*ip); + klass = array_access_to_klass (*ip, sp [0]); NEW_LDELEMA (cfg, load, sp, klass); load->cil_code = ip; #ifdef MONO_ARCH_SOFT_FLOAT @@ -6493,7 +6668,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b sp -= 3; if (sp [0]->type != STACK_OBJ) UNVERIFIED; - klass = array_access_to_klass (*ip); + klass = array_access_to_klass (*ip, sp [0]); NEW_LDELEMA (cfg, load, sp, klass); load->cil_code = ip; #ifdef MONO_ARCH_SOFT_FLOAT @@ -7192,6 +7367,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b ins->cil_code = ip; if (!dont_verify_stloc && target_type_is_incompatible (cfg, param_types [n], *sp)) UNVERIFIED; + STARG_SOFT_FLOAT (cfg, ins, n, ip); if (ins->opcode == CEE_STOBJ) { NEW_ARGLOADA (cfg, ins, n); handle_stobj (cfg, bblock, ins, *sp, ip, ins->klass, FALSE, FALSE, FALSE); @@ -8040,15 +8216,28 @@ mono_dynamic_code_hash_lookup (MonoDomain *domain, MonoMethod *method) typedef struct { MonoClass *vtype; GList *active; - GList *slots; + GSList *slots; } StackSlotInfo; +static inline GSList* +g_slist_prepend_mempool (MonoMemPool *mp, GSList *list, + gpointer data) +{ + GSList *new_list; + + new_list = mono_mempool_alloc (mp, sizeof (GSList)); + new_list->data = data; + new_list->next = list; + + return new_list; +} + /* * mono_allocate_stack_slots_full: * * Allocate stack slots for all non register allocated variables using a * linear scan algorithm. - * Returns: an array of stack offsets which the caller should free. + * Returns: an array of stack offsets. * STACK_SIZE is set to the amount of stack space needed. * STACK_ALIGN is set to the alignment needed by the locals area. */ @@ -8065,11 +8254,11 @@ mono_allocate_stack_slots_full (MonoCompile *m, gboolean backward, guint32 *stac MonoType *t; int nvtypes; - scalar_stack_slots = g_new0 (StackSlotInfo, MONO_TYPE_PINNED); - vtype_stack_slots = g_new0 (StackSlotInfo, 256); + scalar_stack_slots = mono_mempool_alloc0 (m->mempool, sizeof (StackSlotInfo) * MONO_TYPE_PINNED); + vtype_stack_slots = NULL; nvtypes = 0; - offsets = g_new (gint32, m->num_varinfo); + offsets = mono_mempool_alloc (m->mempool, sizeof (gint32) * m->num_varinfo); for (i = 0; i < m->num_varinfo; ++i) offsets [i] = -1; @@ -8113,6 +8302,8 @@ mono_allocate_stack_slots_full (MonoCompile *m, gboolean backward, guint32 *stac } /* Fall through */ case MONO_TYPE_VALUETYPE: + if (!vtype_stack_slots) + vtype_stack_slots = mono_mempool_alloc0 (m->mempool, sizeof (StackSlotInfo) * 256); for (i = 0; i < nvtypes; ++i) if (t->data.klass == vtype_stack_slots [i].vtype) break; @@ -8125,6 +8316,22 @@ mono_allocate_stack_slots_full (MonoCompile *m, gboolean backward, guint32 *stac nvtypes ++; } break; + case MONO_TYPE_CLASS: + case MONO_TYPE_OBJECT: + case MONO_TYPE_ARRAY: + case MONO_TYPE_SZARRAY: + case MONO_TYPE_STRING: + case MONO_TYPE_PTR: + case MONO_TYPE_I: + case MONO_TYPE_U: +#if SIZEOF_VOID_P == 4 + case MONO_TYPE_I4: +#else + case MONO_TYPE_I8: +#endif + /* Share non-float stack slots of the same size */ + slot_info = &scalar_stack_slots [MONO_TYPE_CLASS]; + break; default: slot_info = &scalar_stack_slots [t->type]; } @@ -8144,7 +8351,7 @@ mono_allocate_stack_slots_full (MonoCompile *m, gboolean backward, guint32 *stac //printf ("EXPIR %2d %08x %08x C%d R%d\n", amv->idx, amv->range.first_use.abs_pos, amv->range.last_use.abs_pos, amv->spill_costs, amv->reg); slot_info->active = g_list_delete_link (slot_info->active, slot_info->active); - slot_info->slots = g_list_prepend (slot_info->slots, GINT_TO_POINTER (offsets [amv->idx])); + slot_info->slots = g_slist_prepend_mempool (m->mempool, slot_info->slots, GINT_TO_POINTER (offsets [amv->idx])); } /* @@ -8159,7 +8366,7 @@ mono_allocate_stack_slots_full (MonoCompile *m, gboolean backward, guint32 *stac if (slot_info->slots) { slot = GPOINTER_TO_INT (slot_info->slots->data); - slot_info->slots = g_list_delete_link (slot_info->slots, slot_info->slots); + slot_info->slots = slot_info->slots->next; } slot_info->active = mono_varlist_insert_sorted (m, slot_info->active, vmv, TRUE); @@ -8210,15 +8417,15 @@ mono_allocate_stack_slots_full (MonoCompile *m, gboolean backward, guint32 *stac } g_list_free (vars); for (i = 0; i < MONO_TYPE_PINNED; ++i) { - g_list_free (scalar_stack_slots [i].active); - g_list_free (scalar_stack_slots [i].slots); + if (scalar_stack_slots [i].active) + g_list_free (scalar_stack_slots [i].active); } for (i = 0; i < nvtypes; ++i) { - g_list_free (vtype_stack_slots [i].active); - g_list_free (vtype_stack_slots [i].slots); + if (vtype_stack_slots [i].active) + g_list_free (vtype_stack_slots [i].active); } - g_free (scalar_stack_slots); - g_free (vtype_stack_slots); + + mono_jit_stats.locals_stack_size += offset; *stack_size = offset; return offsets; @@ -8717,6 +8924,7 @@ mono_patch_info_dup_mp (MonoMemPool *mp, MonoJumpInfo *patch_info) memcpy (res, patch_info, sizeof (MonoJumpInfo)); switch (patch_info->type) { + case MONO_PATCH_INFO_RVA: case MONO_PATCH_INFO_LDSTR: case MONO_PATCH_INFO_TYPE_FROM_HANDLE: case MONO_PATCH_INFO_LDTOKEN: @@ -8741,6 +8949,7 @@ mono_patch_info_hash (gconstpointer data) const MonoJumpInfo *ji = (MonoJumpInfo*)data; switch (ji->type) { + case MONO_PATCH_INFO_RVA: case MONO_PATCH_INFO_LDSTR: case MONO_PATCH_INFO_TYPE_FROM_HANDLE: case MONO_PATCH_INFO_LDTOKEN: @@ -8768,6 +8977,7 @@ mono_patch_info_equal (gconstpointer ka, gconstpointer kb) return 0; switch (ji1->type) { + case MONO_PATCH_INFO_RVA: case MONO_PATCH_INFO_LDSTR: case MONO_PATCH_INFO_TYPE_FROM_HANDLE: case MONO_PATCH_INFO_LDTOKEN: @@ -8885,6 +9095,9 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = (char*)vtable->data + patch_info->data.field->offset; break; } + case MONO_PATCH_INFO_RVA: + target = mono_image_rva_map (patch_info->data.token->image, patch_info->data.token->token); + break; case MONO_PATCH_INFO_R4: case MONO_PATCH_INFO_R8: target = patch_info->data.target; @@ -9830,8 +10043,7 @@ mini_select_instructions (MonoCompile *cfg) } emit_state (cfg, mbstate, MB_NTERM_stmt); } - bb->max_ireg = cfg->rs->next_vireg; - bb->max_freg = cfg->rs->next_vfreg; + bb->max_vreg = cfg->rs->next_vreg; if (bb->last_ins) bb->last_ins->next = NULL; @@ -10349,6 +10561,15 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool g_list_free (regs); } + /* todo: remove code when we have verified that the liveness for try/catch blocks + * works perfectly + */ + /* + * Currently, this can't be commented out since exception blocks are not + * processed during liveness analysis. + */ + mono_liveness_handle_exception_clauses (cfg); + if (cfg->opt & MONO_OPT_LINEARS) { GList *vars, *regs; @@ -10953,6 +11174,8 @@ SIG_HANDLER_SIGNATURE (sigsegv_signal_handler) mono_arch_handle_exception (ctx, exc, FALSE); } +#ifndef PLATFORM_WIN32 + static void SIG_HANDLER_SIGNATURE (sigabrt_signal_handler) { @@ -11022,6 +11245,16 @@ SIG_HANDLER_SIGNATURE (sigquit_signal_handler) mono_print_thread_dump (ctx); } +static void +SIG_HANDLER_SIGNATURE (sigusr2_signal_handler) +{ + gboolean enabled = mono_trace_is_enabled (); + + mono_trace_enable (!enabled); +} + +#endif + static void SIG_HANDLER_SIGNATURE (sigint_signal_handler) { @@ -11033,14 +11266,6 @@ SIG_HANDLER_SIGNATURE (sigint_signal_handler) mono_arch_handle_exception (ctx, exc, FALSE); } -static void -SIG_HANDLER_SIGNATURE (sigusr2_signal_handler) -{ - gboolean enabled = mono_trace_is_enabled (); - - mono_trace_enable (!enabled); -} - #ifdef PLATFORM_MACOSX /* @@ -11294,6 +11519,26 @@ enable_rtc_timer (gboolean enable) } #endif +#ifdef PLATFORM_WIN32 +static HANDLE win32_main_thread; +static MMRESULT win32_timer; + +static void CALLBACK +win32_time_proc (UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) +{ + CONTEXT context; + + context.ContextFlags = CONTEXT_CONTROL; + if (GetThreadContext (win32_main_thread, &context)) { +#ifdef _WIN64 + mono_profiler_stat_hit ((guchar *) context.Rip, &context); +#else + mono_profiler_stat_hit ((guchar *) context.Eip, &context); +#endif + } +} +#endif + static void setup_stat_profiler (void) { @@ -11346,6 +11591,27 @@ setup_stat_profiler (void) return; inited = 1; add_signal_handler (SIGPROF, sigprof_signal_handler); +#elif defined (PLATFORM_WIN32) + static int inited = 0; + TIMECAPS timecaps; + + if (inited) + return; + + inited = 1; + if (timeGetDevCaps (&timecaps, sizeof (timecaps)) != TIMERR_NOERROR) + return; + + if ((win32_main_thread = OpenThread (READ_CONTROL | THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId ())) == NULL) + return; + + if (timeBeginPeriod (1) != TIMERR_NOERROR) + return; + + if ((win32_timer = timeSetEvent (1, 0, win32_time_proc, 0, TIME_PERIODIC)) == 0) { + timeEndPeriod (1); + return; + } #endif } @@ -11730,7 +11996,8 @@ print_jit_stats (void) g_print ("Allocated code size: %ld\n", mono_jit_stats.allocated_code_size); g_print ("Inlineable methods: %ld\n", mono_jit_stats.inlineable_methods); g_print ("Inlined methods: %ld\n", mono_jit_stats.inlined_methods); - + g_print ("Locals stack size: %ld\n", mono_jit_stats.locals_stack_size); + g_print ("\nCreated object count: %ld\n", mono_stats.new_object_count); g_print ("Initialized classes: %ld\n", mono_stats.initialized_class_count); g_print ("Used classes: %ld\n", mono_stats.used_class_count);