[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