Skip to content

Commit

Permalink
[gc] Add dynamic threshold to GC MS2
Browse files Browse the repository at this point in the history
memory_used now also accounts for attribute and other fixed size storage
and ignores constant objects. The old code could lead to a lot more
memory being used than accounted for, so rather low thresholds could
still work very well. To address this, the default dynamic GC threshold
has been increased to 75%. Note that these changes have not been applied
to the old GC. It still uses the old accounting.

Also cleanup string compacting code.

git-svn-id: https://svn.parrot.org/parrot/branches/gc_ms2_tuning@49344 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
nwellnhof committed Sep 26, 2010
1 parent 03884b6 commit 7eb63ab
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 280 deletions.
2 changes: 1 addition & 1 deletion include/parrot/gc_api.h
Expand Up @@ -33,7 +33,7 @@

#define ALIGNED_STRING_SIZE(len) (((len) + sizeof (void*) + WORD_ALIGN_1) & WORD_ALIGN_MASK)

#define GC_DYNAMIC_THRESHOLD_DEFAULT 25
#define GC_DYNAMIC_THRESHOLD_DEFAULT 75

/* pool iteration */
typedef enum {
Expand Down
79 changes: 47 additions & 32 deletions src/gc/fixed_allocator.c
Expand Up @@ -18,14 +18,17 @@ C<PoolAllocator> used to allocate memory of particular size.

#include "parrot/parrot.h"
#include "fixed_allocator.h"
#include "gc_private.h"

/* HEADERIZER HFILE: src/gc/fixed_allocator.h */

/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */

static void allocate_new_pool_arena(ARGMOD(Pool_Allocator *pool))
static void allocate_new_pool_arena(PARROT_INTERP,
ARGMOD(Pool_Allocator *pool))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(*pool);

static size_t arena_size(ARGIN(const Pool_Allocator *self))
Expand All @@ -42,12 +45,15 @@ static void * get_newfree_list_item(ARGMOD(Pool_Allocator *pool))
FUNC_MODIFIES(*pool);

PARROT_CANNOT_RETURN_NULL
static void * pool_allocate(ARGMOD(Pool_Allocator *pool))
static void * pool_allocate(PARROT_INTERP, ARGMOD(Pool_Allocator *pool))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(*pool);

static void pool_free(ARGMOD(Pool_Allocator *pool), ARGFREE(void *data))
__attribute__nonnull__(1)
static void pool_free(SHIM_INTERP,
ARGMOD(Pool_Allocator *pool),
ARGFREE(void *data))
__attribute__nonnull__(2)
FUNC_MODIFIES(*pool);

static int pool_is_owned(ARGMOD(Pool_Allocator *pool), ARGIN(void *ptr))
Expand All @@ -56,15 +62,17 @@ static int pool_is_owned(ARGMOD(Pool_Allocator *pool), ARGIN(void *ptr))
FUNC_MODIFIES(*pool);

#define ASSERT_ARGS_allocate_new_pool_arena __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_arena_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(self))
#define ASSERT_ARGS_get_free_list_item __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_get_newfree_list_item __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_pool_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_pool_free __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_pool_is_owned __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
Expand Down Expand Up @@ -158,7 +166,7 @@ Parrot_gc_fixed_allocator_allocate(PARROT_INTERP,
allocator->pools[index] = Parrot_gc_pool_new(interp, alloc_size);
}

ret = pool_allocate(allocator->pools[index]);
ret = pool_allocate(interp, allocator->pools[index]);

/* memset ret to 0 here? */
return ret;
Expand All @@ -178,7 +186,7 @@ Parrot_gc_fixed_allocator_free(PARROT_INTERP,

PARROT_ASSERT(allocator->pools[index]);

pool_free(allocator->pools[index], data);
pool_free(interp, allocator->pools[index], data);
}

/*
Expand Down Expand Up @@ -266,15 +274,15 @@ void *
Parrot_gc_pool_allocate(PARROT_INTERP, ARGMOD(Pool_Allocator * pool))
{
ASSERT_ARGS(Parrot_gc_pool_allocate)
return pool_allocate(pool);
return pool_allocate(interp, pool);
}

PARROT_EXPORT
void
Parrot_gc_pool_free(SHIM_INTERP, ARGMOD(Pool_Allocator *pool), ARGFREE(void *data))
Parrot_gc_pool_free(PARROT_INTERP, ARGMOD(Pool_Allocator *pool), ARGFREE(void *data))
{
ASSERT_ARGS(Parrot_gc_pool_free)
pool_free(pool, data);
pool_free(interp, pool, data);
}

PARROT_EXPORT
Expand All @@ -292,13 +300,13 @@ Parrot_gc_pool_is_owned(SHIM_INTERP, ARGMOD(Pool_Allocator *pool), ARGMOD(void *
=over 4
=item C<static void * pool_allocate(Pool_Allocator *pool)>
=item C<static void * pool_allocate(PARROT_INTERP, Pool_Allocator *pool)>
=item C<static void * get_free_list_item(Pool_Allocator *pool)>
=item C<static void * get_newfree_list_item(Pool_Allocator *pool)>
=item C<static void pool_free(Pool_Allocator *pool, void *data)>
=item C<static void pool_free(PARROT_INTERP, Pool_Allocator *pool, void *data)>
=item C<static int pool_is_owned(Pool_Allocator *pool, void *ptr)>
Expand Down Expand Up @@ -337,28 +345,27 @@ get_newfree_list_item(ARGMOD(Pool_Allocator *pool))

PARROT_CANNOT_RETURN_NULL
static void *
pool_allocate(ARGMOD(Pool_Allocator *pool))
pool_allocate(PARROT_INTERP, ARGMOD(Pool_Allocator *pool))
{
ASSERT_ARGS(pool_allocate)
Pool_Allocator_Free_List *item;

if (pool->free_list)
item = (Pool_Allocator_Free_List*)get_free_list_item(pool);

else if (pool->newfree)
item = (Pool_Allocator_Free_List*)get_newfree_list_item(pool);
void *item;

if (pool->free_list) {
item = get_free_list_item(pool);
}
else {
allocate_new_pool_arena(pool);
item = (Pool_Allocator_Free_List*)get_newfree_list_item(pool);
if (!pool->newfree)
allocate_new_pool_arena(interp, pool);

item = get_newfree_list_item(pool);
}

--pool->num_free_objects;
return (void *)item;
return item;
}

static void
pool_free(ARGMOD(Pool_Allocator *pool), ARGFREE(void *data))
pool_free(SHIM_INTERP, ARGMOD(Pool_Allocator *pool), ARGFREE(void *data))
{
ASSERT_ARGS(pool_free)
Pool_Allocator_Free_List * const item = (Pool_Allocator_Free_List *)data;
Expand Down Expand Up @@ -403,7 +410,8 @@ pool_is_owned(ARGMOD(Pool_Allocator *pool), ARGIN(void *ptr))

/*
=item C<static void allocate_new_pool_arena(Pool_Allocator *pool)>
=item C<static void allocate_new_pool_arena(PARROT_INTERP, Pool_Allocator
*pool)>
Allocate a new pool arena
Expand All @@ -412,18 +420,25 @@ Allocate a new pool arena
*/

static void
allocate_new_pool_arena(ARGMOD(Pool_Allocator *pool))
allocate_new_pool_arena(PARROT_INTERP, ARGMOD(Pool_Allocator *pool))
{
ASSERT_ARGS(allocate_new_pool_arena)
Pool_Allocator_Free_List *next;
Pool_Allocator_Arena *new_arena;

const size_t num_items = pool->objects_per_alloc;
const size_t item_size = pool->object_size;
const size_t item_space = item_size * num_items;

/* Round up to 4kb */
Pool_Allocator_Arena * const new_arena = (Pool_Allocator_Arena *)mem_internal_allocate(
arena_size(pool));
const size_t total_size = arena_size(pool);

/* Run a GC if needed */
if (Parrot_gc_ms_needed(interp))
Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);

new_arena = (Pool_Allocator_Arena *)mem_internal_allocate_zeroed(total_size);

interp->gc_sys->stats.memory_allocated += total_size;

new_arena->prev = NULL;
new_arena->next = pool->top_arena;
Expand All @@ -439,8 +454,8 @@ allocate_new_pool_arena(ARGMOD(Pool_Allocator *pool))
if (pool->lo_arena_ptr > new_arena)
pool->lo_arena_ptr = new_arena;

if (pool->hi_arena_ptr < (char*)new_arena + GC_FIXED_SIZE_POOL_SIZE)
pool->hi_arena_ptr = new_arena + GC_FIXED_SIZE_POOL_SIZE;
if (pool->hi_arena_ptr < (char*)new_arena + total_size)
pool->hi_arena_ptr = new_arena + total_size;
}

