[svn:parrot] r49478 - branches/generational_gc/src/gc

bacek at svn.parrot.org bacek at svn.parrot.org
Fri Oct 8 10:59:00 UTC 2010


Author: bacek
Date: Fri Oct  8 10:59:00 2010
New Revision: 49478
URL: https://trac.parrot.org/parrot/changeset/49478

Log:
Shuffle functions around. Everything is probably broken. Let's start from scratch for mark_and_sweep function

Modified:
   branches/generational_gc/src/gc/gc_ms2.c

Modified: branches/generational_gc/src/gc/gc_ms2.c
==============================================================================
--- branches/generational_gc/src/gc/gc_ms2.c	Fri Oct  8 10:58:24 2010	(r49477)
+++ branches/generational_gc/src/gc/gc_ms2.c	Fri Oct  8 10:59:00 2010	(r49478)
@@ -285,6 +285,10 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+static void gc_ms2_string_mark_propagate(PARROT_INTERP, ARGIN(STRING *s))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 static void gc_ms2_sweep_pmc_cb(PARROT_INTERP, ARGIN(PObj *obj))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -420,6 +424,9 @@
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(str))
+#define ASSERT_ARGS_gc_ms2_string_mark_propagate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_gc_ms2_sweep_pmc_cb __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(obj))
@@ -467,6 +474,240 @@
 
 */
 
