Skip to content

Commit 2cc52c2

Browse files
authored
[wasm] Fix sharing of wbarrier card between los object and wbarrier roots (#118271)
In the change disabling los section allocator on wasm (via sgen_los_enable_sections_allocator), we aligned these los objects to 512 bytes, which is the memory range mapped by a card byte. This alignment prevented two los objects having memory mapped to the same card. Sharing with other objects is impossible since they are allocated in separate spaces with high alignment (the nursery and major blocks). There was however an oversight, which is the possibility of having wbarrier roots allocated in this space (These roots are just variable sized memory ranges containing refs, that are scanned only if the corresponding card is marked). In this situation, scanning the cards for the los object could end up clearing cards for these roots that will no longer be scanned
1 parent 41c675e commit 2cc52c2

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,14 +477,20 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size)
477477
}
478478
} else if (!sgen_los_enable_sections_allocator) {
479479
size_t alloc_size = size + sizeof (LOSObject);
480+
#ifndef SGEN_HAVE_OVERLAPPING_CARDS
481+
// While other objects can't be allocated after the los object (in a memory sharing a card with the los object),
482+
// we could still have wbarrier roots allocated there, since they don't have alignment requirement. This means that
483+
// clearing a card from this object would prevent scanning of refs in the wbarrier roots.
484+
alloc_size = SGEN_ALIGN_UP_TO (alloc_size, CARD_SIZE_IN_BYTES);
485+
#endif
480486
if (sgen_memgov_try_alloc_space (alloc_size, SPACE_LOS)) {
481-
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
482-
int alignment = SGEN_ALLOC_ALIGN;
483-
#else
487+
#ifndef SGEN_HAVE_OVERLAPPING_CARDS
484488
// If we don't use the shadow card table, having a card map to 2 different los objects is invalid
485489
// because once we scan the first object we could clear the card, leading to failure to detect refs
486490
// in the second object. We prevent this by aligning the los object to the card size.
487491
int alignment = CARD_SIZE_IN_BYTES;
492+
#else
493+
int alignment = SGEN_ALLOC_ALIGN;
488494
#endif
489495
obj = (LOSObject *)sgen_alloc_os_memory_aligned (alloc_size, alignment, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL, MONO_MEM_ACCOUNT_SGEN_LOS);
490496
if (obj)

0 commit comments

Comments
 (0)