diff --git a/src/copy-space.h b/src/copy-space.h index bd2df7334..0fbf4b111 100644 --- a/src/copy-space.h +++ b/src/copy-space.h @@ -529,9 +529,30 @@ copy_space_flip(struct copy_space *space) { space->in_gc = 1; } +static inline void +copy_space_allocator_init(struct copy_space_allocator *alloc) { + memset(alloc, 0, sizeof(*alloc)); +} + +static inline void +copy_space_allocator_finish(struct copy_space_allocator *alloc, + struct copy_space *space) { + if (alloc->block) + copy_space_allocator_release_partly_full_block(alloc, space); +} + static void -copy_space_finish_gc(struct copy_space *space) { +copy_space_finish_gc(struct copy_space *space, int is_minor_gc) { // Mutators stopped, can access nonatomically. + if (is_minor_gc) { + // Avoid mixing survivors and new objects on the same blocks. + struct copy_space_allocator alloc; + copy_space_allocator_init(&alloc); + while (copy_space_allocator_acquire_partly_full_block(&alloc, space)) + copy_space_allocator_release_full_block(&alloc, space); + copy_space_allocator_finish(&alloc, space); + } + space->allocated_bytes_at_last_gc = space->allocated_bytes; space->fragmentation_at_last_gc = space->fragmentation; space->in_gc = 0; @@ -778,18 +799,6 @@ copy_space_forget_edge(struct copy_space *space, struct gc_edge edge) { return 1; } -static inline void -copy_space_allocator_init(struct copy_space_allocator *alloc) { - memset(alloc, 0, sizeof(*alloc)); -} - -static inline void -copy_space_allocator_finish(struct copy_space_allocator *alloc, - struct copy_space *space) { - if (alloc->block) - copy_space_allocator_release_partly_full_block(alloc, space); -} - static size_t copy_space_is_power_of_two(size_t n) { GC_ASSERT(n != 0); return (n & (n - 1)) == 0; diff --git a/src/pcc.c b/src/pcc.c index 7ee017ae2..ff10375ef 100644 --- a/src/pcc.c +++ b/src/pcc.c @@ -774,11 +774,12 @@ copy_spaces_start_gc(struct gc_heap *heap, int is_minor_gc) { static void copy_spaces_finish_gc(struct gc_heap *heap, int is_minor_gc) { if (GC_GENERATIONAL) { - copy_space_finish_gc(heap_new_space(heap)); + copy_space_finish_gc(heap_new_space(heap), is_minor_gc); if (!is_minor_gc) - copy_space_finish_gc(heap_old_space(heap)); + copy_space_finish_gc(heap_old_space(heap), 0); } else { - copy_space_finish_gc(heap_mono_space(heap)); + GC_ASSERT(!is_minor_gc); + copy_space_finish_gc(heap_mono_space(heap), 0); } }