+
+/*
+
+=item C<void Parrot_gc_ms2_init(PARROT_INTERP)>
+
+Initializes the infinite memory collector. Installs the necessary function
+pointers into the Memory_Pools structure. The two most important are the
+C<mark_and_sweep> and C<pool_init> functions. C<finalize_gc_system> function
+will be called at Parrot exit and will shut down the GC system if things
+need to be flushed/closed/deactivated/freed/etc. It can be set to NULL if no
+finalization is necessary.
+
+=cut
+
+*/
+
+void
+Parrot_gc_ms2_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_ms2_init)
+    struct MarkSweep_GC *self;
+
+    /* We have to transfer ownership of memory to parent interp in threaded parrot */
+    interp->gc_sys->finalize_gc_system = NULL; /* gc_ms2_finalize; */
+
+    interp->gc_sys->do_gc_mark                  = gc_ms2_mark_and_sweep;
+    interp->gc_sys->compact_string_pool         = gc_ms2_compact_memory_pool;
+
+    /*
+    interp->gc_sys->mark_special                = gc_ms2_mark_special;
+    */
+    interp->gc_sys->pmc_needs_early_collection  = gc_ms2_pmc_needs_early_collection;
+
+    interp->gc_sys->allocate_pmc_header         = gc_ms2_allocate_pmc_header;
+    interp->gc_sys->free_pmc_header             = gc_ms2_free_pmc_header;
+
+    interp->gc_sys->allocate_string_header      = gc_ms2_allocate_string_header;
+    interp->gc_sys->free_string_header          = gc_ms2_free_string_header;
+
+    interp->gc_sys->allocate_bufferlike_header  = gc_ms2_allocate_buffer_header;
+    interp->gc_sys->free_bufferlike_header      = gc_ms2_free_buffer_header;
+
+    interp->gc_sys->allocate_pmc_attributes     = gc_ms2_allocate_pmc_attributes;
+    interp->gc_sys->free_pmc_attributes         = gc_ms2_free_pmc_attributes;
+
+    interp->gc_sys->is_pmc_ptr                  = gc_ms2_is_pmc_ptr;
+    interp->gc_sys->is_string_ptr               = gc_ms2_is_string_ptr;
+    interp->gc_sys->mark_pmc_header             = gc_ms2_mark_pmc_header;
+    interp->gc_sys->mark_str_header             = gc_ms2_mark_string_header;
+
+    interp->gc_sys->block_mark                  = gc_ms2_block_GC_mark;
+    interp->gc_sys->unblock_mark                = gc_ms2_unblock_GC_mark;
+    interp->gc_sys->is_blocked_mark             = gc_ms2_is_blocked_GC_mark;
+
+    interp->gc_sys->block_sweep                 = gc_ms2_block_GC_sweep;
+    interp->gc_sys->unblock_sweep               = gc_ms2_unblock_GC_sweep;
+    interp->gc_sys->is_blocked_sweep            = gc_ms2_is_blocked_GC_sweep;
+
+    interp->gc_sys->allocate_string_storage     = gc_ms2_allocate_string_storage;
+    interp->gc_sys->reallocate_string_storage   = gc_ms2_reallocate_string_storage;
+
+    interp->gc_sys->allocate_buffer_storage     = gc_ms2_allocate_buffer_storage;
+    interp->gc_sys->reallocate_buffer_storage   = gc_ms2_reallocate_buffer_storage;
+
+    interp->gc_sys->allocate_fixed_size_storage = gc_ms2_allocate_fixed_size_storage;
+    interp->gc_sys->free_fixed_size_storage     = gc_ms2_free_fixed_size_storage;
+
+    /* We don't distinguish between chunk and chunk_with_pointers */
+    interp->gc_sys->allocate_memory_chunk       = gc_ms2_allocate_memory_chunk;
+    interp->gc_sys->reallocate_memory_chunk     = gc_ms2_reallocate_memory_chunk;
+    interp->gc_sys->allocate_memory_chunk_with_interior_pointers
+                = gc_ms2_allocate_memory_chunk_zeroed;
+    interp->gc_sys->reallocate_memory_chunk_with_interior_pointers
+                = gc_ms2_reallocate_memory_chunk_zeroed;
+    interp->gc_sys->free_memory_chunk           = gc_ms2_free_memory_chunk;
+
+    interp->gc_sys->iterate_live_strings        = gc_ms2_iterate_live_strings;
+    interp->gc_sys->write_barrier               = gc_ms2_write_barrier;
+
+    interp->gc_sys->get_gc_info                 = gc_ms2_get_gc_info;
+
+    if (interp->parent_interpreter && interp->parent_interpreter->gc_sys) {
+        /* This is a "child" interpreter. Just reuse parent one */
+        self = (MarkSweep_GC*)interp->parent_interpreter->gc_sys->gc_private;
+    }
+    else {
+        self = mem_allocate_zeroed_typed(MarkSweep_GC);
+
+        self->pmc_allocator = Parrot_gc_pool_new(interp,
+            sizeof (List_Item_Header) + sizeof (PMC));
+
+        self->objects[0] = Parrot_list_new(interp);
+        self->objects[1] = Parrot_list_new(interp);
+        self->objects[2] = Parrot_list_new(interp);
+
+        /* Allocate list for gray objects */
+        self->root_objects = Parrot_list_new(interp);
+
+
+        self->string_allocator = Parrot_gc_pool_new(interp,
+            sizeof (List_Item_Header) + sizeof (STRING));
+        self->strings[0] = Parrot_list_new(interp);
+        self->strings[1] = Parrot_list_new(interp);
+        self->strings[2] = Parrot_list_new(interp);
+
+        self->fixed_size_allocator = Parrot_gc_fixed_allocator_new(interp);
+
+        /* Collect every 256M allocated. */
+        /* Hardcode for now. Will be configured via CLI */
+        self->gc_threshold = 1 * 1024 * 1024;
+    }
+    interp->gc_sys->gc_private = self;
+
+    Parrot_gc_str_initialize(interp, &self->string_gc);
+}
+
+static void
+gc_ms2_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
+{
+    ASSERT_ARGS(gc_ms2_mark_and_sweep)
+    MarkSweep_GC      *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
+    List_Item_Header *tmp;
+    Linked_List      *list;
+    size_t            gen;
+    UNUSED(flags);
+
+    /* GC is blocked */
+    if (self->gc_mark_block_level)
+        return;
+
+    if (flags & GC_finish_FLAG) {
+        /* Ignore it. Will cleanup in gc_ms2_finalize */
+        return;
+    }
+
+    /* Ignore calls from String GC. We know better when to trigger GC */
+    if (flags & GC_strings_cb_FLAG) {
+        return;
+    }
+
+    ++self->gc_mark_block_level;
+
+    interp->gc_sys->stats.gc_mark_runs++;
+    /* Which generation we are going to collect? */
+    /* TODO Use less naive approach. E.g. count amount of allocated memory in
+     * older generations */
+    if (0 && interp->gc_sys->stats.gc_mark_runs % 100 == 0)
+        gen = self->current_generation = 2;
+    else if (interp->gc_sys->stats.gc_mark_runs % 10 == 0)
+        gen = self->current_generation = 1;
+    else
+        gen = self->current_generation = 0;
+
+    /* Trace "roots" */
+    gc_ms2_mark_pmc_header(interp, PMCNULL);
+    Parrot_gc_trace_root(interp, NULL, GC_TRACE_FULL);
+    if (interp->pdb && interp->pdb->debugger) {
+        Parrot_gc_trace_root(interp->pdb->debugger, NULL, (Parrot_gc_trace_type)0);
+    }
+
+    /* root_objects are "gray" untill fully marked */
+    /* Additional gray objects will appened to root_objects list */
+    /* So, iterate over them in one go */
+    tmp = self->root_objects->first;
+    while (tmp) {
+        PMC *pmc = LLH2Obj_typed(tmp, PMC);
+        /* if object is a PMC and contains buffers or PMCs, then attach the PMC
+         * to the chained mark list. */
+        if (PObj_is_special_PMC_TEST(pmc)) {
+            if (PObj_custom_mark_TEST(pmc))
+                VTABLE_mark(interp, pmc);
+        }
+
+        if (PMC_metadata(pmc))
+            Parrot_gc_mark_PMC_alive(interp, PMC_metadata(pmc));
+
+        PObj_live_SET(pmc);
+
+        tmp = tmp->next;
+    }
+
+    /* At this point of time root_objects contains only live PMCs */
+    /* objects contains "dead" or "constant" PMCs */
+    /* sweep of root_objects will repaint them white */
+    /* sweep of objects will destroy dead objects leaving only "constant" */
+    gc_ms2_sweep_pool(interp, self->pmc_allocator, self->root_objects, gc_ms2_sweep_pmc_cb);
+
+    /* Depends on current collected generation */
+    gc_ms2_sweep_pool(interp, self->pmc_allocator, self->objects[0], gc_ms2_sweep_pmc_cb);
+    if (gen >= 1)
+        gc_ms2_sweep_pool(interp, self->pmc_allocator, self->objects[1], gc_ms2_sweep_pmc_cb);
+    if (gen >= 2)
+        gc_ms2_sweep_pool(interp, self->pmc_allocator, self->objects[2], gc_ms2_sweep_pmc_cb);
+
+    gc_ms2_sweep_pool(interp, self->string_allocator, self->strings[0], gc_ms2_sweep_string_cb);
+    if (gen >= 1)
+        gc_ms2_sweep_pool(interp, self->string_allocator, self->strings[1], gc_ms2_sweep_string_cb);
+    if (gen >= 2)
+        gc_ms2_sweep_pool(interp, self->string_allocator, self->strings[2], gc_ms2_sweep_string_cb);
+
+    /* Root objects can contains PMCs from older generations. Put them into proper list */
+    tmp = self->root_objects->first;
+    while (tmp) {
+        List_Item_Header *next = tmp->next;
+        PMC              *pmc  = LLH2Obj_typed(tmp, PMC);
+
+        if (PObj_to_generation(pmc)) {
+            LIST_REMOVE(self->root_objects, tmp);
+            LIST_APPEND(self->objects[PObj_to_generation(pmc)], tmp);
+        }
+
+        tmp = next;
+    }
+
+    /* TODO Handle oldest generation */
+    /* Propagate survived objects into older generation */
+    if (gen != 2) {
+        gc_ms2_propagate_to_older_generation(interp, gen, self->objects[gen], self->objects[gen+1]);
+
+        while (self->root_objects->first)
+            gc_ms2_propagate_to_older_generation(interp, gen, self->root_objects, self->objects[gen+1]);
+
+        gc_ms2_propagate_to_older_generation(interp, gen, self->strings[gen], self->strings[gen+1]);
+    }
+
+    interp->gc_sys->stats.header_allocs_since_last_collect = 0;
+    interp->gc_sys->stats.mem_used_last_collect            = 0;
+    self->gc_mark_block_level--;
+    /* We swept all dead objects */
+    self->num_early_gc_PMCs                      = 0;
+
+    gc_ms2_compact_memory_pool(interp);
+}
+
 /*
 
 =item C<static void gc_ms2_compact_memory_pool(PARROT_INTERP)>
@@ -603,122 +844,6 @@
 
 
 
-
-/*
-
-=item C<void Parrot_gc_ms2_init(PARROT_INTERP)>
-
-Initializes the infinite memory collector. Installs the necessary function
-pointers into the Memory_Pools structure. The two most important are the
-C<mark_and_sweep> and C<pool_init> functions. C<finalize_gc_system> function
-will be called at Parrot exit and will shut down the GC system if things
-need to be flushed/closed/deactivated/freed/etc. It can be set to NULL if no
-finalization is necessary.
-
-=cut
-
-*/
-
-void
-Parrot_gc_ms2_init(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_gc_ms2_init)
-    struct MarkSweep_GC *self;
-
-    /* We have to transfer ownership of memory to parent interp in threaded parrot */
-    interp->gc_sys->finalize_gc_system = NULL; /* gc_ms2_finalize; */
-
-    interp->gc_sys->do_gc_mark                  = gc_ms2_mark_and_sweep;
-    interp->gc_sys->compact_string_pool         = gc_ms2_compact_memory_pool;
-
-    /*
-    interp->gc_sys->mark_special                = gc_ms2_mark_special;
-    */
-    interp->gc_sys->pmc_needs_early_collection  = gc_ms2_pmc_needs_early_collection;
-
-    interp->gc_sys->allocate_pmc_header         = gc_ms2_allocate_pmc_header;
-    interp->gc_sys->free_pmc_header             = gc_ms2_free_pmc_header;
-
-    interp->gc_sys->allocate_string_header      = gc_ms2_allocate_string_header;
-    interp->gc_sys->free_string_header          = gc_ms2_free_string_header;
-
-    interp->gc_sys->allocate_bufferlike_header  = gc_ms2_allocate_buffer_header;
-    interp->gc_sys->free_bufferlike_header      = gc_ms2_free_buffer_header;
-
-    interp->gc_sys->allocate_pmc_attributes     = gc_ms2_allocate_pmc_attributes;
-    interp->gc_sys->free_pmc_attributes         = gc_ms2_free_pmc_attributes;
-
-    interp->gc_sys->is_pmc_ptr                  = gc_ms2_is_pmc_ptr;
-    interp->gc_sys->is_string_ptr               = gc_ms2_is_string_ptr;
-    interp->gc_sys->mark_pmc_header             = gc_ms2_mark_pmc_header;
-    interp->gc_sys->mark_str_header             = gc_ms2_mark_string_header;
-
-    interp->gc_sys->block_mark                  = gc_ms2_block_GC_mark;
-    interp->gc_sys->unblock_mark                = gc_ms2_unblock_GC_mark;
-    interp->gc_sys->is_blocked_mark             = gc_ms2_is_blocked_GC_mark;
-
-    interp->gc_sys->block_sweep                 = gc_ms2_block_GC_sweep;
-    interp->gc_sys->unblock_sweep               = gc_ms2_unblock_GC_sweep;
-    interp->gc_sys->is_blocked_sweep            = gc_ms2_is_blocked_GC_sweep;
-
-    interp->gc_sys->allocate_string_storage     = gc_ms2_allocate_string_storage;
-    interp->gc_sys->reallocate_string_storage   = gc_ms2_reallocate_string_storage;
-
-    interp->gc_sys->allocate_buffer_storage     = gc_ms2_allocate_buffer_storage;
-    interp->gc_sys->reallocate_buffer_storage   = gc_ms2_reallocate_buffer_storage;
-
-    interp->gc_sys->allocate_fixed_size_storage = gc_ms2_allocate_fixed_size_storage;
-    interp->gc_sys->free_fixed_size_storage     = gc_ms2_free_fixed_size_storage;
-
-    /* We don't distinguish between chunk and chunk_with_pointers */
-    interp->gc_sys->allocate_memory_chunk       = gc_ms2_allocate_memory_chunk;
-    interp->gc_sys->reallocate_memory_chunk     = gc_ms2_reallocate_memory_chunk;
-    interp->gc_sys->allocate_memory_chunk_with_interior_pointers
-                = gc_ms2_allocate_memory_chunk_zeroed;
-    interp->gc_sys->reallocate_memory_chunk_with_interior_pointers
-                = gc_ms2_reallocate_memory_chunk_zeroed;
-    interp->gc_sys->free_memory_chunk           = gc_ms2_free_memory_chunk;
-
-    interp->gc_sys->iterate_live_strings        = gc_ms2_iterate_live_strings;
-    interp->gc_sys->write_barrier               = gc_ms2_write_barrier;
-
-    interp->gc_sys->get_gc_info                 = gc_ms2_get_gc_info;
-
-    if (interp->parent_interpreter && interp->parent_interpreter->gc_sys) {
-        /* This is a "child" interpreter. Just reuse parent one */
-        self = (MarkSweep_GC*)interp->parent_interpreter->gc_sys->gc_private;
-    }
-    else {
-        self = mem_allocate_zeroed_typed(MarkSweep_GC);
-
-        self->pmc_allocator = Parrot_gc_pool_new(interp,
-            sizeof (List_Item_Header) + sizeof (PMC));
-
-        self->objects[0] = Parrot_list_new(interp);
-        self->objects[1] = Parrot_list_new(interp);
-        self->objects[2] = Parrot_list_new(interp);
-
-        /* Allocate list for gray objects */
-        self->root_objects = Parrot_list_new(interp);
-
-
-        self->string_allocator = Parrot_gc_pool_new(interp,
-            sizeof (List_Item_Header) + sizeof (STRING));
-        self->strings[0] = Parrot_list_new(interp);
-        self->strings[1] = Parrot_list_new(interp);
-        self->strings[2] = Parrot_list_new(interp);
-
-        self->fixed_size_allocator = Parrot_gc_fixed_allocator_new(interp);
-
-        /* Collect every 256M allocated. */
-        /* Hardcode for now. Will be configured via CLI */
-        self->gc_threshold = 1 * 1024 * 1024;
-    }
-    interp->gc_sys->gc_private = self;
-
-    Parrot_gc_str_initialize(interp, &self->string_gc);
-}
-
 /*
 =item C<static void gc_ms2_finalize(PARROT_INTERP)>
 
@@ -826,9 +951,6 @@
 
     LIST_REMOVE(self->objects[gen], item);
     LIST_APPEND(self->root_objects, item);
-    /* Move to young generation */
-    pmc->flags &= ~(PObj_GC_generation_0_FLAG | PObj_GC_generation_1_FLAG);
-
 }
 
 /*
@@ -1036,7 +1158,7 @@
 */
 
 static void
