[svn:parrot] r49045 - trunk/src/gc
bacek at svn.parrot.org
bacek at svn.parrot.org
Thu Sep 16 08:43:03 UTC 2010
Author: bacek
Date: Thu Sep 16 08:43:03 2010
New Revision: 49045
URL: https://trac.parrot.org/parrot/changeset/49045
Log:
Merge branch 'string_gc'
Modified:
trunk/src/gc/alloc_resources.c
trunk/src/gc/gc_ms.c
trunk/src/gc/gc_private.h
Modified: trunk/src/gc/alloc_resources.c
==============================================================================
--- trunk/src/gc/alloc_resources.c Thu Sep 16 08:37:09 2010 (r49044)
+++ trunk/src/gc/alloc_resources.c Thu Sep 16 08:43:03 2010 (r49045)
@@ -34,6 +34,11 @@
typedef void (*compact_f) (Interp *, Memory_Pools * const, Variable_Size_Pool *);
+typedef struct string_callback_data {
+ Memory_Block *new_block; /* A pointer to our working block */
+ char *cur_spot; /* Where we're currently copying to */
+} string_callback_data;
+
/* HEADERIZER HFILE: src/gc/gc_private.h */
/* HEADERIZER BEGIN: static */
@@ -93,6 +98,13 @@
static int is_block_almost_full(ARGIN(const Memory_Block *block))
__attribute__nonnull__(1);
+static void move_buffer_callback(PARROT_INTERP,
+ ARGIN(Buffer *b),
+ ARGIN(void *data))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3);
+
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
static char * move_one_buffer(PARROT_INTERP,
@@ -175,6 +187,10 @@
#define ASSERT_ARGS_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_is_block_almost_full __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(block))
+#define ASSERT_ARGS_move_buffer_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(b) \
+ , PARROT_ASSERT_ARG(data))
#define ASSERT_ARGS_move_one_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pool) \
@@ -439,11 +455,12 @@
INTVAL j;
UINTVAL total_size;
- Memory_Block *new_block; /* A pointer to our working block */
- char *cur_spot; /* Where we're currently copying to */
-
Fixed_Size_Arena *cur_buffer_arena;
+ /* Contains new_block and cur_spot */
+ string_callback_data cb_data;
+
+
/* Bail if we're blocked */
if (mem_pools->gc_sweep_block_level)
return;
@@ -466,57 +483,53 @@
alloc_new_block(mem_pools, total_size, pool, "inside compact");
- new_block = pool->top_block;
+ cb_data.new_block = pool->top_block;
/* Start at the beginning */
- cur_spot = new_block->start;
+ cb_data.cur_spot = cb_data.new_block->start;
/* Run through all the Buffer header pools and copy */
- for (j = (INTVAL)mem_pools->num_sized - 1; j >= 0; --j) {
- Fixed_Size_Pool * const header_pool = mem_pools->sized_header_pools[j];
- UINTVAL object_size;
-
- if (!header_pool)
- continue;
+ interp->gc_sys->iterate_live_strings(interp, move_buffer_callback, &cb_data);
- object_size = header_pool->object_size;
+ /* Okay, we're done with the copy. Set the bits in the pool struct */
+ /* First, where we allocate next */
+ cb_data.new_block->top = cb_data.cur_spot;
- for (cur_buffer_arena = header_pool->last_Arena;
- cur_buffer_arena;
- cur_buffer_arena = cur_buffer_arena->prev) {
- Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
- UINTVAL i;
- const size_t objects_end = cur_buffer_arena->used;
+ PARROT_ASSERT(cb_data.new_block->size
+ >=
+ (size_t)cb_data.new_block->top - (size_t)cb_data.new_block->start);
- for (i = objects_end; i; --i) {
+ /* How much is free. That's the total size minus the amount we used */
+ cb_data.new_block->free = cb_data.new_block->size
+ - (cb_data.cur_spot - cb_data.new_block->start);
+ mem_pools->memory_collected += (cb_data.cur_spot - cb_data.new_block->start);
+ mem_pools->memory_used += (cb_data.cur_spot - cb_data.new_block->start);
- if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
- Memory_Block *old_block = Buffer_pool(b);
+ free_old_mem_blocks(mem_pools, pool, cb_data.new_block, total_size);
- if (!is_block_almost_full(old_block))
- cur_spot = move_one_buffer(interp, new_block, b, cur_spot);
- }
+ --mem_pools->gc_sweep_block_level;
+}
- b = (Buffer *)((char *)b + object_size);
- }
- }
- }
+/*
+=item C<static void move_buffer_callback(PARROT_INTERP, Buffer *b, void *data)>
- /* Okay, we're done with the copy. Set the bits in the pool struct */
- /* First, where we allocate next */
- new_block->top = cur_spot;
+Callback for live STRING/Buffer for compating.
- PARROT_ASSERT(new_block->size >= (size_t)new_block->top -
- (size_t)new_block->start);
+=cut
+*/
+static void
+move_buffer_callback(PARROT_INTERP, ARGIN(Buffer *b), ARGIN(void *data))
+{
+ ASSERT_ARGS(move_buffer_callback)
+ string_callback_data *cb = (string_callback_data*)data;
- /* How much is free. That's the total size minus the amount we used */
- new_block->free = new_block->size - (cur_spot - new_block->start);
- mem_pools->memory_collected += (cur_spot - new_block->start);
- mem_pools->memory_used += (cur_spot - new_block->start);
+ if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
+ Memory_Block *old_block = Buffer_pool(b);
- free_old_mem_blocks(mem_pools, pool, new_block, total_size);
+ if (!is_block_almost_full(old_block))
+ cb->cur_spot = move_one_buffer(interp, cb->new_block, b, cb->cur_spot);
+ }
- --mem_pools->gc_sweep_block_level;
}
/*
Modified: trunk/src/gc/gc_ms.c
==============================================================================
--- trunk/src/gc/gc_ms.c Thu Sep 16 08:37:09 2010 (r49044)
+++ trunk/src/gc/gc_ms.c Thu Sep 16 08:43:03 2010 (r49045)
@@ -162,6 +162,11 @@
static unsigned int gc_ms_is_blocked_GC_sweep(PARROT_INTERP)
__attribute__nonnull__(1);
+static void gc_ms_iterate_live_strings(PARROT_INTERP,
+ string_iterator_callback callback,
+ ARGIN_NULLOK(void *data))
+ __attribute__nonnull__(1);
+
static void gc_ms_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
__attribute__nonnull__(1);
@@ -327,6 +332,8 @@
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_ms_is_blocked_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_gc_ms_iterate_live_strings __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_ms_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_ms_mark_special __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -456,6 +463,8 @@
interp->gc_sys->get_gc_info = gc_ms_get_gc_info;
+ interp->gc_sys->iterate_live_strings = gc_ms_iterate_live_strings;
+
initialize_var_size_pools(interp, interp->mem_pools);
initialize_fixed_size_pools(interp, interp->mem_pools);
Parrot_gc_initialize_fixed_size_pools(interp, interp->mem_pools,
@@ -1878,6 +1887,52 @@
}
/*
+=item C<static void gc_ms_iterate_live_strings(PARROT_INTERP,
+string_iterator_callback callback, void *data)>
+
+Iterate over live string invoking callback for each of them. Used during
+compacting of string pool.
+
+=cut
+*/
+static void
+gc_ms_iterate_live_strings(PARROT_INTERP,
+ string_iterator_callback callback,
+ ARGIN_NULLOK(void *data))
+{
+ ASSERT_ARGS(gc_ms_iterate_live_strings)
+
+ Memory_Pools * const mem_pools = interp->mem_pools;
+ INTVAL j;
+
+ /* Run through all the Buffer header pools and invoke callback */
+ for (j = (INTVAL)mem_pools->num_sized - 1; j >= 0; --j) {
+ Fixed_Size_Pool * const header_pool = mem_pools->sized_header_pools[j];
+ Fixed_Size_Arena * cur_buffer_arena;
+ UINTVAL object_size;
+
+ if (!header_pool)
+ continue;
+
+ object_size = header_pool->object_size;
+
+ for (cur_buffer_arena = header_pool->last_Arena;
+ cur_buffer_arena;
+ cur_buffer_arena = cur_buffer_arena->prev) {
+ Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
+ UINTVAL i;
+ const size_t objects_end = cur_buffer_arena->used;
+
+ for (i = objects_end; i; --i) {
+ callback(interp, b, data);
+ b = (Buffer *)((char *)b + object_size);
+ }
+ }
+ }
+}
+
+
+/*
=back
Modified: trunk/src/gc/gc_private.h
==============================================================================
--- trunk/src/gc/gc_private.h Thu Sep 16 08:37:09 2010 (r49044)
+++ trunk/src/gc/gc_private.h Thu Sep 16 08:43:03 2010 (r49045)
@@ -91,6 +91,9 @@
GC_NEVER_SKIP /* unused */
} gc_skip_type_enum;
+/* Callback for live string. Use Buffer for now... */
+typedef void (*string_iterator_callback)(PARROT_INTERP, Buffer *str, void *data);
+
typedef struct GC_Subsystem {
/* Which GC subsystem are we using? See PARROT_GC_DEFAULT_TYPE in
* include/parrot/settings.h for possible values */
@@ -148,6 +151,9 @@
/* Return by value to simplify memory management */
size_t (*get_gc_info)(PARROT_INTERP, Interpinfo_enum);
+ /* Iterate over _live_ strings. Used for string pool compacting */
+ void (*iterate_live_strings)(PARROT_INTERP, string_iterator_callback callback, void *data);
+
/*Function hooks that GC systems can CHOOSE to provide if they need them
*These will be called via the GC API functions Parrot_gc_func_name
*e.g. read barrier && write barrier hooks can go here later ...*/
More information about the parrot-commits
mailing list