#include <config.h>
#include <signal.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <math.h>
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
#ifdef PLATFORM_MACOSX
#include <mach/mach.h>
#define MONO_IS_COND_BRANCH_OP(ins) (((ins)->opcode >= CEE_BEQ && (ins)->opcode <= CEE_BLT_UN) || ((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))
#define MONO_IS_COND_BRANCH_NOFP(ins) (MONO_IS_COND_BRANCH_OP(ins) && (ins)->inst_left->inst_left->type != STACK_R8)
-#define MONO_IS_BRANCH_OP(ins) (MONO_IS_COND_BRANCH_OP(ins) || ((ins)->opcode == CEE_BR) || ((ins)->opcode == OP_BR_REG) || ((ins)->opcode == CEE_SWITCH))
+#define MONO_IS_BRANCH_OP(ins) (MONO_IS_COND_BRANCH_OP(ins) || ((ins)->opcode == OP_BR) || ((ins)->opcode == OP_BR_REG) || ((ins)->opcode == CEE_SWITCH))
#define MONO_CHECK_THIS(ins) (mono_method_signature (cfg->method)->hasthis && (ins)->ssa_op == MONO_SSA_LOAD && (ins)->inst_left->inst_c0 == 0)
* block_num: unique ID assigned at bblock creation
*/
#define NEW_BBLOCK(cfg) (mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoBasicBlock)))
-#define ADD_BBLOCK(cfg,bbhash,b) do { \
- g_hash_table_insert (bbhash, (b)->cil_code, (b)); \
+#define ADD_BBLOCK(cfg,b) do { \
+ cfg->cil_offset_to_bb [(b)->cil_code - cfg->cil_start] = (b); \
(b)->block_num = cfg->num_bblocks++; \
(b)->real_offset = real_offset; \
} while (0)
-#define GET_BBLOCK(cfg,bbhash,tblock,ip) do { \
- (tblock) = g_hash_table_lookup (bbhash, (ip)); \
+#define GET_BBLOCK(cfg,tblock,ip) do { \
+ (tblock) = cfg->cil_offset_to_bb [(ip) - cfg->cil_start]; \
if (!(tblock)) { \
if ((ip) >= end || (ip) < header->code) UNVERIFIED; \
(tblock) = NEW_BBLOCK (cfg); \
(tblock)->cil_code = (ip); \
- ADD_BBLOCK (cfg, (bbhash), (tblock)); \
+ ADD_BBLOCK (cfg, (tblock)); \
} \
} while (0)
ins->inst_i0 = cmp; \
MONO_ADD_INS (bblock, ins); \
ins->inst_many_bb = mono_mempool_alloc (cfg->mempool, sizeof(gpointer)*2); \
- GET_BBLOCK (cfg, bbhash, tblock, target); \
+ GET_BBLOCK (cfg, tblock, target); \
link_bblock (cfg, bblock, tblock); \
ins->inst_true_bb = tblock; \
CHECK_BBLOCK (target, ip, tblock); \
ins->inst_false_bb = (next_block); \
start_new_bblock = 1; \
} else { \
- GET_BBLOCK (cfg, bbhash, tblock, ip); \
+ GET_BBLOCK (cfg, tblock, ip); \
link_bblock (cfg, bblock, tblock); \
ins->inst_false_bb = tblock; \
start_new_bblock = 2; \
ins->opcode = (istrue)? CEE_BNE_UN: CEE_BEQ; \
MONO_ADD_INS (bblock, ins); \
ins->inst_many_bb = mono_mempool_alloc (cfg->mempool, sizeof(gpointer)*2); \
- GET_BBLOCK (cfg, bbhash, tblock, target); \
+ GET_BBLOCK (cfg, tblock, target); \
link_bblock (cfg, bblock, tblock); \
ins->inst_true_bb = tblock; \
CHECK_BBLOCK (target, ip, tblock); \
- GET_BBLOCK (cfg, bbhash, tblock, ip); \
+ GET_BBLOCK (cfg, tblock, ip); \
link_bblock (cfg, bblock, tblock); \
ins->inst_false_bb = tblock; \
start_new_bblock = 2; \
if (MONO_OFFSET_IN_CLAUSE (clause, (ip - header->code)) &&
(!MONO_OFFSET_IN_CLAUSE (clause, (target - header->code)))) {
if (clause->flags == type) {
- handler = g_hash_table_lookup (cfg->bb_hash, header->code + clause->handler_offset);
+ handler = cfg->cil_offset_to_bb [clause->handler_offset];
g_assert (handler);
res = g_list_append (res, handler);
}
}
}
-typedef struct {
- const guchar *code;
- MonoBasicBlock *best;
-} PrevStruct;
-
-static void
-previous_foreach (gconstpointer key, gpointer val, gpointer data)
+static MonoBasicBlock*
+find_previous (MonoBasicBlock **bblocks, guint32 n_bblocks, MonoBasicBlock *start, const guchar *code)
{
- PrevStruct *p = data;
- MonoBasicBlock *bb = val;
- //printf ("FIDPREV %d %p %p %p %p %p %d %d %d\n", bb->block_num, p->code, bb, p->best, bb->cil_code, p->best->cil_code,
- //bb->method == p->best->method, bb->cil_code < p->code, bb->cil_code > p->best->cil_code);
+ MonoBasicBlock *best = start;
+ int i;
- if (bb->cil_code && bb->cil_code < p->code && bb->cil_code > p->best->cil_code)
- p->best = bb;
-}
+ for (i = 0; i < n_bblocks; ++i) {
+ if (bblocks [i]) {
+ MonoBasicBlock *bb = bblocks [i];
-static MonoBasicBlock*
-find_previous (GHashTable *bb_hash, MonoBasicBlock *start, const guchar *code) {
- PrevStruct p;
-
- p.code = code;
- p.best = start;
+ if (bb->cil_code && bb->cil_code < code && bb->cil_code > best->cil_code)
+ best = bb;
+ }
+ }
- g_hash_table_foreach (bb_hash, (GHFunc)previous_foreach, &p);
- return p.best;
+ return best;
}
static void
ins->type = STACK_R8;
ins->opcode += unops_op_map [ins->inst_i0->type];
return;
- case CEE_CKFINITE:
+ case OP_CKFINITE:
ins->type = STACK_R8;
return;
case CEE_CONV_U2:
case CEE_BGT_UN:
case CEE_BLE_UN:
case CEE_BLT_UN:
- case CEE_BR:
+ case OP_BR:
case CEE_SWITCH:
prev = bb->code;
while (prev->next && prev->next != bb->last_ins)
}
}
-/*
- * We try to share variables when possible
- */
-static MonoInst *
-mono_compile_get_interface_var (MonoCompile *cfg, int slot, MonoInst *ins)
-{
- MonoInst *res;
- int pos, vnum;
-
- /* inlining can result in deeper stacks */
- if (slot >= mono_method_get_header (cfg->method)->max_stack)
- return mono_compile_create_var (cfg, type_from_stack_type (ins), OP_LOCAL);
-
- pos = ins->type - 1 + slot * STACK_MAX;
-
- switch (ins->type) {
- case STACK_I4:
- case STACK_I8:
- case STACK_R8:
- case STACK_PTR:
- case STACK_MP:
- case STACK_OBJ:
- if ((vnum = cfg->intvars [pos]))
- return cfg->varinfo [vnum];
- res = mono_compile_create_var (cfg, type_from_stack_type (ins), OP_LOCAL);
- cfg->intvars [pos] = res->inst_c0;
- break;
- default:
- res = mono_compile_create_var (cfg, type_from_stack_type (ins), OP_LOCAL);
- }
- return res;
-}
-
/*
* merge_stacks:
*
cfg->patch_info = ji;
}
+static void
+mono_save_token_info (MonoCompile *cfg, MonoImage *image, guint32 token, gpointer key)
+{
+ if (cfg->compile_aot) {
+ MonoJumpInfoToken *jump_info_token = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoJumpInfoToken));
+ jump_info_token->image = image;
+ jump_info_token->token = token;
+ g_hash_table_insert (cfg->token_info_hash, key, jump_info_token);
+ }
+}
+
/*
* When we add a tree of instructions, we need to ensure the instructions currently
* on the stack are executed before (like, if we load a value from a local).
{
int i;
for (i = 0; i < sig->param_count; ++i) {
- if (sig->params [i]->type == MONO_TYPE_R4) {
+ if (!sig->params [i]->byref && sig->params [i]->type == MONO_TYPE_R4) {
MonoInst *iargs [1];
int temp;
iargs [0] = args [i + sig->hasthis];
int temp; \
NEW_LOCLOADA (cfg, (ins), (idx)); \
handle_store_float (cfg, bblock, (ins), *sp, (ip)); \
- MONO_INST_NEW (cfg, (ins), CEE_NOP); \
+ MONO_INST_NEW (cfg, (ins), OP_NOP); \
} \
} while (0)
#define LDARG_SOFT_FLOAT(cfg,ins,idx,ip) do {\
int temp; \
NEW_ARGLOADA (cfg, (ins), (idx)); \
handle_store_float (cfg, bblock, (ins), *sp, (ip)); \
- MONO_INST_NEW (cfg, (ins), CEE_NOP); \
+ MONO_INST_NEW (cfg, (ins), OP_NOP); \
} \
} while (0)
#else
}
#ifdef MONO_ARCH_SOFT_FLOAT
/* this complicates things, fix later */
- if (signature->params [i]->type == MONO_TYPE_R4)
+ if (!signature->params [i]->byref && signature->params [i]->type == MONO_TYPE_R4)
return FALSE;
#endif
}
return NULL;
}
+static int
+is_signed_regsize_type (MonoType *type)
+{
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_I4:
+#if SIZEOF_VOID_P == 8
+ /*case MONO_TYPE_I8: this requires different opcodes in inssel.brg */
+#endif
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
static MonoInst*
mini_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
return ins;
#endif
} else if (strcmp (cmethod->name, ".ctor") == 0) {
- MONO_INST_NEW (cfg, ins, CEE_NOP);
+ MONO_INST_NEW (cfg, ins, OP_NOP);
return ins;
} else
return NULL;
store->inst_left = args [2];
store->inst_right = load;
return store;
+ } else if (cmethod->klass == mono_defaults.math_class) {
+ if (strcmp (cmethod->name, "Min") == 0) {
+ if (is_signed_regsize_type (fsig->params [0])) {
+ MONO_INST_NEW (cfg, ins, OP_MIN);
+ ins->inst_i0 = args [0];
+ ins->inst_i1 = args [1];
+ return ins;
+ }
+ } else if (strcmp (cmethod->name, "Max") == 0) {
+ if (is_signed_regsize_type (fsig->params [0])) {
+ MONO_INST_NEW (cfg, ins, OP_MAX);
+ ins->inst_i0 = args [0];
+ ins->inst_i1 = args [1];
+ return ins;
+ }
+ }
} else if (cmethod->klass->image == mono_defaults.corlib) {
if (cmethod->name [0] == 'B' && strcmp (cmethod->name, "Break") == 0
&& strcmp (cmethod->klass->name, "Debugger") == 0) {
- MONO_INST_NEW (cfg, ins, CEE_BREAK);
+ MONO_INST_NEW (cfg, ins, OP_BREAK);
return ins;
}
if (cmethod->name [0] == 'g' && strcmp (cmethod->name, "get_IsRunningOnWindows") == 0
MonoBasicBlock *ebblock, *sbblock;
int i, costs, new_locals_offset;
MonoMethod *prev_inlined_method;
+ MonoBasicBlock **prev_cil_offset_to_bb;
+ unsigned char* prev_cil_start;
+ guint32 prev_cil_offset_to_bb_len;
+
#if (MONO_INLINE_CALLED_LIMITED_METHODS)
if ((! inline_allways) && ! check_inline_called_method_name_limit (cmethod))
return 0;
prev_inlined_method = cfg->inlined_method;
cfg->inlined_method = cmethod;
+ prev_cil_offset_to_bb = cfg->cil_offset_to_bb;
+ prev_cil_offset_to_bb_len = cfg->cil_offset_to_bb_len;
+ prev_cil_start = cfg->cil_start;
costs = mono_method_to_ir (cfg, cmethod, sbblock, ebblock, new_locals_offset, rvar, dont_inline, sp, real_offset, *ip == CEE_CALLVIRT);
cfg->inlined_method = prev_inlined_method;
+ cfg->cil_offset_to_bb = prev_cil_offset_to_bb;
+ cfg->cil_offset_to_bb_len = prev_cil_offset_to_bb_len;
+ cfg->cil_start = prev_cil_start;
if ((costs >= 0 && costs < 60) || inline_allways) {
if (cfg->verbose_level > 2)
mono_jit_stats.inlined_methods++;
/* always add some code to avoid block split failures */
- MONO_INST_NEW (cfg, ins, CEE_NOP);
+ MONO_INST_NEW (cfg, ins, OP_NOP);
MONO_ADD_INS (bblock, ins);
ins->cil_code = ip;
* or through repeated runs where the compiler applies offline the optimizations to
* each method and then decides if it was worth it.
*
- * TODO:
- * * consider using an array instead of an hash table (bb_hash)
*/
#define CHECK_TYPE(ins) if (!(ins)->type) UNVERIFIED
/* offset from br.s -> br like opcodes */
#define BIG_BRANCH_OFFSET 13
-static gboolean
+static inline gboolean
ip_in_bb (MonoCompile *cfg, MonoBasicBlock *bb, const guint8* ip)
{
- MonoBasicBlock *b = g_hash_table_lookup (cfg->bb_hash, ip);
+ MonoBasicBlock *b = cfg->cil_offset_to_bb [ip - cfg->cil_start];
return b == NULL || b == bb;
}
static int
-get_basic_blocks (MonoCompile *cfg, GHashTable *bbhash, MonoMethodHeader* header, guint real_offset, unsigned char *start, unsigned char *end, unsigned char **pos)
+get_basic_blocks (MonoCompile *cfg, MonoMethodHeader* header, guint real_offset, unsigned char *start, unsigned char *end, unsigned char **pos)
{
unsigned char *ip = start;
unsigned char *target;
break;
case MonoShortInlineBrTarget:
target = start + cli_addr + 2 + (signed char)ip [1];
- GET_BBLOCK (cfg, bbhash, bblock, target);
+ GET_BBLOCK (cfg, bblock, target);
ip += 2;
if (ip < end)
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
break;
case MonoInlineBrTarget:
target = start + cli_addr + 5 + (gint32)read32 (ip + 1);
- GET_BBLOCK (cfg, bbhash, bblock, target);
+ GET_BBLOCK (cfg, bblock, target);
ip += 5;
if (ip < end)
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
break;
case MonoInlineSwitch: {
guint32 n = read32 (ip + 1);
ip += 5;
cli_addr += 5 + 4 * n;
target = start + cli_addr;
- GET_BBLOCK (cfg, bbhash, bblock, target);
+ GET_BBLOCK (cfg, bblock, target);
for (j = 0; j < n; ++j) {
target = start + cli_addr + (gint32)read32 (ip);
- GET_BBLOCK (cfg, bbhash, bblock, target);
+ GET_BBLOCK (cfg, bblock, target);
ip += 4;
}
break;
/* Find the start of the bblock containing the throw */
bblock = NULL;
while ((bb_start >= start) && !bblock) {
- bblock = g_hash_table_lookup (bbhash, (bb_start));
+ bblock = cfg->cil_offset_to_bb [(bb_start) - start];
bb_start --;
}
if (bblock)
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) {
/* same compilation unit */
return access_klass->image == member_klass->image;
case FIELD_ATTRIBUTE_PRIVATE:
- if (access_klass->generic_class && member_klass->generic_class && member_klass->generic_class->container_class)
- return member_klass->generic_class->container_class == access_klass->generic_class->container_class;
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:
if (newarr->inst_newa_len->opcode != OP_ICONST)
return NULL;
cmethod = mini_get_method (method, token, NULL, NULL);
+ if (!cmethod)
+ return 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) {
MonoInst *zero_int32, *zero_int64, *zero_ptr, *zero_obj, *zero_r8;
MonoInst *ins, **sp, **stack_start;
MonoBasicBlock *bblock, *tblock = NULL, *init_localsbb = NULL;
- GHashTable *bbhash;
MonoMethod *cmethod;
MonoInst **arg_array;
MonoMethodHeader *header;
sig = mono_method_signature (method);
num_args = sig->hasthis + sig->param_count;
ip = (unsigned char*)header->code;
+ cfg->cil_start = ip;
end = ip + header->code_size;
mono_jit_stats.cil_code_size += header->code_size;
g_assert (!sig->has_type_parameters);
- if (cfg->method == method) {
+ if (cfg->method == method)
real_offset = 0;
- bbhash = cfg->bb_hash;
- } else {
+ else
real_offset = inline_offset;
- bbhash = g_hash_table_new (g_direct_hash, NULL);
- }
+
+ cfg->cil_offset_to_bb = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoBasicBlock*) * header->code_size);
+ cfg->cil_offset_to_bb_len = header->code_size;
if (cfg->verbose_level > 2)
g_print ("method to IR %s\n", mono_method_full_name (method, TRUE));
for (i = 0; i < header->num_clauses; ++i) {
MonoBasicBlock *try_bb;
MonoExceptionClause *clause = &header->clauses [i];
- GET_BBLOCK (cfg, bbhash, try_bb, ip + clause->try_offset);
+ GET_BBLOCK (cfg, try_bb, ip + clause->try_offset);
try_bb->real_offset = clause->try_offset;
- GET_BBLOCK (cfg, bbhash, tblock, ip + clause->handler_offset);
+ GET_BBLOCK (cfg, tblock, ip + clause->handler_offset);
tblock->real_offset = clause->handler_offset;
tblock->flags |= BB_EXCEPTION_HANDLER;
MONO_ADD_INS (tblock, dummy_use);
if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
- GET_BBLOCK (cfg, bbhash, tblock, ip + clause->data.filter_offset);
+ GET_BBLOCK (cfg, tblock, ip + clause->data.filter_offset);
tblock->real_offset = clause->data.filter_offset;
tblock->in_scount = 1;
tblock->in_stack = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*));
bblock = NEW_BBLOCK (cfg);
bblock->cil_code = ip;
- ADD_BBLOCK (cfg, bbhash, bblock);
+ ADD_BBLOCK (cfg, bblock);
if (cfg->method == method) {
breakpoint_id = mono_debugger_method_has_breakpoint (method);
if (breakpoint_id && (mono_debug_format != MONO_DEBUG_FORMAT_DEBUGGER)) {
- MONO_INST_NEW (cfg, ins, CEE_BREAK);
+ MONO_INST_NEW (cfg, ins, OP_BREAK);
MONO_ADD_INS (bblock, ins);
}
}
mono_emit_method_call_spilled (cfg, init_localsbb, secman->demandunmanaged, mono_method_signature (secman->demandunmanaged), NULL, ip, NULL);
}
- if (get_basic_blocks (cfg, bbhash, header, real_offset, ip, end, &err_pos)) {
+ if (get_basic_blocks (cfg, header, real_offset, ip, end, &err_pos)) {
ip = err_pos;
UNVERIFIED;
}
if (start_new_bblock == 2) {
g_assert (ip == tblock->cil_code);
} else {
- GET_BBLOCK (cfg, bbhash, tblock, ip);
+ GET_BBLOCK (cfg, tblock, ip);
}
bblock->next_bb = tblock;
bblock = tblock;
g_slist_free (class_inits);
class_inits = NULL;
} else {
- if ((tblock = g_hash_table_lookup (bbhash, ip)) && (tblock != bblock)) {
+ if ((tblock = cfg->cil_offset_to_bb [ip - cfg->cil_start]) && (tblock != bblock)) {
link_bblock (cfg, bblock, tblock);
if (sp != stack_start) {
handle_stack_args (cfg, bblock, stack_start, sp - stack_start);
switch (*ip) {
case CEE_NOP:
+ MONO_INST_NEW (cfg, ins, OP_NOP);
+ ins->cil_code = ip++;
+ MONO_ADD_INS (bblock, ins);
+ break;
case CEE_BREAK:
- MONO_INST_NEW (cfg, ins, *ip);
+ MONO_INST_NEW (cfg, ins, OP_BREAK);
ins->cil_code = ip++;
MONO_ADD_INS (bblock, ins);
break;
CHECK_OPSIZE (5);
if (stack_start != sp)
UNVERIFIED;
- MONO_INST_NEW (cfg, ins, CEE_JMP);
+ MONO_INST_NEW (cfg, ins, OP_JMP);
token = read32 (ip + 1);
/* FIXME: check the signature matches */
cmethod = mini_get_method (method, token, NULL, generic_context);
fsig = mono_method_get_signature_full (cmethod, image, token, generic_context);
}
+ mono_save_token_info (cfg, image, token, cmethod);
+
n = fsig->param_count + fsig->hasthis;
if (mono_use_security_manager) {
this_arg_temp = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
this_arg_temp->cil_code = ip;
+ /* Because of the PCONST below */
+ cfg->disable_aot = TRUE;
NEW_TEMPLOAD (cfg, iargs [0], this_temp->inst_c0);
- NEW_PCONST (cfg, iargs [1], cmethod);
+ NEW_METHODCONST (cfg, iargs [1], cmethod);
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);
/* FIXME: This assumes the two methods has the same number and type of arguments */
/*
* We implement tail calls by storing the actual arguments into the
- * argument variables, then emitting a CEE_JMP. Since the actual arguments
+ * argument variables, then emitting a OP_JMP. Since the actual arguments
* can refer to the arg variables, we have to spill them.
*/
handle_loaded_temps (cfg, bblock, sp, sp + n);
else
MONO_ADD_INS (bblock, ins);
}
- MONO_INST_NEW (cfg, ins, CEE_JMP);
+ MONO_INST_NEW (cfg, ins, OP_JMP);
ins->cil_code = ip;
ins->inst_p0 = cmethod;
ins->inst_p1 = arg_array [0];
ip += 5;
real_offset += 5;
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
ebblock->next_bb = bblock;
link_bblock (cfg, ebblock, bblock);
ins->cil_code = ip;
MONO_ADD_INS (bblock, ins);
}
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
ins->cil_code = ip;
MONO_ADD_INS (bblock, ins);
tblock = start_bblock->out_bb [0];
g_assert (!return_var);
CHECK_STACK (1);
--sp;
- MONO_INST_NEW (cfg, ins, CEE_NOP);
+ MONO_INST_NEW (cfg, ins, OP_NOP);
ins->opcode = mono_type_to_stind (mono_method_signature (method)->ret);
if (ins->opcode == CEE_STOBJ) {
NEW_RETLOADA (cfg, ins);
}
if (sp != stack_start)
UNVERIFIED;
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
ins->cil_code = ip++;
ins->inst_target_bb = end_bblock;
MONO_ADD_INS (bblock, ins);
break;
case CEE_BR_S:
CHECK_OPSIZE (2);
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
ins->cil_code = ip++;
MONO_ADD_INS (bblock, ins);
target = ip + 1 + (signed char)(*ip);
++ip;
- GET_BBLOCK (cfg, bbhash, tblock, target);
+ GET_BBLOCK (cfg, tblock, target);
link_bblock (cfg, bblock, tblock);
CHECK_BBLOCK (target, ip, tblock);
ins->inst_target_bb = tblock;
break;
case CEE_BR:
CHECK_OPSIZE (5);
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
ins->cil_code = ip++;
MONO_ADD_INS (bblock, ins);
target = ip + 4 + (gint32)read32(ip);
ip += 4;
- GET_BBLOCK (cfg, bbhash, tblock, target);
+ GET_BBLOCK (cfg, tblock, target);
link_bblock (cfg, bblock, tblock);
CHECK_BBLOCK (target, ip, tblock);
ins->inst_target_bb = tblock;
CHECK_OPSIZE (n * sizeof (guint32));
target = ip + n * sizeof (guint32);
MONO_ADD_INS (bblock, ins);
- GET_BBLOCK (cfg, bbhash, tblock, target);
+ GET_BBLOCK (cfg, tblock, target);
link_bblock (cfg, bblock, tblock);
ins->klass = GUINT_TO_POINTER (n);
ins->inst_many_bb = mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (n + 1));
ins->inst_many_bb [n] = tblock;
for (i = 0; i < n; ++i) {
- GET_BBLOCK (cfg, bbhash, tblock, target + (gint32)read32(ip));
+ GET_BBLOCK (cfg, tblock, target + (gint32)read32(ip));
link_bblock (cfg, bblock, tblock);
ins->inst_many_bb [i] = tblock;
ip += 4;
MonoInst* domain_var;
if (cfg->compile_aot) {
+ /* FIXME: bug when inlining methods from different assemblies (n is a token valid just in one). */
cfg->ldstr_list = g_list_prepend (cfg->ldstr_list, GINT_TO_POINTER (n));
}
/* avoid depending on undefined C behavior in sequence points */
goto load_error;
fsig = mono_method_get_signature (cmethod, image, token);
+ mono_save_token_info (cfg, image, token, cmethod);
+
if (!mono_class_init (cmethod->klass))
goto load_error;
ip += 5;
real_offset += 5;
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
ebblock->next_bb = bblock;
link_bblock (cfg, ebblock, bblock);
ip += 5;
real_offset += 5;
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
ebblock->next_bb = bblock;
link_bblock (cfg, ebblock, bblock);
ip += 5;
real_offset += 5;
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
ebblock->next_bb = bblock;
link_bblock (cfg, ebblock, bblock);
ip += 5;
real_offset += 5;
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
ebblock->next_bb = bblock;
link_bblock (cfg, ebblock, bblock);
break;
case CEE_THROW:
CHECK_STACK (1);
- MONO_INST_NEW (cfg, ins, *ip);
+ MONO_INST_NEW (cfg, ins, OP_THROW);
--sp;
ins->inst_left = *sp;
ins->cil_code = ip++;
ip += 5;
real_offset += 5;
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
ebblock->next_bb = bblock;
link_bblock (cfg, ebblock, bblock);
ip += 5;
real_offset += 5;
- GET_BBLOCK (cfg, bbhash, bblock, ip);
+ GET_BBLOCK (cfg, bblock, ip);
ebblock->next_bb = bblock;
link_bblock (cfg, ebblock, bblock);
ins->cil_code = ip;
ins->inst_i0 = *sp;
ip += 5;
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
ins->cil_code = ip;
MONO_ADD_INS (bblock, ins);
if (*ip == CEE_BRTRUE_S) {
target = ip + 4 + (gint)(read32 (ip));
ip += 4;
}
- GET_BBLOCK (cfg, bbhash, tblock, target);
+ GET_BBLOCK (cfg, tblock, target);
link_bblock (cfg, bblock, tblock);
CHECK_BBLOCK (target, ip, tblock);
ins->inst_target_bb = tblock;
- GET_BBLOCK (cfg, bbhash, tblock, ip);
+ GET_BBLOCK (cfg, tblock, ip);
link_bblock (cfg, bblock, tblock);
if (sp != stack_start) {
handle_stack_args (cfg, bblock, stack_start, sp - stack_start);
CHECK_TYPELOAD (klass);
mono_class_init (klass);
if (MONO_TYPE_IS_REFERENCE (&klass->byval_arg)) {
- MonoMethod* helper = mono_marshal_get_stelemref ();
- MonoInst *iargs [3];
- handle_loaded_temps (cfg, bblock, stack_start, sp);
+ /* storing a NULL doesn't need any of the complex checks in stelemref */
+ if (sp [2]->opcode == OP_PCONST && sp [2]->inst_p0 == NULL) {
+ MonoInst *load;
+ NEW_LDELEMA (cfg, load, sp, mono_defaults.object_class);
+ load->cil_code = ip;
+ MONO_INST_NEW (cfg, ins, stelem_to_stind [*ip - CEE_STELEM_I]);
+ ins->cil_code = ip;
+ ins->inst_left = load;
+ ins->inst_right = sp [2];
+ MONO_ADD_INS (bblock, ins);
+ } else {
+ MonoMethod* helper = mono_marshal_get_stelemref ();
+ MonoInst *iargs [3];
+ handle_loaded_temps (cfg, bblock, stack_start, sp);
- iargs [2] = sp [2];
- iargs [1] = sp [1];
- iargs [0] = sp [0];
-
- mono_emit_method_call_spilled (cfg, bblock, helper, mono_method_signature (helper), iargs, ip, NULL);
+ iargs [2] = sp [2];
+ iargs [1] = sp [1];
+ iargs [0] = sp [0];
+
+ mono_emit_method_call_spilled (cfg, bblock, helper, mono_method_signature (helper), iargs, ip, NULL);
+ }
} else {
NEW_LDELEMA (cfg, load, sp, klass);
load->cil_code = ip;
handle_loaded_temps (cfg, bblock, stack_start, sp);
- iargs [2] = sp [2];
- iargs [1] = sp [1];
- iargs [0] = sp [0];
+ /* storing a NULL doesn't need any of the complex checks in stelemref */
+ if (sp [2]->opcode == OP_PCONST && sp [2]->inst_p0 == NULL) {
+ MonoInst *load;
+ NEW_LDELEMA (cfg, load, sp, mono_defaults.object_class);
+ load->cil_code = ip;
+ MONO_INST_NEW (cfg, ins, stelem_to_stind [*ip - CEE_STELEM_I]);
+ ins->cil_code = ip;
+ ins->inst_left = load;
+ ins->inst_right = sp [2];
+ MONO_ADD_INS (bblock, ins);
+ } else {
+ iargs [2] = sp [2];
+ iargs [1] = sp [1];
+ iargs [0] = sp [0];
- mono_emit_method_call_spilled (cfg, bblock, helper, mono_method_signature (helper), iargs, ip, NULL);
-
- /*
- MonoInst *group;
- NEW_GROUP (cfg, group, sp [0], sp [1]);
- MONO_INST_NEW (cfg, ins, CEE_STELEM_REF);
- ins->cil_code = ip;
- ins->inst_left = group;
- ins->inst_right = sp [2];
- MONO_ADD_INS (bblock, ins);
- */
+ mono_emit_method_call_spilled (cfg, bblock, helper, mono_method_signature (helper), iargs, ip, NULL);
+ inline_costs += 1;
+ }
++ip;
- inline_costs += 1;
break;
}
case CEE_CKFINITE: {
* this check */
- MONO_INST_NEW (cfg, ins, CEE_CKFINITE);
+ MONO_INST_NEW (cfg, ins, OP_CKFINITE);
ins->cil_code = ip;
ins->inst_left = sp [-1];
temp = mono_compile_create_var (cfg, &mono_defaults.double_class->byval_arg, OP_LOCAL);
ip++;
break;
case CEE_ENDFINALLY:
- MONO_INST_NEW (cfg, ins, *ip);
+ MONO_INST_NEW (cfg, ins, OP_ENDFINALLY);
MONO_ADD_INS (bblock, ins);
ins->cil_code = ip++;
start_new_bblock = 1;
g_list_free (handlers);
}
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
ins->cil_code = ip;
MONO_ADD_INS (bblock, ins);
- GET_BBLOCK (cfg, bbhash, tblock, target);
+ GET_BBLOCK (cfg, tblock, target);
link_bblock (cfg, bblock, tblock);
CHECK_BBLOCK (target, ip, tblock);
ins->inst_target_bb = tblock;
if (sp != stack_start)
UNVERIFIED;
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
ins->cil_code = ip;
ins->inst_target_bb = end_bblock;
MONO_ADD_INS (bblock, ins);
for (tmp = bb_recheck; tmp; tmp = tmp->next) {
bblock = tmp->data;
/*g_print ("need recheck in %s at IL_%04x\n", method->name, bblock->cil_code - header->code);*/
- tblock = find_previous (bbhash, start_bblock, bblock->cil_code);
+ tblock = find_previous (cfg->cil_offset_to_bb, header->code_size, start_bblock, bblock->cil_code);
if (tblock != start_bblock) {
int l;
split_bblock (cfg, tblock, bblock);
if (cfg->verbose_level > 2)
g_print ("REGION BB%d IL_%04x ID_%08X\n", bb->block_num, bb->real_offset, bb->region);
}
- } else {
- g_hash_table_destroy (bbhash);
}
g_slist_free (class_inits);
return inline_costs;
inline_failure:
- if (cfg->method != method)
- g_hash_table_destroy (bbhash);
g_slist_free (class_inits);
dont_inline = g_list_remove (dont_inline, method);
return -1;
load_error:
- if (cfg->method != method)
- g_hash_table_destroy (bbhash);
g_slist_free (class_inits);
dont_inline = g_list_remove (dont_inline, method);
cfg->exception_type = MONO_EXCEPTION_TYPE_LOAD;
return -1;
unverified:
- if (cfg->method != method)
- g_hash_table_destroy (bbhash);
g_slist_free (class_inits);
dont_inline = g_list_remove (dont_inline, method);
cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
}
case OP_RENAME:
case OP_RETARG:
- case CEE_NOP:
- case CEE_JMP:
- case CEE_BREAK:
+ case OP_NOP:
+ case OP_JMP:
+ case OP_BREAK:
break;
case OP_LOAD_MEMBASE:
case OP_LOADI4_MEMBASE:
case OP_LOADI2_MEMBASE:
printf ("[%s] <- [%s + 0x%x]", mono_arch_regname (tree->dreg), mono_arch_regname (tree->inst_basereg), (int)tree->inst_offset);
break;
- case CEE_BR:
+ case OP_BR:
case OP_CALL_HANDLER:
printf ("[B%d]", tree->inst_target_bb->block_num);
break;
#endif
static gpointer
-mono_create_delegate_trampoline (MonoMethod *method, gpointer addr)
+mono_create_delegate_trampoline (MonoClass *klass)
{
#ifdef MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
+ MonoDomain *domain = mono_domain_get ();
gpointer code, ptr;
guint32 code_size;
- MonoDomain *domain = mono_domain_get ();
-
-#ifndef __ia64__
- code = mono_jit_find_compiled_method (domain, method);
- if (code)
- return code;
-#else
- /*
- * FIXME: We should return a function descriptor here but it is not stored
- * anywhere so it would be leaked.
- */
-#endif
mono_domain_lock (domain);
- ptr = g_hash_table_lookup (domain->delegate_trampoline_hash, method);
+ ptr = g_hash_table_lookup (domain->delegate_trampoline_hash, klass);
mono_domain_unlock (domain);
if (ptr)
return ptr;
- code = mono_arch_create_specific_trampoline (method, MONO_TRAMPOLINE_DELEGATE, domain, &code_size);
+ code = mono_arch_create_specific_trampoline (klass, MONO_TRAMPOLINE_DELEGATE, mono_domain_get (), &code_size);
ptr = mono_create_ftnptr (domain, code);
/* store trampoline address */
mono_domain_lock (domain);
g_hash_table_insert (domain->delegate_trampoline_hash,
- method, ptr);
+ klass, ptr);
mono_domain_unlock (domain);
return ptr;
#else
- return addr;
+ return NULL;
#endif
}
mono_destroy_compile (MonoCompile *cfg)
{
//mono_mempool_stats (cfg->mempool);
- g_hash_table_destroy (cfg->bb_hash);
mono_free_loop_info (cfg);
if (cfg->rs)
mono_regstate_free (cfg->rs);
g_hash_table_destroy (cfg->exvars);
mono_mempool_destroy (cfg->mempool);
g_list_free (cfg->ldstr_list);
+ g_hash_table_destroy (cfg->token_info_hash);
g_free (cfg->varinfo);
g_free (cfg->vars);
}
if (bb->last_ins != NULL) {
switch (bb->last_ins->opcode) {
- case CEE_BR:
+ case OP_BR:
if (bb->last_ins->inst_target_bb == orig) {
bb->last_ins->inst_target_bb = repl;
}
for (inst = bb->code; inst != NULL; inst = inst->next) {
switch (inst->opcode) {
- case CEE_NOP:
+ case OP_NOP:
break;
- case CEE_BR:
+ case OP_BR:
target_bb = inst->inst_target_bb;
break;
default:
if ((previous_bb != cfg->bb_entry) &&
(previous_bb->region == bb->region) &&
((previous_bb->last_ins == NULL) ||
- ((previous_bb->last_ins->opcode != CEE_BR) &&
+ ((previous_bb->last_ins->opcode != OP_BR) &&
(! (MONO_IS_COND_BRANCH_OP (previous_bb->last_ins))) &&
(previous_bb->last_ins->opcode != CEE_SWITCH)))) {
for (i = 0; i < previous_bb->out_count; i++) {
if (previous_bb->out_bb [i] == target_bb) {
MonoInst *jump;
- MONO_INST_NEW (cfg, jump, CEE_BR);
+ MONO_INST_NEW (cfg, jump, OP_BR);
MONO_ADD_INS (previous_bb, jump);
jump->cil_code = previous_bb->cil_code;
jump->inst_target_bb = target_bb;
/* Nullify branch at the end of bb */
if (bb->last_ins && MONO_IS_BRANCH_OP (bb->last_ins)) {
- bb->last_ins->opcode = CEE_NOP;
+ bb->last_ins->opcode = OP_NOP;
}
if (bb->last_ins) {
if (next && (!bb->last_ins || (bb->last_ins->opcode != OP_NOT_REACHED))) {
MonoInst *ins;
- MONO_INST_NEW (cfg, ins, CEE_BR);
+ MONO_INST_NEW (cfg, ins, OP_BR);
MONO_ADD_INS (bb, ins);
link_bblock (cfg, bb, next);
ins->inst_target_bb = next;
return FALSE;
condb->opcode = get_unsigned_condbranch (condb->opcode);
/* change the original condbranch to just point to the new unsigned check */
- bb->last_ins->opcode = CEE_BR;
+ bb->last_ins->opcode = OP_BR;
bb->last_ins->inst_target_bb = falset;
replace_out_block (bb, truet, NULL);
replace_in_block (truet, bb, NULL);
if (bb->out_count == 1) {
bbn = bb->out_bb [0];
- /* conditional branches where true and false targets are the same can be also replaced with CEE_BR */
+ /* conditional branches where true and false targets are the same can be also replaced with OP_BR */
if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins)) {
MonoInst *pop;
MONO_INST_NEW (cfg, pop, CEE_POP);
MONO_INST_NEW (cfg, pop, CEE_POP);
pop->inst_left = bb->last_ins->inst_left->inst_right;
mono_add_ins_to_end (bb, pop);
- bb->last_ins->opcode = CEE_BR;
+ bb->last_ins->opcode = OP_BR;
bb->last_ins->inst_target_bb = bb->last_ins->inst_true_bb;
changed = TRUE;
if (cfg->verbose_level > 2)
/* the block are in sequence anyway ... */
/* branches to the following block can be removed */
- if (bb->last_ins && bb->last_ins->opcode == CEE_BR) {
- bb->last_ins->opcode = CEE_NOP;
+ if (bb->last_ins && bb->last_ins->opcode == OP_BR) {
+ bb->last_ins->opcode = OP_NOP;
changed = TRUE;
if (cfg->verbose_level > 2)
g_print ("br removal triggered %d -> %d\n", bb->block_num, bbn->block_num);
if (bb->out_count == 1) {
bbn = bb->out_bb [0];
- if (bb->last_ins && bb->last_ins->opcode == CEE_BR) {
+ if (bb->last_ins && bb->last_ins->opcode == OP_BR) {
bbn = bb->last_ins->inst_target_bb;
- if (bb->region == bbn->region && bbn->code && bbn->code->opcode == CEE_BR &&
+ if (bb->region == bbn->region && bbn->code && bbn->code->opcode == OP_BR &&
bbn->code->inst_target_bb->region == bb->region) {
if (cfg->verbose_level > 2)
/* if mono_eval_cond_branch () is ever taken to handle
* non-constant values to compare, issue a pop here.
*/
- bb->last_ins->opcode = CEE_BR;
+ bb->last_ins->opcode = OP_BR;
bb->last_ins->inst_target_bb = taken_branch_target;
mono_unlink_bblock (cfg, bb, untaken_branch_target);
changed = TRUE;
continue;
}
bbn = bb->last_ins->inst_true_bb;
- if (bb->region == bbn->region && bbn->code && bbn->code->opcode == CEE_BR &&
+ if (bb->region == bbn->region && bbn->code && bbn->code->opcode == OP_BR &&
bbn->code->inst_target_bb->region == bb->region) {
if (cfg->verbose_level > 2)
g_print ("cbranch1 to branch triggered %d -> (%d) %d (0x%02x)\n",
}
bbn = bb->last_ins->inst_false_bb;
- if (bb->region == bbn->region && bbn->code && bbn->code->opcode == CEE_BR &&
+ if (bb->region == bbn->region && bbn->code && bbn->code->opcode == OP_BR &&
bbn->code->inst_target_bb->region == bb->region) {
if (cfg->verbose_level > 2)
g_print ("cbranch2 to branch triggered %d -> (%d) %d (0x%02x)\n",
if (cfg->verbose_level > 2)
g_print ("creating vars\n");
+ cfg->args = mono_mempool_alloc0 (cfg->mempool, (sig->param_count + sig->hasthis) * sizeof (MonoInst*));
+
if (sig->hasthis)
- mono_compile_create_var (cfg, &cfg->method->klass->this_arg, OP_ARG);
+ cfg->args [0] = mono_compile_create_var (cfg, &cfg->method->klass->this_arg, OP_ARG);
for (i = 0; i < sig->param_count; ++i) {
- mono_compile_create_var (cfg, sig->params [i], OP_ARG);
+ cfg->args [i + sig->hasthis] = mono_compile_create_var (cfg, sig->params [i], OP_ARG);
if (sig->params [i]->byref) {
cfg->disable_ssa = TRUE;
}
bb->last_ins->opcode = reverse_branch_op (bb->last_ins->opcode);
} else {
MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
- inst->opcode = CEE_BR;
+ inst->opcode = OP_BR;
inst->inst_target_bb = bb->last_ins->inst_false_bb;
mono_bblock_add_inst (bb, inst);
}
if (previous_bb->region == bb->region) {
if (previous_bb != cfg->bb_entry) {
/* If previous_bb "followed through" to bb, */
- /* keep it linked with a CEE_BR */
+ /* keep it linked with a OP_BR */
if ((previous_bb->last_ins == NULL) ||
- ((previous_bb->last_ins->opcode != CEE_BR) &&
+ ((previous_bb->last_ins->opcode != OP_BR) &&
(! (MONO_IS_COND_BRANCH_OP (previous_bb->last_ins))) &&
(previous_bb->last_ins->opcode != CEE_SWITCH))) {
int i;
for (i = 0; i < previous_bb->out_count; i++) {
if (previous_bb->out_bb [i] == bb) {
MonoInst *jump;
- MONO_INST_NEW (cfg, jump, CEE_BR);
+ MONO_INST_NEW (cfg, jump, OP_BR);
MONO_ADD_INS (previous_bb, jump);
jump->cil_code = previous_bb->cil_code;
jump->inst_target_bb = bb;
}
} else {
/* We cannot add any inst to the entry BB, so we must */
- /* put a new BB in the middle to hold the CEE_BR */
+ /* put a new BB in the middle to hold the OP_BR */
MonoInst *jump;
MonoBasicBlock *new_bb_after_entry = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoBasicBlock));
new_bb_after_entry->block_num = cfg->num_bblocks++;
// new_bb_after_entry->real_offset = bb->real_offset;
new_bb_after_entry->region = bb->region;
- MONO_INST_NEW (cfg, jump, CEE_BR);
+ MONO_INST_NEW (cfg, jump, OP_BR);
MONO_ADD_INS (new_bb_after_entry, jump);
jump->cil_code = bb->cil_code;
jump->inst_target_bb = bb;
cfg->opt = opts;
cfg->prof_options = mono_profiler_get_events ();
cfg->run_cctors = run_cctors;
- cfg->bb_hash = g_hash_table_new (NULL, NULL);
cfg->domain = domain;
cfg->verbose_level = mini_verbose;
cfg->compile_aot = compile_aot;
cfg->skip_visibility = method->skip_visibility;
+ cfg->token_info_hash = g_hash_table_new (NULL, NULL);
if (!header) {
cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
cfg->exception_message = g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name);
ei->exvar_offset = exvar ? exvar->inst_offset : 0;
if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
- tblock = g_hash_table_lookup (cfg->bb_hash, ip + ec->data.filter_offset);
+ tblock = cfg->cil_offset_to_bb [ec->data.filter_offset];
g_assert (tblock);
ei->data.filter = cfg->native_code + tblock->native_offset;
} else {
ei->data.catch_class = ec->data.catch_class;
}
- tblock = g_hash_table_lookup (cfg->bb_hash, ip + ec->try_offset);
+ tblock = cfg->cil_offset_to_bb [ec->try_offset];
g_assert (tblock);
ei->try_start = cfg->native_code + tblock->native_offset;
g_assert (tblock->native_offset);
- tblock = g_hash_table_lookup (cfg->bb_hash, ip + ec->try_offset + ec->try_len);
+ tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len];
g_assert (tblock);
ei->try_end = cfg->native_code + tblock->native_offset;
g_assert (tblock->native_offset);
- tblock = g_hash_table_lookup (cfg->bb_hash, ip + ec->handler_offset);
+ tblock = cfg->cil_offset_to_bb [ec->handler_offset];
g_assert (tblock);
ei->handler_start = cfg->native_code + tblock->native_offset;
}
mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt)
{
MonoCompile *cfg;
- GHashTable *jit_code_hash;
gpointer code = NULL;
MonoJitInfo *info;
- jit_code_hash = target_domain->jit_code_hash;
-
method = mono_get_inflated_method (method);
#ifdef MONO_USE_AOT_COMPILER
/* Check if some other thread already did the job. In this case, we can
discard the code this thread generated. */
- if ((info = g_hash_table_lookup (target_domain->jit_code_hash, method))) {
+ if ((info = mono_internal_hash_table_lookup (&target_domain->jit_code_hash, method))) {
/* We can't use a domain specific method in another domain */
if ((target_domain == mono_domain_get ()) || info->domain_neutral) {
code = info->code_start;
}
if (code == NULL) {
- g_hash_table_insert (jit_code_hash, method, cfg->jit_info);
+ mono_internal_hash_table_insert (&target_domain->jit_code_hash, method, cfg->jit_info);
code = cfg->native_code;
}
mono_domain_lock (target_domain);
- if ((info = g_hash_table_lookup (target_domain->jit_code_hash, method))) {
+ if ((info = mono_internal_hash_table_lookup (&target_domain->jit_code_hash, method))) {
/* We can't use a domain specific method in another domain */
if (! ((domain != target_domain) && !info->domain_neutral)) {
mono_domain_unlock (target_domain);
return;
mono_domain_lock (domain);
g_hash_table_remove (domain->dynamic_code_hash, method);
- g_hash_table_remove (domain->jit_code_hash, method);
+ mono_internal_hash_table_remove (&domain->jit_code_hash, method);
g_hash_table_remove (domain->jump_trampoline_hash, method);
mono_domain_unlock (domain);
mono_domain_lock (target_domain);
- if ((info = g_hash_table_lookup (target_domain->jit_code_hash, method))) {
+ if ((info = mono_internal_hash_table_lookup (&target_domain->jit_code_hash, method))) {
/* We can't use a domain specific method in another domain */
if (! ((domain != target_domain) && !info->domain_neutral)) {
mono_domain_unlock (target_domain);
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
- if (GetThreadContext (win32_main_thread, &context))
+ 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