/*
Expand Down
6 changes: 4 additions & 2 deletions src/gc/fixed_allocator.h
Expand Up @@ -99,9 +99,10 @@ void Parrot_gc_pool_destroy(SHIM_INTERP, ARGMOD(Pool_Allocator *pool))
FUNC_MODIFIES(*pool);

PARROT_EXPORT
void Parrot_gc_pool_free(SHIM_INTERP,
void Parrot_gc_pool_free(PARROT_INTERP,
ARGMOD(Pool_Allocator *pool),
ARGFREE(void *data))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(*pool);

Expand Down Expand Up @@ -139,7 +140,8 @@ Pool_Allocator * Parrot_gc_pool_new(SHIM_INTERP, size_t object_size);
#define ASSERT_ARGS_Parrot_gc_pool_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_Parrot_gc_pool_free __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_Parrot_gc_pool_is_owned __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool) \
, PARROT_ASSERT_ARG(ptr))
Expand Down
2 changes: 0 additions & 2 deletions src/gc/gc_ms.c
Expand Up @@ -621,10 +621,8 @@ gc_ms_mark_and_sweep(PARROT_INTERP, UINTVAL flags)

/* Note it */
++interp->gc_sys->stats.gc_mark_runs;
interp->gc_sys->stats.header_allocs_since_last_collect = 0;

--mem_pools->gc_mark_block_level;
interp->gc_sys->stats.header_allocs_since_last_collect = 0;
interp->gc_sys->stats.mem_used_last_collect = interp->gc_sys->stats.memory_used;

return;
Expand Down

0 comments on commit 7eb63ab

Please sign in to comment.