Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/mono/mono/metadata/class-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1749,8 +1749,6 @@ mono_class_setup_count_virtual_methods (MonoClass *klass)
return vcount;
}

#ifdef COMPRESSED_INTERFACE_BITMAP

/*
* Compressed interface bitmap design.
*
Expand Down Expand Up @@ -1840,7 +1838,7 @@ mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size)
* FALSE otherwise.
*/
int
mono_class_interface_match (const uint8_t *bitmap, int id)
mono_class_interface_match_compressed (const uint8_t *bitmap, int id)
{
while (TRUE) {
id -= bitmap [0] * 8;
Expand All @@ -1853,7 +1851,6 @@ mono_class_interface_match (const uint8_t *bitmap, int id)
id -= 8;
}
}
#endif

static char*
concat_two_strings_with_zero (MonoImage *image, const char *s1, const char *s2)
Expand Down
13 changes: 5 additions & 8 deletions src/mono/mono/metadata/class-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "mono/utils/mono-error-internals.h"
#include "mono/utils/mono-memory-model.h"
#include "mono/utils/mono-compiler.h"
#include "mono/utils/options.h"

#define MONO_CLASS_IS_ARRAY(c) (m_class_get_rank (c))

Expand Down Expand Up @@ -287,8 +288,6 @@ union _MonoClassSizes {
int generic_param_token; /* for generic param types, both var and mvar */
};

#define COMPRESSED_INTERFACE_BITMAP 1

#ifdef ENABLE_CHECKED_BUILD_PRIVATE_TYPES
#define MONO_CLASS_DEF_PRIVATE 1
#endif
Expand Down Expand Up @@ -317,14 +316,12 @@ union _MonoClassSizes {
#undef MONO_CLASS_GETTER
#undef MONO_CLASS_OFFSET

#ifdef COMPRESSED_INTERFACE_BITMAP
int mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size);
int mono_class_interface_match (const uint8_t *bitmap, int id);
#else
int mono_class_interface_match_compressed (const uint8_t *bitmap, int id);

#define mono_class_interface_match(bmap,uiid) ((bmap) [(uiid) >> 3] & (1 << ((uiid)&7)))
#endif

#define MONO_CLASS_IMPLEMENTS_INTERFACE(k,uiid) (((uiid) <= m_class_get_max_interface_id (k)) && mono_class_interface_match (m_class_get_interface_bitmap (k), (uiid)))
#define MONO_CLASS_IMPLEMENTS_INTERFACE(k,uiid) (((uiid) <= m_class_get_max_interface_id (k)) && (mono_opt_compressed_interface_bitmap ? mono_class_interface_match_compressed (m_class_get_interface_bitmap (k), (uiid)) : mono_class_interface_match (m_class_get_interface_bitmap (k), (uiid))))

#define MONO_VTABLE_AVAILABLE_GC_BITS 4