-gc_ms2_mark_string_header(PARROT_INTERP, ARGIN(STRING *str))
+gc_ms2_mark_string_header(PARROT_INTERP, ARGIN_NULLOK(STRING *str))
 {
     ASSERT_ARGS(gc_ms2_mark_string_header)
     MarkSweep_GC      *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
@@ -1057,35 +1179,6 @@
 
     /* mark it live */
     PObj_live_SET(str);
-
-    /* Move to young generation */
-    if (gen) {
-        LIST_REMOVE(self->strings[gen], item);
-        LIST_APPEND(self->strings[0], item);
-        str->flags &= ~(PObj_GC_generation_0_FLAG | PObj_GC_generation_1_FLAG);
-    }
-}
-/*
-
-=item C<static void gc_ms2_mark_pobj_header(PARROT_INTERP, PObj * obj)>
-
-Mark PObj as live.
-
-=cut
-
-*/
-
-static void
-gc_ms2_mark_pobj_header(PARROT_INTERP, ARGIN_NULLOK(PObj * obj))
-{
-    ASSERT_ARGS(gc_ms2_mark_pobj_header)
-    if (obj) {
-        if (PObj_is_PMC_TEST(obj))
-            gc_ms2_mark_pmc_header(interp, (PMC *)obj);
-        else {
-            gc_ms2_mark_string_header(interp, (STRING *)obj);
-        }
-    }
 }
 
 /*
@@ -1160,120 +1253,6 @@
     }
 }
 
-static void
-gc_ms2_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
-{
-    ASSERT_ARGS(gc_ms2_mark_and_sweep)
-    MarkSweep_GC      *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
-    List_Item_Header *tmp;
-    Linked_List      *list;
-    size_t            gen;
-    UNUSED(flags);
-
-    /* GC is blocked */
-    if (self->gc_mark_block_level)
-        return;
-
-    if (flags & GC_finish_FLAG) {
-        /* Ignore it. Will cleanup in gc_ms2_finalize */
-        return;
-    }
-
-    /* Ignore calls from String GC. We know better when to trigger GC */
-    if (flags & GC_strings_cb_FLAG) {
-        return;
-    }
-
-    ++self->gc_mark_block_level;
-
-    interp->gc_sys->stats.gc_mark_runs++;
-    /* Which generation we are going to collect? */
-    /* TODO Use less naive approach. E.g. count amount of allocated memory in
-     * older generations */
-    if (0 && interp->gc_sys->stats.gc_mark_runs % 100 == 0)
-        gen = self->current_generation = 2;
-    else if (interp->gc_sys->stats.gc_mark_runs % 10 == 0)
-        gen = self->current_generation = 1;
-    else
-        gen = self->current_generation = 0;
-
-    /* Trace "roots" */
-    gc_ms2_mark_pmc_header(interp, PMCNULL);
-    Parrot_gc_trace_root(interp, NULL, GC_TRACE_FULL);
-    if (interp->pdb && interp->pdb->debugger) {
-        Parrot_gc_trace_root(interp->pdb->debugger, NULL, (Parrot_gc_trace_type)0);
-    }
-
-    /* root_objects are "gray" untill fully marked */
-    /* Additional gray objects will appened to root_objects list */
-    /* So, iterate over them in one go */
-    tmp = self->root_objects->first;
-    while (tmp) {
-        PMC *pmc = LLH2Obj_typed(tmp, PMC);
-        /* if object is a PMC and contains buffers or PMCs, then attach the PMC
-         * to the chained mark list. */
-        if (PObj_is_special_PMC_TEST(pmc)) {
-            if (PObj_custom_mark_TEST(pmc))
-                VTABLE_mark(interp, pmc);
-        }
-
-        if (PMC_metadata(pmc))
-            Parrot_gc_mark_PMC_alive(interp, PMC_metadata(pmc));
-
-        PObj_live_SET(pmc);
-
-        tmp = tmp->next;
-    }
-
-    /* At this point of time root_objects contains only live PMCs */
-    /* objects contains "dead" or "constant" PMCs */
-    /* sweep of root_objects will repaint them white */
-    /* sweep of objects will destroy dead objects leaving only "constant" */
-    gc_ms2_sweep_pool(interp, self->pmc_allocator, self->root_objects, gc_ms2_sweep_pmc_cb);
-
-    /* Depends on current collected generation */
-    gc_ms2_sweep_pool(interp, self->pmc_allocator, self->objects[0], gc_ms2_sweep_pmc_cb);
-    if (gen >= 1)
-        gc_ms2_sweep_pool(interp, self->pmc_allocator, self->objects[1], gc_ms2_sweep_pmc_cb);
-    if (gen >= 2)
-        gc_ms2_sweep_pool(interp, self->pmc_allocator, self->objects[2], gc_ms2_sweep_pmc_cb);
-
-    gc_ms2_sweep_pool(interp, self->string_allocator, self->strings[0], gc_ms2_sweep_string_cb);
-    if (gen >= 1)
-        gc_ms2_sweep_pool(interp, self->string_allocator, self->strings[1], gc_ms2_sweep_string_cb);
-    if (gen >= 2)
-        gc_ms2_sweep_pool(interp, self->string_allocator, self->strings[2], gc_ms2_sweep_string_cb);
-
-    /* TODO */
-    /* Replace objects with root_objects. Ignoring "constant" one */
-    list = self->objects[0];
-    self->objects[0] = self->root_objects;
-
-    /* Cleanup old list */
-    list->first = list->last = NULL;
-    list->count = 0;
-    self->root_objects = list;
-
-    /* TODO Handle oldest generation */
-    /* Propagate survived objects into older generation */
-    if (gen != 2) {
-        gc_ms2_propagate_to_older_generation(interp, gen, self->objects[gen], self->objects[gen+1]);
-
-        while (self->root_objects->first)
-            gc_ms2_propagate_to_older_generation(interp, gen, self->root_objects, self->objects[gen+1]);
-
-        gc_ms2_propagate_to_older_generation(interp, gen, self->strings[gen], self->strings[gen+1]);
-    }
-
-    interp->gc_sys->stats.header_allocs_since_last_collect = 0;
-    interp->gc_sys->stats.mem_used_last_collect            = 0;
-    self->gc_mark_block_level--;
-    /* We swept all dead objects */
-    self->num_early_gc_PMCs                      = 0;
-
-    gc_ms2_compact_memory_pool(interp);
-}
-
 /*
 
 =item C<static void gc_ms2_propagate_to_older_generation(PARROT_INTERP, size_t
@@ -1312,7 +1291,7 @@
                 /* Move into older generation */
                 LIST_REMOVE(from, tmp);
                 LIST_APPEND(to, tmp);
