Enhance maximum number of supported interfaces from 2^16.
int vtable_size; /* number of slots */
guint16 interface_count;
- guint16 interface_id; /* unique inderface id (for interfaces) */
- guint16 max_interface_id;
+ guint32 interface_id; /* unique inderface id (for interfaces) */
+ guint32 max_interface_id;
guint16 interface_offsets_count;
MonoClass **interfaces_packed;
MonoDomain *domain; /* each object/vtable belongs to exactly one domain */
gpointer type; /* System.Type type for klass */
guint8 *interface_bitmap;
- guint16 max_interface_id;
+ guint32 max_interface_id;
guint8 rank;
guint remote : 1; /* class is remotely activated */
guint initialized : 1; /* cctor has been run */
* LOCKING: Acquires the classes lock.
* Returns: The new ID.
*/
-static guint
+static guint32
mono_get_unique_iid (MonoClass *klass)
{
int iid;
}
#endif
- g_assert (iid <= 65535);
+ /* I've confirmed iids safe past 16 bits, however bitset code uses a signed int while testing.
+ * Once this changes, it should be safe for us to allow 2^32-1 interfaces, until then 2^31-2 is the max. */
+ g_assert (iid < INT_MAX);
return iid;
}
{
MonoError error;
MonoClass *k, *ic;
- int i, j, max_iid, num_ifaces;
+ int i, j, num_ifaces;
+ guint32 max_iid;
MonoClass **interfaces_full = NULL;
int *interface_offsets_full = NULL;
GPtrArray *ifaces;
bitmap = (uint8_t *)mono_class_alloc0 (klass, bsize);
#endif
for (i = 0; i < interface_offsets_count; i++) {
- int id = interfaces_full [i]->interface_id;
+ guint32 id = interfaces_full [i]->interface_id;
bitmap [id >> 3] |= (1 << (id & 7));
klass->interfaces_packed [i] = interfaces_full [i];
klass->interface_offsets_packed [i] = interface_offsets_full [i];
MonoError error;
MonoClass *k, *ic;
MonoMethod **vtable;
- int i, max_vtsize = 0, max_iid, cur_slot = 0;
+ int i, max_vtsize = 0, cur_slot = 0;
+ guint32 max_iid;
GPtrArray *ifaces = NULL;
GHashTable *override_map = NULL;
MonoMethod *cm;
return NULL;
}
+ /* This is required now that it is possible for more than 2^16 interfaces to exist. */
+ g_assert(icount <= 65535);
+
klass->interfaces = interfaces;
klass->interface_count = icount;
klass->interfaces_inited = 1;
/* uiid = klass->interface_id; */
mono_mb_emit_ldloc (mb, aklass);
mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoClass, interface_id));
- mono_mb_emit_byte (mb, CEE_LDIND_U2);
+ mono_mb_emit_byte (mb, CEE_LDIND_U4);
mono_mb_emit_stloc (mb, uiid);
/*if (uiid > vt->max_interface_id)*/
mono_mb_emit_ldloc (mb, uiid);
mono_mb_emit_ldloc (mb, vtable);
mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoVTable, max_interface_id));
- mono_mb_emit_byte (mb, CEE_LDIND_U2);
+ mono_mb_emit_byte (mb, CEE_LDIND_U4);
b2 = mono_mb_emit_branch (mb, CEE_BGT_UN);
/* if (!(vt->interface_bitmap [(uiid) >> 3] & (1 << ((uiid)&7)))) */
MONO_REQ_GC_UNSAFE_MODE;
MonoVTable *vt, *pvt;
- int i, j, vtsize, max_interface_id, extra_interface_vtsize = 0;
+ int i, j, vtsize, extra_interface_vtsize = 0;
+ guint32 max_interface_id;
MonoClass *k;
GSList *extra_interfaces = NULL;
MonoClass *klass = remote_class->proxy_class;
{
int max_iid_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU2_MEMBASE, max_iid_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, max_interface_id));
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU4_MEMBASE, max_iid_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, max_interface_id));
mini_emit_max_iid_check (cfg, max_iid_reg, klass, false_target);
}
{
int max_iid_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU2_MEMBASE, max_iid_reg, klass_reg, MONO_STRUCT_OFFSET (MonoClass, max_interface_id));
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU4_MEMBASE, max_iid_reg, klass_reg, MONO_STRUCT_OFFSET (MonoClass, max_interface_id));
mini_emit_max_iid_check (cfg, max_iid_reg, klass, false_target);
}
break;
case MONO_PATCH_INFO_IID:
mono_class_init (patch_info->data.klass);
- target = GINT_TO_POINTER ((int)patch_info->data.klass->interface_id);
+ target = GUINT_TO_POINTER (patch_info->data.klass->interface_id);
break;
case MONO_PATCH_INFO_ADJUSTED_IID:
mono_class_init (patch_info->data.klass);
- target = GINT_TO_POINTER ((int)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
+ target = GUINT_TO_POINTER ((guint32)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
break;
case MONO_PATCH_INFO_VTABLE:
target = mono_class_vtable (domain, patch_info->data.klass);