MINT_IN_BREAK;
}
- MINT_IN_CASE(MINT_LDSSFLD_SLOW)
- MINT_IN_CASE(MINT_LDSSFLD_VT_SLOW) {
- gboolean is_vt = *ip == MINT_LDSSFLD_VT_SLOW;
+#define LDTSFLD(datamem, fieldtype) { \
+ guint32 offset = READ32(ip + 1); \
+ MonoInternalThread *thread = mono_thread_internal_current (); \
+ gpointer addr = ((char*)thread->static_data [offset & 0x3f]) + (offset >> 6); \
+ sp[0].data.datamem = *(fieldtype*)addr; \
+ ip += 3; \
+ ++sp; \
+ }
+ MINT_IN_CASE(MINT_LDTSFLD_I1) LDTSFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_U1) LDTSFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_I2) LDTSFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_U2) LDTSFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_I4) LDTSFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_I8) LDTSFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_R4) LDTSFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_R8) LDTSFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_O) LDTSFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDTSFLD_P) LDTSFLD(p, gpointer); MINT_IN_BREAK;
+
+ MINT_IN_CASE(MINT_LDSSFLD) {
MonoClassField *field = (MonoClassField*)imethod->data_items [* (guint16 *)(ip + 1)];
- gpointer addr = mono_class_static_field_address (imethod->domain, field);
- EXCEPTION_CHECKPOINT;
- if (is_vt) {
- int size = READ32 (ip + 2);
- sp->data.p = vt_sp;
- vt_sp += ALIGN_TO (size, MINT_VT_ALIGNMENT);
- }
+ guint32 offset = READ32(ip + 2);
+ gpointer addr = mono_get_special_static_data (offset);
stackval_from_data (field->type, sp, addr, FALSE);
- ip += (is_vt ? 4 : 2);
+ ip += 4;
++sp;
MINT_IN_BREAK;
}
+ MINT_IN_CASE(MINT_LDSSFLD_VT) {
+ guint32 offset = READ32(ip + 1);
+ gpointer addr = mono_get_special_static_data (offset);
+ int size = READ32 (ip + 3);
+ memcpy (vt_sp, addr, size);
+ sp->data.p = vt_sp;
+ vt_sp += ALIGN_TO (size, MINT_VT_ALIGNMENT);
+ ip += 5;
+ ++sp;
+ MINT_IN_BREAK;
+ }
#define STSFLD(datamem, fieldtype) { \
MonoVTable *vtable = (MonoVTable*) imethod->data_items [*(guint16*)(ip + 1)]; \
INIT_VTABLE (vtable); \
MINT_IN_BREAK;
}
- MINT_IN_CASE(MINT_STSSFLD_SLOW)
- MINT_IN_CASE(MINT_STSSFLD_VT_SLOW) {
- gboolean is_vt = *ip == MINT_STSSFLD_VT_SLOW;
+#define STTSFLD(datamem, fieldtype) { \
+ guint32 offset = READ32(ip + 1); \
+ MonoInternalThread *thread = mono_thread_internal_current (); \
+ gpointer addr = ((char*)thread->static_data [offset & 0x3f]) + (offset >> 6); \
+ sp--; \
+ *(fieldtype*)addr = sp[0].data.datamem; \
+ ip += 3; \
+ }
+
+ MINT_IN_CASE(MINT_STTSFLD_I1) STTSFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_U1) STTSFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_I2) STTSFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_U2) STTSFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_I4) STTSFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_I8) STTSFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_R4) STTSFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_R8) STTSFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_P) STTSFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STTSFLD_O) STTSFLD(p, gpointer); MINT_IN_BREAK;
+
+ MINT_IN_CASE(MINT_STSSFLD) {
MonoClassField *field = (MonoClassField*)imethod->data_items [* (guint16 *)(ip + 1)];
- gpointer addr = mono_class_static_field_address (imethod->domain, field);
- EXCEPTION_CHECKPOINT;
+ guint32 offset = READ32(ip + 2);
+ gpointer addr = mono_get_special_static_data (offset);
--sp;
stackval_to_data (field->type, sp, addr, FALSE);
- if (is_vt) {
- int size = READ32 (ip + 2);
- vt_sp -= ALIGN_TO (size, MINT_VT_ALIGNMENT);
- ip += 4;
- } else {
- ip += 2;
- }
+ ip += 4;
MINT_IN_BREAK;
}
+ MINT_IN_CASE(MINT_STSSFLD_VT) {
+ guint32 offset = READ32(ip + 1);
+ gpointer addr = mono_get_special_static_data (offset);
+ --sp;
+ int size = READ32 (ip + 3);
+ memcpy (addr, sp->data.vt, size);
+ vt_sp -= ALIGN_TO (size, MINT_VT_ALIGNMENT);
+ ip += 5;
+ MINT_IN_BREAK;
+ }
+
MINT_IN_CASE(MINT_STOBJ_VT) {
int size;
c = (MonoClass*)imethod->data_items[* (guint16 *)(ip + 1)];
OPDEF(MINT_STRMFLD, "strmfld", 2, MintOpFieldToken)
OPDEF(MINT_STRMFLD_VT, "strmfld.vt", 2, MintOpUShortInt)
-OPDEF(MINT_LDSSFLD_SLOW, "ldssfld.slow", 2, MintOpFieldToken)
-OPDEF(MINT_LDSSFLD_VT_SLOW, "ldssfld.vt.slow", 4, MintOpFieldToken)
+OPDEF(MINT_LDTSFLD_I1, "ldtsfld.i1", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_U1, "ldtsfld.u1", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_I2, "ldtsfld.i2", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_U2, "ldtsfld.u2", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_I4, "ldtsfld.i4", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_I8, "ldtsfld.i8", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_R4, "ldtsfld.r4", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_R8, "ldtsfld.r8", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_O, "ldtsfld.o", 3, MintOpInt)
+OPDEF(MINT_LDTSFLD_P, "ldtsfld.p", 3, MintOpInt)
+OPDEF(MINT_LDSSFLD, "ldssfld", 4, MintOpFieldToken)
+OPDEF(MINT_LDSSFLD_VT, "ldssfld.vt", 5, MintOpInt)
+
OPDEF(MINT_LDSFLD_I1, "ldsfld.i1", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_U1, "ldsfld.u1", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_I2, "ldsfld.i2", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_P, "ldsfld.p", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 5, MintOpTwoShorts)
-OPDEF(MINT_STSSFLD_SLOW, "stssfld.slow", 2, MintOpFieldToken)
-OPDEF(MINT_STSSFLD_VT_SLOW, "stssfld.vt.slow", 4, MintOpFieldToken)
+OPDEF(MINT_STTSFLD_I1, "sttsfld.i1", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_U1, "sttsfld.u1", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_I2, "sttsfld.i2", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_U2, "sttsfld.u2", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_I4, "sttsfld.i4", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_I8, "sttsfld.i8", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_R4, "sttsfld.r4", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_R8, "sttsfld.r8", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_O, "sttsfld.o", 3, MintOpInt)
+OPDEF(MINT_STTSFLD_P, "sttsfld.p", 3, MintOpInt)
+OPDEF(MINT_STSSFLD, "stssfld", 4, MintOpFieldToken)
+OPDEF(MINT_STSSFLD_VT, "stssfld.vt", 5, MintOpInt)
OPDEF(MINT_STSFLD_I1, "stsfld.i1", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_U1, "stsfld.u1", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_I2, "stsfld.i2", 3, MintOpUShortInt)
}
static void
-interp_emit_ldsfld (TransformData *td, MonoClassField *field, MonoClass *field_class, int mt, MonoError *error)
+interp_emit_sfld_access (TransformData *td, MonoClassField *field, MonoClass *field_class, int mt, gboolean is_load, MonoError *error)
{
- if (mono_class_field_is_special_static (field)) {
- interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_LDSSFLD_VT_SLOW : MINT_LDSSFLD_SLOW);
- td->last_ins->data [0] = get_data_item_index (td, field);
- if (mt == MINT_TYPE_VT) {
- int size = mono_class_value_size (field_class, NULL);
- WRITE32_INS(td->last_ins, 1, &size);
- }
- } else {
- MonoVTable *vtable = mono_class_vtable_checked (td->rtm->domain, field->parent, error);
- return_if_nok (error);
-
- interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_LDSFLD_VT : (MINT_LDSFLD_I1 + mt - MINT_TYPE_I1));
- td->last_ins->data [0] = get_data_item_index (td, vtable);
- td->last_ins->data [1] = get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset);
-
- if (mt == MINT_TYPE_VT) {
- int size = mono_class_value_size (field_class, NULL);
- WRITE32_INS(td->last_ins, 2, &size);
- }
- }
-}
+ MonoDomain *domain = td->rtm->domain;
+ // Initialize the offset for the field
+ MonoVTable *vtable = mono_class_vtable_checked (domain, field->parent, error);
+ return_if_nok (error);
-static void
-interp_emit_stsfld (TransformData *td, MonoClassField *field, MonoClass *field_class, int mt, MonoError *error)
-{
if (mono_class_field_is_special_static (field)) {
- interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSSFLD_VT_SLOW : MINT_STSSFLD_SLOW);
- td->last_ins->data [0] = get_data_item_index (td, field);
- if (mt == MINT_TYPE_VT) {
- int size = mono_class_value_size (field_class, NULL);
- WRITE32_INS(td->last_ins, 1, &size);
+ guint32 offset;
+
+ mono_domain_lock (domain);
+ g_assert (domain->special_static_fields);
+ offset = GPOINTER_TO_UINT (g_hash_table_lookup (domain->special_static_fields, field));
+ mono_domain_unlock (domain);
+ g_assert (offset);
+
+ // Offset is SpecialStaticOffset
+ if ((offset & 0x80000000) == 0 && mt != MINT_TYPE_VT) {
+ // This field is thread static
+ interp_add_ins (td, (is_load ? MINT_LDTSFLD_I1 : MINT_STTSFLD_I1) + mt);
+ WRITE32_INS(td->last_ins, 0, &offset);
+ } else {
+ if (mt == MINT_TYPE_VT) {
+ interp_add_ins (td, is_load ? MINT_LDSSFLD_VT : MINT_STSSFLD_VT);
+ WRITE32_INS(td->last_ins, 0, &offset);
+
+ int size = mono_class_value_size (field_class, NULL);
+ WRITE32_INS(td->last_ins, 2, &size);
+ } else {
+ interp_add_ins (td, is_load ? MINT_LDSSFLD : MINT_STSSFLD);
+ td->last_ins->data [0] = get_data_item_index (td, field);
+ WRITE32_INS(td->last_ins, 1, &offset);
+ }
}
} else {
- MonoVTable *vtable = mono_class_vtable_checked (td->rtm->domain, field->parent, error);
- return_if_nok (error);
+ if (is_load)
+ interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_LDSFLD_VT : (MINT_LDSFLD_I1 + mt - MINT_TYPE_I1));
+ else
+ interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSFLD_VT : (MINT_STSFLD_I1 + mt - MINT_TYPE_I1));
- interp_add_ins (td, (mt == MINT_TYPE_VT) ? MINT_STSFLD_VT : (MINT_STSFLD_I1 + mt - MINT_TYPE_I1));
td->last_ins->data [0] = get_data_item_index (td, vtable);
td->last_ins->data [1] = get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset);
if (is_static) {
interp_add_ins (td, MINT_POP);
td->last_ins->data [0] = 0;
- interp_emit_ldsfld (td, field, field_klass, mt, error);
+ interp_emit_sfld_access (td, field, field_klass, mt, TRUE, error);
goto_if_nok (error, exit);
} else {
int opcode = MINT_LDFLD_I1 + mt - MINT_TYPE_I1;
if (is_static) {
interp_add_ins (td, MINT_POP);
td->last_ins->data [0] = 1;
- interp_emit_stsfld (td, field, field_klass, mt, error);
+ interp_emit_sfld_access (td, field, field_klass, mt, FALSE, error);
goto_if_nok (error, exit);
/* the vtable of the field might not be initialized at this point */
mt = mint_type (ftype);
klass = mono_class_from_mono_type_internal (ftype);
- interp_emit_ldsfld (td, field, klass, mt, error);
+ interp_emit_sfld_access (td, field, klass, mt, TRUE, error);
goto_if_nok (error, exit);
if (mt == MINT_TYPE_VT) {
mono_class_vtable_checked (domain, fld_klass, error);
goto_if_nok (error, exit);
- interp_emit_stsfld (td, field, fld_klass, mt, error);
+ interp_emit_sfld_access (td, field, fld_klass, mt, FALSE, error);
goto_if_nok (error, exit);
if (mt == MINT_TYPE_VT) {