[svn:parrot] r49365 - branches/generational_gc/src/gc
bacek at svn.parrot.org
bacek at svn.parrot.org
Tue Sep 28 11:02:57 UTC 2010
Author: bacek
Date: Tue Sep 28 11:02:56 2010
New Revision: 49365
URL: https://trac.parrot.org/parrot/changeset/49365
Log:
Awful hack - reuse VTABLE_mark to propagate objects between generations. WIP, broken, etc
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 Tue Sep 28 10:29:11 2010 (r49364)
+++ branches/generational_gc/src/gc/gc_ms2.c Tue Sep 28 11:02:56 2010 (r49365)
@@ -311,6 +311,10 @@
static void gc_ms2_unblock_GC_sweep(PARROT_INTERP)
__attribute__nonnull__(1);
+static void gc_ms2_vtable_mark_propagate(PARROT_INTERP, ARGIN(PMC *pmc))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
static void gc_ms2_write_barrier(PARROT_INTERP, ARGIN(PMC *pmc))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
@@ -436,6 +440,9 @@
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_ms2_unblock_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_gc_ms2_vtable_mark_propagate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(pmc))
#define ASSERT_ARGS_gc_ms2_write_barrier __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pmc))
@@ -1256,6 +1263,10 @@
/* 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]);
}
@@ -1287,46 +1298,100 @@
{
ASSERT_ARGS(gc_ms2_propagate_to_older_generation)
List_Item_Header *next, *tmp = from->first;
+ List_Item_Header *previous_last = to->last;
+
++current_gen;
while (tmp) {
PObj * obj = LLH2Obj_typed(tmp, PObj);
next = tmp->next;
- /* We can't do such a naive check for "survived" objects */
- /* If PMC "A" survived first collection */
- /* Then PMC "B" was added to it */
- /* We'll move "A" into older generation */
- /* But keep "B" in younger */
- /* Kaboom. "B" collected prematurely on next run */
- if (1 || obj->flags & PObj_GC_generation_2_FLAG) {
- /* 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 |= generation_to_flags(current_gen);
-
- if (PObj_is_PMC_TEST(obj)) {
- PMC *pmc = (PMC *)obj;
- VTABLE *t = pmc->vtable;
+ if (!PObj_constant_TEST(obj)) {
- PARROT_ASSERT(pmc->vtable);
- PARROT_ASSERT(pmc->vtable->wb_variant_vtable);
+ /* We can't do such a naive check for "survived" objects */
+ /* If PMC "A" survived first collection */
+ /* Then PMC "B" was added to it */
+ /* We'll move "A" into older generation */
+ /* But keep "B" in younger */
+ /* Kaboom. "B" collected prematurely on next run */
+ if (1 || obj->flags & PObj_GC_generation_2_FLAG) {
+ /* 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 |= generation_to_flags(current_gen);
+
+ if (PObj_is_PMC_TEST(obj)) {
+ PMC *pmc = (PMC *)obj;
+ VTABLE *t = pmc->vtable;
+
+ PARROT_ASSERT(pmc->vtable);
+ PARROT_ASSERT(pmc->vtable->wb_variant_vtable);
- pmc->vtable = pmc->vtable->wb_variant_vtable;
- pmc->vtable->wb_variant_vtable = t;
+ pmc->vtable = pmc->vtable->wb_variant_vtable;
+ pmc->vtable->wb_variant_vtable = t;
- PARROT_ASSERT(pmc->vtable != pmc->vtable->wb_variant_vtable);
- PARROT_ASSERT(pmc->vtable != pmc->vtable->ro_variant_vtable);
+ PARROT_ASSERT(pmc->vtable != pmc->vtable->wb_variant_vtable);
+ PARROT_ASSERT(pmc->vtable != pmc->vtable->ro_variant_vtable);
+ }
+ }
+ else {
+ /* First time survival. */
+ obj->flags |= PObj_GC_generation_2_FLAG;
}
- }
- else {
- /* First time survival. */
- obj->flags |= PObj_GC_generation_2_FLAG;
}
tmp = next;
}
+
+ /* Ugly, awful, terrible hack. I'm not even trying to find excuse for doing it */
+ /* When we propagating object to older generation we have to propagate all his
+ * dependant objects. To do it I just override mark_pmc_header function with
+ * special version which copy this objects into C<root_objects>. After first
+ * pass I just propagate all gathered objects into older generation */
+ 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;
+
+ tmp = previous_last
+ ? previous_last->next
+ : to->first;
+ while (tmp) {
+ PMC *pmc = LLH2Obj_typed(tmp, PMC);
+ next = tmp->next;
+ if (PObj_custom_mark_TEST(pmc))
+ VTABLE_mark(interp, pmc);
+ ++count;
+ tmp = next;
+ }
+
+ fprintf(stderr, "count: %d\n", count);
+ interp->gc_sys->mark_pmc_header = gc_ms2_mark_pmc_header;
+ }
+
+}
+
+static void
+gc_ms2_vtable_mark_propagate(PARROT_INTERP, ARGIN(PMC *pmc))
+{
+ MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
+ List_Item_Header *item = Obj2LLH(pmc);
+ size_t gen = PObj_to_generation(pmc);
+
+ /* Objects from older generation will stay */
+ if (gen > self->current_generation)
+ return;
+
+ /* "Constant"... */
+ if (pmc->flags & PObj_constant_FLAG)
+ return;
+
+ if (pmc->flags & PObj_GC_generation_2_FLAG)
+ return;
+
+ LIST_REMOVE(self->objects[gen], item);
+ LIST_APPEND(self->root_objects, item);
+ pmc->flags |= PObj_GC_generation_2_FLAG;
}
/*
More information about the parrot-commits
mailing list