Expand Down Expand Up @@ -374,7 +371,7 @@ struct MonoVTable {

#define MONO_SIZEOF_VTABLE (sizeof (MonoVTable) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)

#define MONO_VTABLE_IMPLEMENTS_INTERFACE(vt,uiid) (((uiid) <= (vt)->max_interface_id) && mono_class_interface_match ((vt)->interface_bitmap, (uiid)))
#define MONO_VTABLE_IMPLEMENTS_INTERFACE(vt,uiid) (((uiid) <= (vt)->max_interface_id) && (mono_opt_compressed_interface_bitmap ? mono_class_interface_match_compressed ((vt)->interface_bitmap, (uiid)) : mono_class_interface_match ((vt)->interface_bitmap, (uiid))))

/*
* Generic instantiation data type encoding.
Expand Down
39 changes: 19 additions & 20 deletions src/mono/mono/metadata/class-setup-vtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,18 @@ print_implemented_interfaces (MonoClass *klass)
printf ("(%d,F)", i);
printf ("\n");
printf ("Dump interface flags:");
#ifdef COMPRESSED_INTERFACE_BITMAP
{
if (mono_opt_compressed_interface_bitmap) {
const uint8_t* p = klass->interface_bitmap;
guint32 i = klass->max_interface_id;
while (i > 0) {
printf (" %d x 00 %02X", p [0], p [1]);
i -= p [0] * 8;
i -= 8;
}
} else {
for (guint32 i = 0; i < ((((klass->max_interface_id + 1) >> 3)) + (((klass->max_interface_id + 1) & 7) ? 1 : 0)); i++)
printf (" %02X", klass->interface_bitmap [i]);
}
#else
for (guint32 i = 0; i < ((((klass->max_interface_id + 1) >> 3)) + (((klass->max_interface_id + 1) & 7)? 1 :0)); i++)
printf (" %02X", klass->interface_bitmap [i]);
#endif
printf ("\n");
while (klass != NULL) {
printf ("[LEVEL %d] Implemented interfaces by class %s:\n", ancestor_level, klass->name);
Expand Down Expand Up @@ -331,11 +329,12 @@ mono_class_setup_interface_offsets_internal (MonoClass *klass, int cur_slot, int
klass->interface_offsets_packed = (guint16 *)mono_class_alloc (klass, sizeof (guint16) * interface_offsets_count);
}
bsize = (sizeof (guint8) * ((max_iid + 1) >> 3)) + (((max_iid + 1) & 7)? 1 :0);
#ifdef COMPRESSED_INTERFACE_BITMAP
bitmap = g_malloc0 (bsize);
#else
bitmap = (uint8_t *)mono_class_alloc0 (klass, bsize);
#endif

if (mono_opt_compressed_interface_bitmap)
bitmap = g_malloc0 (bsize);
else
bitmap = (uint8_t *)mono_class_alloc0 (klass, bsize);

for (int i = 0; i < interface_offsets_count; i++) {
guint32 id = interfaces_full [i]->interface_id;
bitmap [id >> 3] |= (1 << (id & 7));
Expand All @@ -345,16 +344,16 @@ mono_class_setup_interface_offsets_internal (MonoClass *klass, int cur_slot, int
}
}
if (!klass->interface_bitmap) {
#ifdef COMPRESSED_INTERFACE_BITMAP
int len = mono_compress_bitmap (NULL, bitmap, bsize);
uint8_t *compressed_bitmap = mono_class_alloc0 (klass, len);
mono_compress_bitmap (compressed_bitmap, bitmap, bsize);
g_free (bitmap);
if (mono_opt_compressed_interface_bitmap) {
int len = mono_compress_bitmap (NULL, bitmap, bsize);
uint8_t *compressed_bitmap = mono_class_alloc0 (klass, len);
mono_compress_bitmap (compressed_bitmap, bitmap, bsize);
g_free (bitmap);

klass->interface_bitmap = compressed_bitmap;
#else
klass->interface_bitmap = bitmap;
#endif
klass->interface_bitmap = compressed_bitmap;
} else {
klass->interface_bitmap = bitmap;
}
}
}
end:
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/metadata/jit-icall-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ MONO_JIT_ICALL (mono_break) \
MONO_JIT_ICALL (mono_byvalarray_to_byte_array) \
MONO_JIT_ICALL (mono_chkstk_win64) \
MONO_JIT_ICALL (mono_ckfinite) \
MONO_JIT_ICALL (mono_class_interface_match) \
MONO_JIT_ICALL (mono_class_interface_match_compressed) \
MONO_JIT_ICALL (mono_class_static_field_address) \
MONO_JIT_ICALL (mono_compile_method_icall) \
MONO_JIT_ICALL (mono_context_get_icall) \
Expand Down
7 changes: 2 additions & 5 deletions src/mono/mono/metadata/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -4860,11 +4860,8 @@ get_virtual_stelemref_kind (MonoClass *element_class)

/* Compressed interface bitmaps require code that is quite complex, so don't optimize for it. */
if (MONO_CLASS_IS_INTERFACE_INTERNAL (element_class) && !mono_class_has_variant_generic_params (element_class))
#ifdef COMPRESSED_INTERFACE_BITMAP
return STELEMREF_COMPLEX;
#else
return STELEMREF_INTERFACE;
#endif
return mono_opt_compressed_interface_bitmap ? STELEMREF_COMPLEX : STELEMREF_INTERFACE;

/*Arrays are sealed but are covariant on their element type, We can't use any of the fast paths.*/
if (m_class_get_rank (element_class) || mono_class_has_variant_generic_params (element_class))
return STELEMREF_COMPLEX;
Expand Down
9 changes: 9 additions & 0 deletions src/mono/mono/metadata/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,15 @@ mono_metadata_init (void)
g_hash_table_insert (type_cache, (gpointer) &builtin_types [i], (gpointer) &builtin_types [i]);

mono_metadata_update_init ();

char *compressed_bmap = g_getenv ("MONO_COMPRESSED_INTERFACE_BITMAP");
if (compressed_bmap) {
if (compressed_bmap [0] == '1')
mono_opt_compressed_interface_bitmap = TRUE;
else if (compressed_bmap [0] == '0')
mono_opt_compressed_interface_bitmap = FALSE;
g_free (compressed_bmap);
}
}