-                obj->flags &= ~(PObj_GC_generation_0_FLAG | PObj_GC_generation_1_FLAG);
+                obj->flags &= ~(PObj_GC_generation_0_FLAG | PObj_GC_generation_1_FLAG | PObj_GC_generation_2_FLAG);
                 obj->flags |= generation_to_flags(current_gen);
 
                 if (PObj_is_PMC_TEST(obj)) {
@@ -1347,6 +1326,7 @@
     if (to->first && PObj_is_PMC_TEST(LLH2Obj_typed(to->first, PObj))) {
         size_t count = 0;
         interp->gc_sys->mark_pmc_header = gc_ms2_vtable_mark_propagate;
+        interp->gc_sys->mark_str_header = gc_ms2_string_mark_propagate;
 
         tmp = previous_last
               ? previous_last->next
@@ -1361,6 +1341,7 @@
         }
 
         //fprintf(stderr, "count: %d\n", count);
+        interp->gc_sys->mark_str_header = gc_ms2_mark_string_header;
         interp->gc_sys->mark_pmc_header = gc_ms2_mark_pmc_header;
     }
 
@@ -1374,7 +1355,7 @@
     size_t             gen  = PObj_to_generation(pmc);
 
     /* Objects from older generation will stay */
-    if (gen > self->current_generation)
+    if (gen >= self->current_generation)
         return;
 
     /* "Constant"... */
