MonoClass *module_klass;
MonoVTable *module_vtable;
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_TYPE, "Running module .cctor for '%s'", image->name);
module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, error);
if (!module_klass) {
return FALSE;
if (do_initialization) {
MonoException *exc = NULL;
+ if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_TYPE)) {
+ char* type_name = mono_type_full_name (m_class_get_byval_arg (klass));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_TYPE, "Running class .cctor for %s from '%s'", type_name, m_class_get_image (klass)->name);
+ g_free (type_name);
+ }
/* We are holding the per-vtable lock, do the actual initialization */
mono_threads_begin_abort_protected_block ();
MINT_IN_BREAK;
}
+ MINT_IN_CASE(MINT_LDSFLD_W) {
+ MonoVTable *vtable = (MonoVTable*) frame->imethod->data_items [READ32 (ip + 2)];
+ INIT_VTABLE (vtable);
+ gpointer addr = frame->imethod->data_items [READ32 (ip + 4)];
+ MonoClass *klass = frame->imethod->data_items [READ32 (ip + 6)];
+ stackval_from_data (m_class_get_byval_arg (klass), (stackval*)(locals + ip [1]), addr, FALSE);
+ ip += 8;
+ MINT_IN_BREAK;
+ }
+
#define STSFLD(datatype, fieldtype) { \
MonoVTable *vtable = (MonoVTable*) frame->imethod->data_items [ip [2]]; \
INIT_VTABLE (vtable); \
MINT_IN_BREAK;
}
+ MINT_IN_CASE(MINT_STSFLD_W) {
+ MonoVTable *vtable = (MonoVTable*) frame->imethod->data_items [READ32 (ip + 2)];
+ INIT_VTABLE (vtable);
+ gpointer addr = frame->imethod->data_items [READ32 (ip + 4)];
+ MonoClass *klass = frame->imethod->data_items [READ32 (ip + 6)];
+ stackval_to_data (m_class_get_byval_arg (klass), (stackval*)(locals + ip [1]), addr, FALSE);
+ ip += 8;
+ MINT_IN_BREAK;
+ }
+
MINT_IN_CASE(MINT_STOBJ_VT) {
MonoClass *c = (MonoClass*)frame->imethod->data_items [ip [3]];
mono_value_copy_internal (LOCAL_VAR (ip [1], gpointer), locals + ip [2], c);
OPDEF(MINT_LDSFLD_R8, "ldsfld.r8", 4, 1, 0, MintOpUShortInt)
OPDEF(MINT_LDSFLD_O, "ldsfld.o", 4, 1, 0, MintOpUShortInt)
OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 5, 1, 0, MintOpTwoShorts)
+OPDEF(MINT_LDSFLD_W, "ldsfld.w", 8, 1, 0, MintOpTwoInts)
OPDEF(MINT_STSFLD_I1, "stsfld.i1", 4, 0, 1, MintOpUShortInt)
OPDEF(MINT_STSFLD_U1, "stsfld.u1", 4, 0, 1, MintOpUShortInt)
OPDEF(MINT_STSFLD_R8, "stsfld.r8", 4, 0, 1, MintOpUShortInt)
OPDEF(MINT_STSFLD_O, "stsfld.o", 4, 0, 1, MintOpUShortInt)
OPDEF(MINT_STSFLD_VT, "stsfld.vt", 5, 0, 1, MintOpTwoShorts)
+OPDEF(MINT_STSFLD_W, "stsfld.w", 8, 0, 1, MintOpTwoInts)
OPDEF(MINT_LDSFLDA, "ldsflda", 4, 1, 0, MintOpTwoShorts)
OPDEF(MINT_LDTSFLDA, "ldtsflda", 4, 1, 0, MintOpInt)
MintOpFieldToken,
MintOpClassToken,
MintOpTwoShorts,
+ MintOpTwoInts,
MintOpShortAndInt,
MintOpShortAndShortBranch,
MintOpPair2,
td->last_ins->data [0] = td->locals [local].size;
}
-static guint16
-get_data_item_index (TransformData *td, void *ptr)
+static guint32
+get_data_item_wide_index (TransformData *td, void *ptr)
{
gpointer p = g_hash_table_lookup (td->data_hash, ptr);
- guint index;
+ guint32 index;
if (p != NULL)
return GPOINTER_TO_UINT (p) - 1;
if (td->max_data_items == td->n_data_items) {
}
static guint16
+get_data_item_index (TransformData *td, void *ptr)
+{
+ guint32 index = get_data_item_wide_index (td, ptr);
+ g_assertf (index <= G_MAXUINT16, "Interpreter data item index 0x%x for method '%s' overflows", index, td->method->name);
+ return (guint16)index;
+}
+
+static gboolean
+is_data_item_wide_index (guint32 data_item_index)
+{
+ return data_item_index > G_MAXUINT16;
+}
+
+static guint16
get_data_item_index_nonshared (TransformData *td, void *ptr)
{
guint index;
case MintOpTwoShorts:
g_string_append_printf (str, " %u,%u", *(guint16*)data, *(guint16 *)(data + 1));
break;
+ case MintOpTwoInts:
+ g_string_append_printf (str, " %u,%u", (guint32)READ32(data), (guint32)READ32(data + 2));
+ break;
case MintOpShortAndInt:
g_string_append_printf (str, " %u,%u", *(guint16*)data, (guint32)READ32(data + 1));
break;
if (interp_emit_load_const (td, field_addr, mt))
return;
}
- if (mt == MINT_TYPE_VT) {
+ }
+ guint32 vtable_index = get_data_item_wide_index (td, vtable);
+ guint32 addr_index = get_data_item_wide_index (td, (char*)field_addr);
+ gboolean wide_data = is_data_item_wide_index (vtable_index) || is_data_item_wide_index (addr_index);
+ guint32 klass_index = !wide_data ? 0 : get_data_item_wide_index (td, field_class);
+ if (is_load) {
+ if (G_UNLIKELY (wide_data)) {
+ interp_add_ins (td, MINT_LDSFLD_W);
+ if (mt == MINT_TYPE_VT) {
+ push_type_vt (td, field_class, size);
+ } else {
+ push_type (td, stack_type [mt], field_class);
+ }
+ } else if (mt == MINT_TYPE_VT) {
interp_add_ins (td, MINT_LDSFLD_VT);
push_type_vt (td, field_class, size);
} else {
}
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
} else {
- interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSFLD_VT : (MINT_STSFLD_I1 + mt - MINT_TYPE_I1));
+ if (G_LIKELY (!wide_data))
+ interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSFLD_VT : (MINT_STSFLD_I1 + mt - MINT_TYPE_I1));
+ else
+ interp_add_ins (td, MINT_STSFLD_W);
td->sp--;
interp_ins_set_sreg (td->last_ins, td->sp [0].local);
}
- td->last_ins->data [0] = get_data_item_index (td, vtable);
- td->last_ins->data [1] = get_data_item_index (td, (char*)field_addr);
- if (mt == MINT_TYPE_VT)
- td->last_ins->data [2] = size;
+ if (G_LIKELY (!wide_data)) {
+ td->last_ins->data [0] = (guint16) vtable_index;
+ td->last_ins->data [1] = (guint16) addr_index;
+ if (mt == MINT_TYPE_VT)
+ td->last_ins->data [2] = size;
+ } else {
+ WRITE32_INS (td->last_ins, 0, &vtable_index);
+ WRITE32_INS (td->last_ins, 2, &addr_index);
+ WRITE32_INS (td->last_ins, 4, &klass_index);
+ }
}
}