From 9c4fc97ce3563faab7e0a31f8ab9b61f7596d2be Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 11 Apr 2024 13:25:54 +0300 Subject: [PATCH 1/2] [mono][interp] Fix resizing of ref slots bitset In rare cases it can happen that doubling the capacity won't fit all ref slots for the var, in case it is a large VT. --- src/mono/mono/mini/interp/transform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 814d5af9a8c9a..a0d088b19e27b 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -8585,6 +8585,8 @@ interp_mark_ref_slots_for_var (TransformData *td, int var) if (!td->ref_slots || max_index >= td->ref_slots->size) { guint32 old_size = td->ref_slots ? (guint32)td->ref_slots->size : 0; guint32 new_size = old_size ? old_size * 2 : 32; + while (new_size <= max_index) + new_size *= 2; gpointer mem = mono_mempool_alloc0 (td->mempool, mono_bitset_alloc_size (new_size, 0)); MonoBitSet *new_ref_slots = mono_bitset_mem_new (mem, new_size, 0); From 4011e1bbba386d4e0adcb4c305f7ee552aac05e9 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 11 Apr 2024 13:27:39 +0300 Subject: [PATCH 2/2] [mono][interp] Use asserting version of bitset set Since it is not a hot path anyway. --- src/mono/mono/mini/interp/transform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index a0d088b19e27b..1065becef752c 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -8553,7 +8553,7 @@ interp_mark_ref_slots_for_vt (TransformData *td, int base_offset, MonoClass *kla retry: if (mini_type_is_reference (ftype) || ftype->type == MONO_TYPE_I || ftype->type == MONO_TYPE_U || m_type_is_byref (ftype)) { int index = offset / sizeof (gpointer); - mono_bitset_set_fast (td->ref_slots, index); + mono_bitset_set (td->ref_slots, index); if (td->verbose_level) g_print ("Stack ref slot vt field at off %d\n", offset); } else if (ftype->type == MONO_TYPE_VALUETYPE || ftype->type == MONO_TYPE_GENERICINST) { @@ -8604,7 +8604,7 @@ interp_mark_ref_slots_for_var (TransformData *td, int var) // Managed pointers in interp are normally MONO_TYPE_I if (mini_type_is_reference (type) || type->type == MONO_TYPE_I || type->type == MONO_TYPE_U || m_type_is_byref (type)) { int index = td->vars [var].offset / sizeof (gpointer); - mono_bitset_set_fast (td->ref_slots, index); + mono_bitset_set (td->ref_slots, index); if (td->verbose_level) g_print ("Stack ref slot at off %d for var %d\n", index * sizeof (gpointer), var); }