[svn:parrot] r49015 - branches/gc_massacre/src/gc

bacek at svn.parrot.org bacek at svn.parrot.org
Wed Sep 15 09:52:09 UTC 2010


Author: bacek
Date: Wed Sep 15 09:52:09 2010
New Revision: 49015
URL: https://trac.parrot.org/parrot/changeset/49015

Log:
Rework triggering of GC MS2 by rough counting of allocated memory since last collect

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

Modified: branches/gc_massacre/src/gc/gc_ms2.c
==============================================================================
--- branches/gc_massacre/src/gc/gc_ms2.c	Wed Sep 15 06:30:07 2010	(r49014)
+++ branches/gc_massacre/src/gc/gc_ms2.c	Wed Sep 15 09:52:09 2010	(r49015)
@@ -114,6 +114,16 @@
         __attribute__nonnull__(1);
 
 static void gc_ms2_compact_memory_pool(SHIM_INTERP);
+static size_t gc_ms2_count_used_pmc_memory(PARROT_INTERP,
+    ARGIN(Linked_List *list))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+static size_t gc_ms2_count_used_string_memory(PARROT_INTERP,
+    ARGIN(Linked_List *list))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 static void gc_ms2_free_bufferlike_header(SHIM_INTERP,
     ARGFREE(Buffer *b),
     SHIM(size_t size));
@@ -170,6 +180,9 @@
 static void gc_ms2_mark_pobj_header(PARROT_INTERP, ARGIN_NULLOK(PObj * obj))
         __attribute__nonnull__(1);
 
+static void gc_ms2_maybe_mark_and_sweep(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
 static void gc_ms2_pmc_needs_early_collection(PARROT_INTERP,
     ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
@@ -252,6 +265,13 @@
 #define ASSERT_ARGS_gc_ms2_block_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms2_compact_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_gc_ms2_count_used_pmc_memory __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(list))
+#define ASSERT_ARGS_gc_ms2_count_used_string_memory \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(list))
 #define ASSERT_ARGS_gc_ms2_free_bufferlike_header __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_gc_ms2_free_fixed_size_storage \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -286,6 +306,8 @@
     , PARROT_ASSERT_ARG(pmc))
 #define ASSERT_ARGS_gc_ms2_mark_pobj_header __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_gc_ms2_maybe_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms2_pmc_needs_early_collection \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
@@ -443,9 +465,10 @@
 
 
 static void
-gc_ms2_allocate_string_storage(SHIM_INTERP, ARGMOD(STRING *str), size_t size)
+gc_ms2_allocate_string_storage(PARROT_INTERP, ARGMOD(STRING *str), size_t size)
 {
     ASSERT_ARGS(gc_ms2_allocate_string_storage)
+    MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
 
     /* Packfiles requires aligned strings. */
     size = (size + WORD_ALIGN_1) & WORD_ALIGN_MASK;
@@ -459,6 +482,10 @@
          * FIXME Packfile pack garbage from string tail...
          */
         memset(mem, 0, size);
+
+        /* Increase memory used */
+        self->stats.memory_allocated      += size;
+        self->stats.mem_used_last_collect += size;
     }
     else {
         Buffer_bufstart(str) = NULL;
@@ -466,20 +493,25 @@
 }
 
 static void
-gc_ms2_reallocate_string_storage(SHIM_INTERP, ARGMOD(STRING *str), size_t size)
+gc_ms2_reallocate_string_storage(PARROT_INTERP, ARGMOD(STRING *str), size_t size)
 {
     ASSERT_ARGS(gc_ms2_reallocate_string_storage)
+    MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
     char * const mem     = (char *)mem_internal_realloc(Buffer_bufstart(str), size);
 
+    self->stats.memory_allocated      += size - Buffer_buflen(str);
+    self->stats.mem_used_last_collect += size - Buffer_buflen(str);
+
     Buffer_bufstart(str) = str->strstart = mem;
     Buffer_buflen(str)   = size;
 }
 
 
 static void
-gc_ms2_allocate_buffer_storage(SHIM_INTERP, ARGMOD(Buffer *buffer), size_t size)
+gc_ms2_allocate_buffer_storage(PARROT_INTERP, ARGMOD(Buffer *buffer), size_t size)
 {
     ASSERT_ARGS(gc_ms2_allocate_buffer_storage)
+    MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
     char *mem;
 
     Buffer_buflen(buffer)   = 0;
@@ -488,6 +520,9 @@
     if (size == 0)
         return;
 
+    self->stats.memory_allocated      += size;
+    self->stats.mem_used_last_collect += size;
+
     mem      = (char *)mem_internal_allocate(size);
 
     Buffer_bufstart(buffer) = mem;
@@ -495,11 +530,15 @@
 }
 
 static void
-gc_ms2_reallocate_buffer_storage(SHIM_INTERP, ARGMOD(Buffer *buffer), size_t size)
+gc_ms2_reallocate_buffer_storage(PARROT_INTERP, ARGMOD(Buffer *buffer), size_t size)
 {
     ASSERT_ARGS(gc_ms2_reallocate_buffer_storage)
+    MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
     char * const mem = (char *)mem_internal_realloc(Buffer_bufstart(buffer), size);
 
+    self->stats.memory_allocated      += size - Buffer_buflen(buffer);
+    self->stats.mem_used_last_collect += size - Buffer_buflen(buffer);
+
     Buffer_bufstart(buffer) = mem;
     Buffer_buflen(buffer)   = size;
 }
@@ -510,6 +549,10 @@
 {
     ASSERT_ARGS(gc_ms2_allocate_fixed_size_storage)
     MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
+
+    self->stats.memory_allocated      += size;
+    self->stats.mem_used_last_collect += size;
+
     return Parrot_gc_fixed_allocator_allocate(interp, self->fixed_size_allocator, size);
 }
 
@@ -519,6 +562,10 @@
     ASSERT_ARGS(gc_ms2_free_fixed_size_storage)
     if (data) {
         MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
+
+        self->stats.memory_allocated      -= size;
+        self->stats.mem_used_last_collect -= size;
+
         Parrot_gc_fixed_allocator_free(interp, self->fixed_size_allocator, data, size);
     }
 }
