Skip to content

Commit 4def3e8

Browse files
authored
[release/9.0] [mono] Make the compressed interface bitmap feature usable (#120154)
* [mono][metadata] Enable compressed interface bitmap by default (#119694) * [mono][metadata] Enable compressed interface bitmap by default * Fix build on windows * Fix publishing of compressed bitmap Before this commit we were doing changes on the published data which is problematic for multithreaded environments. We ensure the bitmap is fully processed before publishing it so that we can rely on the data dependency memory ordering constraint for correctness. * [mono] Enable configuration at runtime of the compressed interface bitmap feature (#119881) * Add option to configure use of compressed interface bitmaps This optimization is disabled by default. Enable it with `MONO_COMPRESSED_INTERFACE_BITMAP=1` * Add support for detecting mismatch with aot images
1 parent 09744b4 commit 4def3e8

File tree

12 files changed

+91
-80
lines changed

12 files changed

+91
-80
lines changed

src/mono/mono/metadata/class-init.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,8 +1689,6 @@ mono_class_setup_count_virtual_methods (MonoClass *klass)
16891689
return vcount;
16901690
}
16911691

1692-
#ifdef COMPRESSED_INTERFACE_BITMAP
1693-
16941692
/*
16951693
* Compressed interface bitmap design.
16961694
*
@@ -1745,7 +1743,7 @@ mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size)
17451743
while (bitmap < end) {
17461744
if (*bitmap || numz == 255) {
17471745
if (dest) {
1748-
*dest++ = numz;
1746+
*dest++ = (uint8_t)numz;
17491747
*dest++ = *bitmap;
17501748
}
17511749
res += 2;
@@ -1759,7 +1757,7 @@ mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size)
17591757
if (numz) {
17601758
res += 2;
17611759
if (dest) {
1762-
*dest++ = numz;
1760+
*dest++ = (uint8_t)numz;
17631761
*dest++ = 0;
17641762
}
17651763
}
@@ -1780,7 +1778,7 @@ mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size)
17801778
* FALSE otherwise.
17811779
*/
17821780
int
1783-
mono_class_interface_match (const uint8_t *bitmap, int id)
1781+
mono_class_interface_match_compressed (const uint8_t *bitmap, int id)
17841782
{
17851783
while (TRUE) {
17861784
id -= bitmap [0] * 8;
@@ -1793,7 +1791,6 @@ mono_class_interface_match (const uint8_t *bitmap, int id)
17931791
id -= 8;
17941792
}
17951793
}
1796-
#endif
17971794

17981795
static char*
17991796
concat_two_strings_with_zero (MonoImage *image, const char *s1, const char *s2)

src/mono/mono/metadata/class-internals.h

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "mono/utils/mono-error-internals.h"
1818
#include "mono/utils/mono-memory-model.h"
1919
#include "mono/utils/mono-compiler.h"
20+
#include "mono/utils/options.h"
2021

2122
#define MONO_CLASS_IS_ARRAY(c) (m_class_get_rank (c))
2223

@@ -287,12 +288,6 @@ union _MonoClassSizes {
287288
int generic_param_token; /* for generic param types, both var and mvar */
288289
};
289290

290-
/* enabled only with small config for now: we might want to do it unconditionally */
291-
#ifdef MONO_SMALL_CONFIG
292-
#define COMPRESSED_INTERFACE_BITMAP 1
293-
#endif
294-
295-
296291
#ifdef ENABLE_CHECKED_BUILD_PRIVATE_TYPES
297292
#define MONO_CLASS_DEF_PRIVATE 1
298293
#endif
@@ -321,14 +316,12 @@ union _MonoClassSizes {
321316
#undef MONO_CLASS_GETTER
322317
#undef MONO_CLASS_OFFSET
323318

324-
#ifdef COMPRESSED_INTERFACE_BITMAP
325319
int mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size);
326-
int mono_class_interface_match (const uint8_t *bitmap, int id);
327-
#else
320+
int mono_class_interface_match_compressed (const uint8_t *bitmap, int id);
321+
328322
#define mono_class_interface_match(bmap,uiid) ((bmap) [(uiid) >> 3] & (1 << ((uiid)&7)))
329-
#endif
330323

331-
#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)))
324+
#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))))
332325

333326
#define MONO_VTABLE_AVAILABLE_GC_BITS 4
334327

@@ -378,7 +371,7 @@ struct MonoVTable {
378371

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

381-
#define MONO_VTABLE_IMPLEMENTS_INTERFACE(vt,uiid) (((uiid) <= (vt)->max_interface_id) && mono_class_interface_match ((vt)->interface_bitmap, (uiid)))
374+
#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))))
382375

383376
/*
384377
* Generic instantiation data type encoding.

src/mono/mono/metadata/class-setup-vtable.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,18 @@ print_implemented_interfaces (MonoClass *klass)
5656
printf ("(%d,F)", i);
5757
printf ("\n");
5858
printf ("Dump interface flags:");
59-
#ifdef COMPRESSED_INTERFACE_BITMAP
60-
{
59+
if (mono_opt_compressed_interface_bitmap) {
6160
const uint8_t* p = klass->interface_bitmap;
6261
guint32 i = klass->max_interface_id;
6362
while (i > 0) {
6463
printf (" %d x 00 %02X", p [0], p [1]);
6564
i -= p [0] * 8;
6665
i -= 8;
6766
}
67+
} else {
68+
for (guint32 i = 0; i < ((((klass->max_interface_id + 1) >> 3)) + (((klass->max_interface_id + 1) & 7) ? 1 : 0)); i++)
69+
printf (" %02X", klass->interface_bitmap [i]);
6870
}
69-
#else
70-
for (guint32 i = 0; i < ((((klass->max_interface_id + 1) >> 3)) + (((klass->max_interface_id + 1) & 7)? 1 :0)); i++)
71-
printf (" %02X", klass->interface_bitmap [i]);
72-
#endif
7371
printf ("\n");
7472
while (klass != NULL) {
7573
printf ("[LEVEL %d] Implemented interfaces by class %s:\n", ancestor_level, klass->name);
@@ -329,11 +327,12 @@ mono_class_setup_interface_offsets_internal (MonoClass *klass, int cur_slot, int
329327
klass->interface_offsets_packed = (guint16 *)mono_class_alloc (klass, sizeof (guint16) * interface_offsets_count);
330328
}
331329
bsize = (sizeof (guint8) * ((max_iid + 1) >> 3)) + (((max_iid + 1) & 7)? 1 :0);
332-
#ifdef COMPRESSED_INTERFACE_BITMAP
333-
bitmap = g_malloc0 (bsize);
334-
#else
335-
bitmap = (uint8_t *)mono_class_alloc0 (klass, bsize);
336-
#endif
330+
331+
if (mono_opt_compressed_interface_bitmap)
332+
bitmap = g_malloc0 (bsize);
333+
else
334+
bitmap = (uint8_t *)mono_class_alloc0 (klass, bsize);
335+
337336
for (int i = 0; i < interface_offsets_count; i++) {
338337
guint32 id = interfaces_full [i]->interface_id;
339338
bitmap [id >> 3] |= (1 << (id & 7));
@@ -343,14 +342,16 @@ mono_class_setup_interface_offsets_internal (MonoClass *klass, int cur_slot, int
343342
}
344343
}
345344
if (!klass->interface_bitmap) {
346-
#ifdef COMPRESSED_INTERFACE_BITMAP
347-
int i = mono_compress_bitmap (NULL, bitmap, bsize);
348-
klass->interface_bitmap = mono_class_alloc0 (klass, i);
349-
mono_compress_bitmap (klass->interface_bitmap, bitmap, bsize);
350-
g_free (bitmap);
351-
#else
352-
klass->interface_bitmap = bitmap;
353-
#endif
345+
if (mono_opt_compressed_interface_bitmap) {
346+
int len = mono_compress_bitmap (NULL, bitmap, bsize);
347+
uint8_t *compressed_bitmap = mono_class_alloc0 (klass, len);
348+
mono_compress_bitmap (compressed_bitmap, bitmap, bsize);
349+
g_free (bitmap);
350+
351+
klass->interface_bitmap = compressed_bitmap;
352+
} else {
353+
klass->interface_bitmap = bitmap;
354+
}
354355
}
355356
}
356357
end:

src/mono/mono/metadata/jit-icall-reg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ MONO_JIT_ICALL (mono_break) \
162162
MONO_JIT_ICALL (mono_byvalarray_to_byte_array) \
163163
MONO_JIT_ICALL (mono_chkstk_win64) \
164164
MONO_JIT_ICALL (mono_ckfinite) \
165-
MONO_JIT_ICALL (mono_class_interface_match) \
165+
MONO_JIT_ICALL (mono_class_interface_match_compressed) \
166166
MONO_JIT_ICALL (mono_class_static_field_address) \
167167
MONO_JIT_ICALL (mono_compile_method_icall) \
168168
MONO_JIT_ICALL (mono_context_get_icall) \

src/mono/mono/metadata/marshal.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4860,11 +4860,8 @@ get_virtual_stelemref_kind (MonoClass *element_class)
48604860

48614861
/* Compressed interface bitmaps require code that is quite complex, so don't optimize for it. */
48624862
if (MONO_CLASS_IS_INTERFACE_INTERNAL (element_class) && !mono_class_has_variant_generic_params (element_class))
4863-
#ifdef COMPRESSED_INTERFACE_BITMAP
4864-
return STELEMREF_COMPLEX;
4865-
#else
4866-
return STELEMREF_INTERFACE;
4867-
#endif
4863+
return mono_opt_compressed_interface_bitmap ? STELEMREF_COMPLEX : STELEMREF_INTERFACE;
4864+
48684865
/*Arrays are sealed but are covariant on their element type, We can't use any of the fast paths.*/
48694866
if (m_class_get_rank (element_class) || mono_class_has_variant_generic_params (element_class))
48704867
return STELEMREF_COMPLEX;

src/mono/mono/metadata/metadata.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,6 +1975,15 @@ mono_metadata_init (void)
19751975
g_hash_table_insert (type_cache, (gpointer) &builtin_types [i], (gpointer) &builtin_types [i]);
19761976

19771977
mono_metadata_update_init ();
1978+
1979+
char *compressed_bmap = g_getenv ("MONO_COMPRESSED_INTERFACE_BITMAP");
1980+
if (compressed_bmap) {
1981+
if (compressed_bmap [0] == '1')
1982+
mono_opt_compressed_interface_bitmap = TRUE;
1983+
else if (compressed_bmap [0] == '0')
1984+
mono_opt_compressed_interface_bitmap = FALSE;
1985+
g_free (compressed_bmap);
1986+
}
19781987
}
19791988

19801989
/*

src/mono/mono/mini/aot-compiler.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15120,6 +15120,9 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1512015120
acfg->is_full_aot = TRUE;
1512115121
}
1512215122

15123+
if (mono_opt_compressed_interface_bitmap)
15124+
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_COMPRESSED_INTERFACE_BITMAP);
15125+
1512315126
if (mini_safepoints_enabled ())
1512415127
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SAFEPOINTS);
1512515128

src/mono/mono/mini/aot-runtime.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1631,7 +1631,7 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, guint8 *blob, char
16311631
char *build_info;
16321632
char *msg = NULL;
16331633
gboolean usable = TRUE;
1634-
gboolean full_aot, interp, safepoints;
1634+
gboolean full_aot, interp, safepoints, compressed_interface_bmap;
16351635
guint32 excluded_cpu_optimizations;
16361636

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

1716+
compressed_interface_bmap = info->flags & MONO_AOT_FILE_FLAG_COMPRESSED_INTERFACE_BITMAP;
1717+
if ((mono_opt_compressed_interface_bitmap && !compressed_interface_bmap) ||
1718+
(!mono_opt_compressed_interface_bitmap && compressed_interface_bmap)) {
1719+
msg = g_strdup ("mismatch with compressed interface bitmap feature");
1720+
usable = FALSE;
1721+
}
1722+
17161723
*out_msg = msg;
17171724
return usable;
17181725
}

src/mono/mono/mini/aot-runtime.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "mini.h"
1212

1313
/* Version number of the AOT file format */
14-
#define MONO_AOT_FILE_VERSION 186
14+
#define MONO_AOT_FILE_VERSION 187
1515

1616
#define MONO_AOT_TRAMP_PAGE_SIZE 16384
1717

@@ -74,7 +74,8 @@ typedef enum {
7474
MONO_AOT_FILE_FLAG_SEPARATE_DATA = 64,
7575
MONO_AOT_FILE_FLAG_EAGER_LOAD = 128,
7676
MONO_AOT_FILE_FLAG_INTERP = 256,
77-
MONO_AOT_FILE_FLAG_CODE_EXEC_ONLY = 512
77+
MONO_AOT_FILE_FLAG_CODE_EXEC_ONLY = 512,
78+
MONO_AOT_FILE_FLAG_COMPRESSED_INTERFACE_BITMAP = 1024
7879
} MonoAotFileFlags;
7980

8081
typedef enum {

src/mono/mono/mini/mini-runtime.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5091,9 +5091,9 @@ register_icalls (void)
50915091
#endif
50925092
register_icall (mono_ckfinite, mono_icall_sig_double_double, FALSE);
50935093

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

50985098
/* other jit icalls */
50995099
register_icall (ves_icall_mono_delegate_ctor, mono_icall_sig_void_object_object_ptr, FALSE);

0 commit comments

Comments
 (0)