/*
Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -15107,6 +15107,9 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
acfg->is_full_aot = TRUE;
}

if (mono_opt_compressed_interface_bitmap)
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_COMPRESSED_INTERFACE_BITMAP);

if (mini_safepoints_enabled ())
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SAFEPOINTS);

Expand Down
9 changes: 8 additions & 1 deletion src/mono/mono/mini/aot-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,7 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, guint8 *blob, char
char *build_info;
char *msg = NULL;
gboolean usable = TRUE;
gboolean full_aot, interp, safepoints;
gboolean full_aot, interp, safepoints, compressed_interface_bmap;
guint32 excluded_cpu_optimizations;

if (strcmp (assembly->image->guid, (const char*)info->assembly_guid)) {
Expand Down Expand Up @@ -1713,6 +1713,13 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, guint8 *blob, char
}
#endif

compressed_interface_bmap = info->flags & MONO_AOT_FILE_FLAG_COMPRESSED_INTERFACE_BITMAP;
if ((mono_opt_compressed_interface_bitmap && !compressed_interface_bmap) ||
(!mono_opt_compressed_interface_bitmap && compressed_interface_bmap)) {
msg = g_strdup ("mismatch with compressed interface bitmap feature");
usable = FALSE;
}

*out_msg = msg;
return usable;
}
Expand Down
5 changes: 3 additions & 2 deletions src/mono/mono/mini/aot-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "mini.h"

/* Version number of the AOT file format */
#define MONO_AOT_FILE_VERSION 186
#define MONO_AOT_FILE_VERSION 187

#define MONO_AOT_TRAMP_PAGE_SIZE 16384

Expand Down Expand Up @@ -74,7 +74,8 @@ typedef enum {
MONO_AOT_FILE_FLAG_SEPARATE_DATA = 64,
MONO_AOT_FILE_FLAG_EAGER_LOAD = 128,
MONO_AOT_FILE_FLAG_INTERP = 256,
MONO_AOT_FILE_FLAG_CODE_EXEC_ONLY = 512
MONO_AOT_FILE_FLAG_CODE_EXEC_ONLY = 512,
MONO_AOT_FILE_FLAG_COMPRESSED_INTERFACE_BITMAP = 1024
} MonoAotFileFlags;

typedef enum {
Expand Down
6 changes: 3 additions & 3 deletions src/mono/mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -5080,9 +5080,9 @@ register_icalls (void)
#endif
register_icall (mono_ckfinite, mono_icall_sig_double_double, FALSE);

#ifdef COMPRESSED_INTERFACE_BITMAP
register_icall (mono_class_interface_match, mono_icall_sig_uint32_ptr_int32, TRUE);
#endif
// opt is initialized because mono_metadata_init is ran before this
if (mono_opt_compressed_interface_bitmap)
register_icall (mono_class_interface_match_compressed, mono_icall_sig_uint32_ptr_int32, TRUE);

/* other jit icalls */
register_icall (ves_icall_mono_delegate_ctor, mono_icall_sig_void_object_object_ptr, FALSE);
Expand Down
63 changes: 32 additions & 31 deletions src/mono/mono/mini/type-checking.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,40 +134,41 @@ static void
mini_emit_interface_bitmap_check (MonoCompile *cfg, int intf_bit_reg, int base_reg, intptr_t offset, MonoClass *klass)
{
int ibitmap_reg = alloc_preg (cfg);
#ifdef COMPRESSED_INTERFACE_BITMAP
MonoInst *args [2];
MonoInst *res, *ins;
NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, ibitmap_reg, base_reg, (target_mgreg_t)offset);
MONO_ADD_INS (cfg->cbb, ins);
args [0] = ins;
args [1] = mini_emit_runtime_constant (cfg, MONO_PATCH_INFO_IID, klass);
res = mono_emit_jit_icall (cfg, mono_class_interface_match, args);
MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, intf_bit_reg, res->dreg);
#else
int ibitmap_byte_reg = alloc_preg (cfg);

MONO_EMIT_NEW_LOAD_MEMBASE (cfg, ibitmap_reg, base_reg, GINTPTR_TO_TMREG (offset));