@@ -644,6 +691,7 @@
 
         /* Arbitary number */
         self->gc_threshold = 1024 * 1024;
+        self->gc_threshold = 100 * 1024;
     }
     interp->gc_sys->gc_private = self;
 }
@@ -658,11 +706,20 @@
     List_Item_Header *ptr;
     PMC              *ret;
 
+#if 0
     /* Invoke M&S early. Freshly allocated "header" isn't header yet */
     if ((++self->stats.header_allocs_since_last_collect > self->gc_threshold)
         && self->pmc_allocator->num_free_objects <= 1) {
         gc_ms2_mark_and_sweep(interp, 0);
     }
+#endif
+
+    gc_ms2_maybe_mark_and_sweep(interp);
+
+    /* Increase used memory. Not precisely accurate due Pool_Allocator paging */
+    ++self->stats.header_allocs_since_last_collect;
+    self->stats.memory_allocated      += sizeof (PMC);
+    self->stats.mem_used_last_collect += sizeof (PMC);
 
     ptr = (List_Item_Header *)Parrot_gc_pool_allocate(interp,
             self->pmc_allocator);
@@ -687,6 +744,10 @@
         Parrot_pmc_destroy(interp, pmc);
 
         Parrot_gc_pool_free(interp, self->pmc_allocator, Obj2LLH(pmc));
+
+        --self->stats.header_allocs_since_last_collect;
+        self->stats.memory_allocated      -= sizeof (PMC);
+        self->stats.mem_used_last_collect -= sizeof (PMC);
     }
 }
 
@@ -772,10 +833,19 @@
     List_Item_Header *ptr;
     STRING           *ret;
 
+#if 0
     if ((++self->stats.header_allocs_since_last_collect > self->gc_threshold)
         && self->string_allocator->num_free_objects <= 1) {
         gc_ms2_mark_and_sweep(interp, 0);
     }
