Skip to content

Commit 02596ba

Browse files
authored
[wasm] Fix fragmentation caused by large objects allocation (#118099)
1 parent 123627b commit 02596ba

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

src/mono/mono/sgen/sgen-los.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ mword sgen_los_memory_usage = 0;
125125
/* Total memory used by the LOS allocator */
126126
mword sgen_los_memory_usage_total = 0;
127127

128+
#ifdef HOST_WASM
129+
const gboolean sgen_los_enable_sections_allocator = 0;
130+
#else
131+
const gboolean sgen_los_enable_sections_allocator = 1;
132+
#endif
133+
128134
static LOSSection *los_sections = NULL;
129135
static LOSFreeChunks *los_fast_free_lists [LOS_NUM_FAST_SIZES]; /* 0 is for larger sizes */
130136
static mword los_num_objects = 0;
@@ -156,6 +162,9 @@ los_consistency_check (void)
156162
int i;
157163
mword memory_usage = 0;
158164

165+
if (!sgen_los_enable_sections_allocator)
166+
return;
167+
159168
FOREACH_LOS_OBJECT_NO_LOCK (obj) {
160169
mword obj_size = sgen_los_object_size (obj);
161170
char *end = obj->data + obj_size;
@@ -400,6 +409,11 @@ sgen_los_free_object (LOSObject *obj)
400409
sgen_free_os_memory ((gpointer)SGEN_ALIGN_DOWN_TO ((mword)obj, pagesize), size, SGEN_ALLOC_HEAP, MONO_MEM_ACCOUNT_SGEN_LOS);
401410
sgen_los_memory_usage_total -= size;
402411
sgen_memgov_release_space (size, SPACE_LOS);
412+
} else if (!sgen_los_enable_sections_allocator) {
413+
size += sizeof (LOSObject);
414+
sgen_free_os_memory (obj, size, SGEN_ALLOC_HEAP, MONO_MEM_ACCOUNT_SGEN_LOS);
415+
sgen_los_memory_usage_total -= size;
416+
sgen_memgov_release_space (size, SPACE_LOS);
403417
} else {
404418
free_los_section_memory (obj, size + sizeof (LOSObject));
405419
#ifdef LOS_CONSISTENCY_CHECKS
@@ -461,6 +475,21 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size)
461475
obj = randomize_los_object_start (obj, obj_size, alloc_size, pagesize);
462476
}
463477
}
478+
} else if (!sgen_los_enable_sections_allocator) {
479+
size_t alloc_size = size + sizeof (LOSObject);
480+
if (sgen_memgov_try_alloc_space (alloc_size, SPACE_LOS)) {
481+
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
482+
int alignment = SGEN_ALLOC_ALIGN;
483+
#else
484+
// If we don't use the shadow card table, having a card map to 2 different los objects is invalid
485+
// because once we scan the first object we could clear the card, leading to failure to detect refs
486+
// in the second object. We prevent this by aligning the los object to the card size.
487+
int alignment = CARD_SIZE_IN_BYTES;
488+
#endif
489+
obj = (LOSObject *)sgen_alloc_os_memory_aligned (alloc_size, alignment, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL, MONO_MEM_ACCOUNT_SGEN_LOS);
490+
if (obj)
491+
sgen_los_memory_usage_total += alloc_size;
492+
}
464493
} else {
465494
obj = get_los_section_memory (size + sizeof (LOSObject));
466495
if (obj)

0 commit comments

Comments
 (0)