if (cfg->compile_aot) {
int iid_reg = alloc_preg (cfg);
int shifted_iid_reg = alloc_preg (cfg);
int ibitmap_byte_address_reg = alloc_preg (cfg);
int masked_iid_reg = alloc_preg (cfg);
int iid_one_bit_reg = alloc_preg (cfg);
int iid_bit_reg = alloc_preg (cfg);
MONO_EMIT_NEW_AOTCONST (cfg, iid_reg, klass, MONO_PATCH_INFO_IID);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SHR_IMM, shifted_iid_reg, iid_reg, 3);
MONO_EMIT_NEW_BIALU (cfg, OP_PADD, ibitmap_byte_address_reg, ibitmap_reg, shifted_iid_reg);
MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, ibitmap_byte_reg, ibitmap_byte_address_reg, 0);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IAND_IMM, masked_iid_reg, iid_reg, 7);
MONO_EMIT_NEW_ICONST (cfg, iid_one_bit_reg, 1);
MONO_EMIT_NEW_BIALU (cfg, OP_ISHL, iid_bit_reg, iid_one_bit_reg, masked_iid_reg);
MONO_EMIT_NEW_BIALU (cfg, OP_IAND, intf_bit_reg, ibitmap_byte_reg, iid_bit_reg);
if (mono_opt_compressed_interface_bitmap) {
MonoInst *args [2];
MonoInst *res, *ins;
NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, ibitmap_reg, base_reg, (target_mgreg_t)offset);
MONO_ADD_INS (cfg->cbb, ins);
args [0] = ins;
args [1] = mini_emit_runtime_constant (cfg, MONO_PATCH_INFO_IID, klass);
res = mono_emit_jit_icall (cfg, mono_class_interface_match_compressed, args);
MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, intf_bit_reg, res->dreg);
} else {
MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, ibitmap_byte_reg, ibitmap_reg, m_class_get_interface_id (klass) >> 3);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_AND_IMM, intf_bit_reg, ibitmap_byte_reg, ((target_mgreg_t)1) << (m_class_get_interface_id (klass) & 7));
int ibitmap_byte_reg = alloc_preg (cfg);

MONO_EMIT_NEW_LOAD_MEMBASE (cfg, ibitmap_reg, base_reg, GINTPTR_TO_TMREG (offset));

if (cfg->compile_aot) {
int iid_reg = alloc_preg (cfg);
int shifted_iid_reg = alloc_preg (cfg);
int ibitmap_byte_address_reg = alloc_preg (cfg);
int masked_iid_reg = alloc_preg (cfg);
int iid_one_bit_reg = alloc_preg (cfg);
int iid_bit_reg = alloc_preg (cfg);
MONO_EMIT_NEW_AOTCONST (cfg, iid_reg, klass, MONO_PATCH_INFO_IID);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SHR_IMM, shifted_iid_reg, iid_reg, 3);
MONO_EMIT_NEW_BIALU (cfg, OP_PADD, ibitmap_byte_address_reg, ibitmap_reg, shifted_iid_reg);
MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, ibitmap_byte_reg, ibitmap_byte_address_reg, 0);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IAND_IMM, masked_iid_reg, iid_reg, 7);
MONO_EMIT_NEW_ICONST (cfg, iid_one_bit_reg, 1);
MONO_EMIT_NEW_BIALU (cfg, OP_ISHL, iid_bit_reg, iid_one_bit_reg, masked_iid_reg);
MONO_EMIT_NEW_BIALU (cfg, OP_IAND, intf_bit_reg, ibitmap_byte_reg, iid_bit_reg);
} else {
MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, ibitmap_byte_reg, ibitmap_reg, m_class_get_interface_id (klass) >> 3);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_AND_IMM, intf_bit_reg, ibitmap_byte_reg, ((target_mgreg_t)1) << (m_class_get_interface_id (klass) & 7));
}
}
#endif
}

/*
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/utils/options-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ DEFINE_BOOL_READONLY(experimental_gshared_mrgctx, "experimental-gshared-mrgctx",
DEFINE_BOOL(experimental_gshared_mrgctx, "experimental-gshared-mrgctx", FALSE, "Use a mrgctx for all gshared methods")
#endif

DEFINE_BOOL(compressed_interface_bitmap, "compressed-interface-bitmap", FALSE, "Use compressed bitmap for storing implemented interfaces in vtables and classes")

#if defined(TARGET_WASI)
DEFINE_BOOL_READONLY(llvm_emulate_unwind, "emulate-unwind", TRUE, "")
#else
Expand Down
Loading