Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base: master
...
compare: whiteknight/gc_two_stage_sweep
Checking mergeability… Don't worry, you can still create the pull request.
  • 1 commit
  • 1 file changed
  • 0 commit comments
  • 1 contributor
Commits on May 11, 2012
@Whiteknight Whiteknight Implement 2-pass sweep.
Sweep all generations looking for dead PMCs. Call VTABLE_destroy if necessary and add them to a dead_list. Next, iterate the dead_list, freeing memory. This scheme should completely avoid order-of-destruction issues, because all PMCs are kept alive until all destroy vtables are called. moritz++ for the idea. bacek++ for writing such easy-to-hack GC code.
0f8993b
Showing with 31 additions and 8 deletions.
  1. +31 −8 src/gc/gc_gms.c
View
39 src/gc/gc_gms.c
@@ -842,7 +842,7 @@ gc_gms_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
self->gc_mark_block_level--;
/* We swept all dead objects */
- self->num_early_gc_PMCs = 0;
+ self->num_early_gc_PMCs = 0;
/* Don't compact after nursery collection */
if (gen)
@@ -1051,6 +1051,12 @@ gc_gms_sweep_pools(PARROT_INTERP, ARGMOD(MarkSweep_GC *self))
INTVAL i;
+ Parrot_Pointer_Array * const dead_list = Parrot_pa_new(interp);
+
+ /* Sweep over all objects in each generation. For each object, if it's
+ still alive, bump it up to the next generation. Objects in the last
+ generation don't go any higher. For objects which are dead we call
+ VTABLE_destroy if necessary and add it to a sweep list */
for (i = self->gen_to_collect; i >= 0; i--) {
/* Don't move to generation beyond last */
const int move_to_old = (i + 1) != MAX_GENERATIONS;
@@ -1090,15 +1096,32 @@ gc_gms_sweep_pools(PARROT_INTERP, ARGMOD(MarkSweep_GC *self))
if (PObj_custom_destroy_TEST(pmc))
VTABLE_destroy(interp, pmc);
- if (pmc->vtable->attr_size && PMC_data(pmc))
- Parrot_gc_free_pmc_attributes(interp, pmc);
- PMC_data(pmc) = NULL;
+ Parrot_pa_insert(dead_list, item);
+ }
+ );
+ }
- PObj_on_free_list_SET(pmc);
- PObj_gc_CLEAR(pmc);
+ POINTER_ARRAY_ITER(dead_list,
+ pmc_alloc_struct * const item = (pmc_alloc_struct *)ptr;
+ PMC * const pmc = &(item->pmc);
- Parrot_gc_pool_free(interp, self->pmc_allocator, ptr);
- });
+ if (pmc->vtable->attr_size && PMC_data(pmc))
+ Parrot_gc_free_pmc_attributes(interp, pmc);
+ PMC_data(pmc) = NULL;
+
+ PObj_on_free_list_SET(pmc);
+ PObj_gc_CLEAR(pmc);
+
+ Parrot_gc_pool_free(interp, self->pmc_allocator, ptr);
+ );
+ Parrot_pa_destroy(interp, dead_list);
+
+ /* Sweep over all string pools performing the same operation. If alive,
+ bump the string to the next generation up to MAX_GENERATIONS. If
+ dead, reclaim the memory */
+ for (i = self->gen_to_collect; i >= 0; i--) {
+ /* Don't move to generation beyond last */
+ const int move_to_old = (i + 1) != MAX_GENERATIONS;
POINTER_ARRAY_ITER(self->strings[i],
string_alloc_struct * const item = (string_alloc_struct *)ptr;

No commit comments for this range

Something went wrong with that request. Please try again.