return alloc_dreg (cfg, stack_type);
}
+/*
+ * mono_alloc_ireg_ref:
+ *
+ * Allocate an IREG, and mark it as holding a GC ref.
+ */
+guint32
+mono_alloc_ireg_ref (MonoCompile *cfg)
+{
+ return alloc_ireg_ref (cfg);
+}
+
+/*
+ * mono_alloc_ireg_mp:
+ *
+ * Allocate an IREG, and mark it as holding a managed pointer.
+ */
+guint32
+mono_alloc_ireg_mp (MonoCompile *cfg)
+{
+ return alloc_ireg_mp (cfg);
+}
+
+/*
+ * mono_alloc_ireg_copy:
+ *
+ * Allocate an IREG with the same GC type as VREG.
+ */
+guint32
+mono_alloc_ireg_copy (MonoCompile *cfg, guint32 vreg)
+{
+ if (vreg_is_ref (cfg, vreg))
+ return alloc_ireg_ref (cfg);
+ else if (vreg_is_mp (cfg, vreg))
+ return alloc_ireg_mp (cfg);
+ else
+ return alloc_ireg (cfg);
+}
+
guint
mono_type_to_regmove (MonoCompile *cfg, MonoType *type)
{
#if defined(TARGET_X86) || defined(TARGET_AMD64)
#define EMIT_NEW_X86_LEA(cfg,dest,sr1,sr2,shift,imm) do { \
MONO_INST_NEW (cfg, dest, OP_X86_LEA); \
- (dest)->dreg = alloc_preg ((cfg)); \
+ (dest)->dreg = alloc_ireg_mp ((cfg)); \
(dest)->sreg1 = (sr1); \
(dest)->sreg2 = (sr2); \
(dest)->inst_imm = (imm); \
return vtable_var;
} else {
MonoInst *ins;
- int vtable_reg, res_reg;
+ int vtable_reg;
vtable_reg = alloc_preg (cfg);
- res_reg = alloc_preg (cfg);
EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, vtable_reg, this->dreg, G_STRUCT_OFFSET (MonoObject, vtable));
return ins;
}
reset_cast_details (cfg);
}
- NEW_BIALU_IMM (cfg, add, OP_ADD_IMM, alloc_dreg (cfg, STACK_PTR), obj_reg, sizeof (MonoObject));
+ NEW_BIALU_IMM (cfg, add, OP_ADD_IMM, alloc_dreg (cfg, STACK_MP), obj_reg, sizeof (MonoObject));
MONO_ADD_INS (cfg->cbb, add);
add->type = STACK_MP;
add->klass = klass;
MonoBasicBlock *is_null_bb, *false_bb, *end_bb;
int obj_reg = src->dreg;
int vtable_reg = alloc_preg (cfg);
- int res_reg = alloc_preg (cfg);
+ int res_reg = alloc_ireg_ref (cfg);
MonoInst *klass_inst = NULL;
if (context_used) {
static const int fast_log2 [] = { 1, 0, 1, -1, 2, -1, -1, -1, 3 };
EMIT_NEW_X86_LEA (cfg, ins, array_reg, index2_reg, fast_log2 [size], G_STRUCT_OFFSET (MonoArray, vector));
- ins->type = STACK_PTR;
+ ins->klass = mono_class_get_element_class (klass);
+ ins->type = STACK_MP;
return ins;
}
#endif
- add_reg = alloc_preg (cfg);
+ add_reg = alloc_ireg_mp (cfg);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_MUL_IMM, mult_reg, index2_reg, size);
MONO_EMIT_NEW_BIALU (cfg, OP_PADD, add_reg, array_reg, mult_reg);
NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, add_reg, add_reg, G_STRUCT_OFFSET (MonoArray, vector));
- ins->type = STACK_PTR;
+ ins->klass = mono_class_get_element_class (klass);
+ ins->type = STACK_MP;
MONO_ADD_INS (cfg->cbb, ins);
return ins;
mini_emit_ldelema_2_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index_ins1, MonoInst *index_ins2)
{
int bounds_reg = alloc_preg (cfg);
- int add_reg = alloc_preg (cfg);
+ int add_reg = alloc_ireg_mp (cfg);
int mult_reg = alloc_preg (cfg);
int mult2_reg = alloc_preg (cfg);
int low1_reg = alloc_preg (cfg);
} else if (cmethod->klass == mono_defaults.object_class) {
if (strcmp (cmethod->name, "GetType") == 0) {
- int dreg = alloc_preg (cfg);
+ int dreg = alloc_ireg_ref (cfg);
int vt_reg = alloc_preg (cfg);
MONO_EMIT_NEW_LOAD_MEMBASE_FAULT (cfg, vt_reg, args [0]->dreg, G_STRUCT_OFFSET (MonoObject, vtable));
EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, dreg, vt_reg, G_STRUCT_OFFSET (MonoVTable, type));
*/
if ((strcmp (cmethod->name, "GetLength") == 0 || strcmp (cmethod->name, "GetLowerBound") == 0) && args [1]->opcode == OP_ICONST && args [1]->inst_c0 == 0) {
int dreg = alloc_ireg (cfg);
- int bounds_reg = alloc_ireg (cfg);
+ int bounds_reg = alloc_ireg_mp (cfg);
MonoBasicBlock *end_bb, *szarray_bb;
gboolean get_length = strcmp (cmethod->name, "GetLength") == 0;
return NULL;
MONO_INST_NEW (cfg, ins, opcode);
- ins->dreg = mono_alloc_ireg (cfg);
+ ins->dreg = is_ref ? mono_alloc_ireg_ref (cfg) : mono_alloc_ireg (cfg);
ins->inst_basereg = args [0]->dreg;
ins->inst_offset = 0;
ins->sreg2 = args [1]->dreg;
size = 8;
if (size == 4) {
MONO_INST_NEW (cfg, ins, OP_ATOMIC_CAS_I4);
- ins->dreg = alloc_ireg (cfg);
+ ins->dreg = is_ref ? alloc_ireg_ref (cfg) : alloc_ireg (cfg);
ins->sreg1 = args [0]->dreg;
ins->sreg2 = args [1]->dreg;
ins->sreg3 = args [2]->dreg;
MONO_ADD_INS (cfg->cbb, ins);
} else if (size == 8) {
MONO_INST_NEW (cfg, ins, OP_ATOMIC_CAS_I8);
- ins->dreg = alloc_ireg (cfg);
+ ins->dreg = is_ref ? alloc_ireg_ref (cfg) : alloc_ireg (cfg);
ins->sreg1 = args [0]->dreg;
ins->sreg2 = args [1]->dreg;
ins->sreg3 = args [2]->dreg;
dont_verify_stloc = method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE;
dont_verify_stloc |= method->wrapper_type == MONO_WRAPPER_UNKNOWN;
dont_verify_stloc |= method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED;
+ dont_verify_stloc |= method->wrapper_type == MONO_WRAPPER_STELEMREF;
image = method->klass->image;
header = mono_method_get_header (method);
sp [0] = handle_box (cfg, ins, constrained_call, mono_class_check_context_used (constrained_call));
CHECK_CFG_EXCEPTION;
} else if (!constrained_call->valuetype) {
- int dreg = alloc_preg (cfg);
+ int dreg = alloc_ireg_ref (cfg);
/*
* The type parameter is instantiated as a reference
case CEE_LDIND_I8:
dreg = alloc_lreg (cfg);
break;
+ case CEE_LDIND_REF:
+ dreg = alloc_ireg_ref (cfg);
+ break;
default:
dreg = alloc_preg (cfg);
}
sp -= 2;
if (generic_class_is_reference_type (cfg, klass)) {
MonoInst *store, *load;
- int dreg = alloc_preg (cfg);
+ int dreg = alloc_ireg_ref (cfg);
NEW_LOAD_MEMBASE (cfg, load, OP_LOAD_MEMBASE, dreg, sp [1]->dreg, 0);
load->flags |= ins_flag;
MonoInst *ptr;
int dreg;
- dreg = alloc_preg (cfg);
+ dreg = alloc_ireg_mp (cfg);
EMIT_NEW_BIALU_IMM (cfg, ptr, OP_PADD_IMM, dreg, sp [0]->dreg, foffset);
emit_write_barrier (cfg, ptr, sp [1], -1);
}
MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");
}
- dreg = alloc_preg (cfg);
+ dreg = alloc_ireg_mp (cfg);
EMIT_NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, dreg, sp [0]->dreg, foffset);
ins->klass = mono_class_from_mono_type (field->type);
CHECK_TYPELOAD (array_type);
MONO_INST_NEW (cfg, ins, OP_NEWARR);
- ins->dreg = alloc_preg (cfg);
+ ins->dreg = alloc_ireg_ref (cfg);
ins->sreg1 = sp [0]->dreg;
ins->inst_newa_class = klass;
ins->type = STACK_OBJ;
if ((cfg->opt & MONO_OPT_INTRINS) && ip + 6 < end && ip_in_bb (cfg, bblock, ip + 6) && (len_ins->opcode == OP_ICONST) && (data_ptr = initialize_array_data (method, cfg->compile_aot, ip, klass, len_ins->inst_c0, &data_size, &field_token))) {
MonoMethod *memcpy_method = get_memcpy_method ();
MonoInst *iargs [3];
- int add_reg = alloc_preg (cfg);
+ int add_reg = alloc_ireg_mp (cfg);
EMIT_NEW_BIALU_IMM (cfg, iargs [0], OP_PADD_IMM, add_reg, ins->dreg, G_STRUCT_OFFSET (MonoArray, vector));
if (cfg->compile_aot) {
if (sp [0]->type != STACK_OBJ)
UNVERIFIED;
- dreg = alloc_preg (cfg);
MONO_INST_NEW (cfg, ins, OP_LDLEN);
ins->dreg = alloc_preg (cfg);
ins->sreg1 = sp [0]->dreg;
CHECK_STACK (1);
--sp;
MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->dreg = alloc_preg (cfg);
+ ins->dreg = alloc_ireg_mp (cfg);
ins->sreg1 = sp [0]->dreg;
ins->type = STACK_MP;
MONO_ADD_INS (cfg->cbb, ins);
switch (regtype) {
case 'i':
- mono_compile_create_var_for_vreg (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL, vreg);
+ if (vreg_is_ref (cfg, vreg))
+ mono_compile_create_var_for_vreg (cfg, &mono_defaults.object_class->byval_arg, OP_LOCAL, vreg);
+ else
+ mono_compile_create_var_for_vreg (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL, vreg);
break;
case 'l':
mono_compile_create_var_for_vreg (cfg, &mono_defaults.int64_class->byval_arg, OP_LOCAL, vreg);
}
#endif
+ if (cfg->compute_gc_maps) {
+ /* registers need liveness info even for !non refs */
+ for (i = 0; i < cfg->num_varinfo; i++) {
+ MonoInst *ins = cfg->varinfo [i];
+
+ if (ins->opcode == OP_REGVAR)
+ ins->flags |= MONO_INST_GC_TRACK;
+ }
+ }
+
/* FIXME: widening and truncation */
/*
live_range_start [dreg] = def_ins;
live_range_start_bb [dreg] = bb;
}
+
+ if (cfg->compute_gc_maps && def_ins && (var->flags & MONO_INST_GC_TRACK)) {
+ MonoInst *tmp;
+
+ MONO_INST_NEW (cfg, tmp, OP_GC_LIVENESS_DEF);
+ tmp->inst_c1 = dreg;
+ mono_bblock_insert_after_ins (bb, def_ins, tmp);
+ }
}
/************/
//mono_inst_set_src_registers (ins, sregs);
live_range_end [sreg] = use_ins;
live_range_end_bb [sreg] = bb;
+
+ if (cfg->compute_gc_maps && var->dreg < orig_next_vreg && (var->flags & MONO_INST_GC_TRACK)) {
+ MonoInst *tmp;
+
+ MONO_INST_NEW (cfg, tmp, OP_GC_LIVENESS_USE);
+ /* var->dreg is a hreg */
+ tmp->inst_c1 = sreg;
+ mono_bblock_insert_after_ins (bb, ins, tmp);
+ }
+
continue;
}
live_range_end [var->dreg] = use_ins;
live_range_end_bb [var->dreg] = bb;
}
+
+ if (cfg->compute_gc_maps && var->dreg < orig_next_vreg && (var->flags & MONO_INST_GC_TRACK)) {
+ MonoInst *tmp;
+
+ MONO_INST_NEW (cfg, tmp, OP_GC_LIVENESS_USE);
+ tmp->inst_c1 = var->dreg;
+ mono_bblock_insert_after_ins (bb, ins, tmp);
+ }
}
}
mono_inst_set_src_registers (ins, sregs);