@@ -1389,6 +1370,30 @@
     pmc->flags |= PObj_GC_generation_2_FLAG;
 }
 
+static void
+gc_ms2_string_mark_propagate(PARROT_INTERP, ARGIN(STRING *s))
+{
+    MarkSweep_GC      *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
+    List_Item_Header  *item = Obj2LLH(s);
+    size_t             gen  = PObj_to_generation(s);
+
+    PARROT_ASSERT(item->owner == self->strings[gen]);
+
+    /* Objects from older generation will stay */
+    if (gen >= self->current_generation)
+        return;
+
+    /* "Constant"... */
+    if (s->flags & PObj_constant_FLAG)
+        return;
+
+    if (s->flags & PObj_GC_generation_2_FLAG)
+        return;
+
+    LIST_REMOVE(self->strings[gen], item);
+    LIST_REMOVE(self->strings[self->current_generation], item);
+    s->flags |= generation_to_flags(self->current_generation) | PObj_GC_generation_2_FLAG;
+}
 /*
 =item C<static void gc_ms2_sweep_pool(PARROT_INTERP, Pool_Allocator *pool,
 Linked_List *list, sweep_cb callback)>
@@ -1718,7 +1723,6 @@
 
     LIST_REMOVE(self->objects[PObj_to_generation(pmc)], item);
     LIST_APPEND(self->root_objects, item);
-    pmc->flags &= ~(PObj_GC_generation_0_FLAG | PObj_GC_generation_1_FLAG);
     PObj_live_SET(pmc);
 }
 


More information about the parrot-commits mailing list