void Parrot_gc_sweep_pool(PARROT_INTERP, ARGMOD(Memory_Pools *mem_pools), ARGMOD(Fixed_Size_Pool *pool)) { ASSERT_ARGS(Parrot_gc_sweep_pool) PObj *b; Fixed_Size_Arena *cur_arena; UINTVAL total_used = 0; const UINTVAL object_size = pool->object_size; const gc_object_fn_type gc_object = pool->gc_object; const add_free_object_fn_type add_free_object = pool->add_free_object; /* Run through all the PObj header pools and mark */ for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) { const size_t objects_end = cur_arena->used; UINTVAL i; b = (PObj *)cur_arena->start_objects; /* loop only while there are objects in the arena */ for (i = objects_end; i; --i) { /* if it's on free list, do nothing */ if (PObj_live_TEST(b)) { ++total_used; PObj_live_CLEAR(b); PObj_get_FLAGS(b) &= ~PObj_custom_GC_FLAG; } else if (!PObj_on_free_list_TEST(b)) { /* it must be dead */ if (PObj_is_shared_TEST(b)) { /* only mess with shared objects if we * (and thus everyone) is suspended for * a GC run. * XXX wrong thing to do with "other" GCs */ if (!(interp->thread_data && (interp->thread_data->state & THREAD_STATE_SUSPENDED_GC))) { ++total_used; goto next; } } if (gc_object) gc_object(interp, mem_pools, pool, b); add_free_object(interp, mem_pools, pool, b); } next: b = (PObj *)((char *)b + object_size); } } pool->num_free_objects = pool->total_objects - total_used; }
void Parrot_gc_clear_live_bits(SHIM_INTERP, ARGIN(const Fixed_Size_Pool *pool)) { ASSERT_ARGS(Parrot_gc_clear_live_bits) Fixed_Size_Arena *arena; const UINTVAL object_size = pool->object_size; for (arena = pool->last_Arena; arena; arena = arena->prev) { Buffer *b = (Buffer *)arena->start_objects; UINTVAL i; for (i = 0; i < arena->used; ++i) { PObj_live_CLEAR(b); b = (Buffer *)((char *)b + object_size); } } }