+#endif
+
+    gc_ms2_maybe_mark_and_sweep(interp);
+
+    /* Increase used memory. Not precisely accurate due Pool_Allocator paging */
+    ++self->stats.header_allocs_since_last_collect;
+    self->stats.memory_allocated      += sizeof (STRING);
+    self->stats.mem_used_last_collect += sizeof (STRING);
 
     ptr = (List_Item_Header *)Parrot_gc_pool_allocate(interp,
             self->string_allocator);
@@ -801,6 +871,10 @@
             mem_sys_free(Buffer_bufstart(s));
 
         Parrot_gc_pool_free(interp, self->string_allocator, Obj2LLH(s));
+
+        --self->stats.header_allocs_since_last_collect;
+        self->stats.memory_allocated      -= sizeof (STRING);
+        self->stats.mem_used_last_collect -= sizeof (STRING);
     }
 }
 
@@ -898,10 +972,11 @@
     gc_ms2_sweep_pool(interp, self->pmc_allocator, self->objects, gc_ms2_sweep_pmc_cb);
     gc_ms2_sweep_pool(interp, self->string_allocator, self->strings, gc_ms2_sweep_string_cb);
 
-    if (self->gc_threshold < 1024 * 1024 * 10)
-        self->gc_threshold *= 1.1;
+    //if (self->gc_threshold < 1024 * 1024 * 10)
+    //    self->gc_threshold *= 1.1;
 
     self->stats.header_allocs_since_last_collect = 0;
+    self->stats.mem_used_last_collect            = 0;
     self->stats.gc_mark_runs++;
     self->gc_mark_block_level--;
 }
@@ -1175,7 +1250,7 @@
 
 /*
 
-=item C<void gc_ms_pmc_needs_early_collection(PARROT_INTERP, PMC *pmc)>
+=item C<void gc_ms2_pmc_needs_early_collection(PARROT_INTERP, PMC *pmc)>
 
 Mark a PMC as needing timely destruction
 
@@ -1191,6 +1266,69 @@
     ++self->num_early_gc_PMCs;
 }
 
+/*
+
+=item C<void gc_ms2_maybe_mark_and_sweep()>
+
+Maybe M&S. Depends on total allocated memory, memory allocated since last alloc
+and phase of the Moon.
+
+=cut
+
+*/
+static void
+gc_ms2_maybe_mark_and_sweep(PARROT_INTERP)
+{
+    MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
+
+    /* Collect every 256M. Hardcode for now. Will be configured via CLI */
+    if (self->stats.mem_used_last_collect > 256 * 1024 * 1024) {
+        gc_ms2_mark_and_sweep(interp, 0);
+    }
+}
+
+static size_t
+gc_ms2_count_used_string_memory(PARROT_INTERP, ARGIN(Linked_List *list))
+{
+    size_t total_amount = 0;
+
+    List_Item_Header *tmp = list->first;
+    while (tmp) {
+        List_Item_Header *next = tmp->next;
+        PObj             *obj  = LLH2Obj_typed(tmp, PObj);
+        STRING           *str  = (STRING*)obj;
+
+        /* Header size */
+        total_amount += sizeof(List_Item_Header)
+                        + sizeof(STRING*);
+        total_amount += str->bufused;
+
+        tmp = next;
+    }
+
+    return total_amount;
+}
+
+static size_t
+gc_ms2_count_used_pmc_memory(PARROT_INTERP, ARGIN(Linked_List *list))
+{
+    size_t total_amount = 0;
+
+    List_Item_Header *tmp = list->first;
+    while (tmp) {
+        List_Item_Header *next = tmp->next;
+        PMC              *obj  = LLH2Obj_typed(tmp, PMC);
+
+        /* Header size */
+        total_amount += sizeof(List_Item_Header)
+                        + sizeof(PMC*);
+        total_amount += obj->vtable->attr_size;
+
+        tmp = next;
+    }
+
+    return total_amount;
+}
 
 /*
 


More information about the parrot-commits mailing list