Ticket #1737: gc-timing.diff

File gc-timing.diff, 11.2 KB (added by nwellnhof, 11 years ago)
  • src/gc/alloc_resources.c

    diff --git a/src/gc/alloc_resources.c b/src/gc/alloc_resources.c
    index cd96ffb..6930bb8 100644
    a b  
    321321         * TODO pass required allocation size to the GC system, 
    322322         *      so that collection can be skipped if needed 
    323323         */ 
     324        size_t new_mem = mem_pools->memory_used - 
     325                         mem_pools->mem_used_last_collect; 
    324326        if (!mem_pools->gc_mark_block_level 
    325         &&   mem_pools->mem_allocs_since_last_collect) { 
     327            && new_mem > (mem_pools->mem_used_last_collect >> 1) 
     328            && new_mem > GC_SIZE_THRESHOLD) { 
    326329            Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG); 
    327330 
    328331            if (interp->gc_sys->sys_type != INF) { 
     
    360363    return_val             = pool->top_block->top; 
    361364    pool->top_block->top  += size; 
    362365    pool->top_block->free -= size; 
     366    mem_pools->memory_used += size; 
    363367 
    364368    return return_val; 
    365369} 
     
    512516    /* How much is free. That's the total size minus the amount we used */ 
    513517    new_block->free = new_block->size - (cur_spot - new_block->start); 
    514518    mem_pools->memory_collected +=      (cur_spot - new_block->start); 
     519    mem_pools->memory_used      +=      (cur_spot - new_block->start); 
    515520 
    516521    free_old_mem_blocks(mem_pools, pool, new_block, total_size); 
    517522 
     
    719724        else { 
    720725            /* Note that we don't have it any more */ 
    721726            mem_pools->memory_allocated -= cur_block->size; 
     727            mem_pools->memory_used -= 
     728                cur_block->size - cur_block->free - cur_block->freed; 
    722729 
    723730            /* We know the pool body and pool header are a single chunk, so 
    724731             * this is enough to get rid of 'em both */ 
  • src/gc/gc_ms.c

    diff --git a/src/gc/gc_ms.c b/src/gc/gc_ms.c
    index 523a5ca..9dc50f1 100644
    a b  
    3535        __attribute__nonnull__(1); 
    3636 
    3737static void gc_ms_add_free_object(SHIM_INTERP, 
    38     SHIM(Memory_Pools *mem_pools), 
     38    ARGMOD(Memory_Pools *mem_pools), 
    3939    ARGMOD(Fixed_Size_Pool *pool), 
    4040    ARGIN(void *to_add)) 
     41        __attribute__nonnull__(2) 
    4142        __attribute__nonnull__(3) 
    4243        __attribute__nonnull__(4) 
     44        FUNC_MODIFIES(*mem_pools) 
    4345        FUNC_MODIFIES(*pool); 
    4446 
    4547static void gc_ms_alloc_objects(PARROT_INTERP, 
     
    134136PARROT_CANNOT_RETURN_NULL 
    135137PARROT_WARN_UNUSED_RESULT 
    136138static void * gc_ms_get_free_object(PARROT_INTERP, 
    137     ARGIN(Memory_Pools *mem_pools), 
     139    ARGMOD(Memory_Pools *mem_pools), 
    138140    ARGMOD(Fixed_Size_Pool *pool)) 
    139141        __attribute__nonnull__(1) 
    140142        __attribute__nonnull__(2) 
    141143        __attribute__nonnull__(3) 
     144        FUNC_MODIFIES(*mem_pools) 
    142145        FUNC_MODIFIES(*pool); 
    143146 
    144147static size_t gc_ms_get_gc_info(PARROT_INTERP, Interpinfo_enum which) 
     
    253256#define ASSERT_ARGS_gc_ms_active_sized_buffers __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    254257       PARROT_ASSERT_ARG(mem_pools)) 
    255258#define ASSERT_ARGS_gc_ms_add_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    256        PARROT_ASSERT_ARG(pool) \ 
     259       PARROT_ASSERT_ARG(mem_pools) \ 
     260    , PARROT_ASSERT_ARG(pool) \ 
    257261    , PARROT_ASSERT_ARG(to_add)) 
    258262#define ASSERT_ARGS_gc_ms_alloc_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    259263       PARROT_ASSERT_ARG(interp) \ 
     
    560564    ++mem_pools->gc_mark_runs; 
    561565    --mem_pools->gc_mark_block_level; 
    562566    mem_pools->header_allocs_since_last_collect = 0; 
     567    mem_pools->mem_used_last_collect = mem_pools->memory_used; 
    563568 
    564569    return; 
    565570} 
     
    11271132    &&  (pool->top_block->top  == (char *)Buffer_bufstart(buffer) + old_size)) { 
    11281133        pool->top_block->free -= needed; 
    11291134        pool->top_block->top  += needed; 
     1135        interp->mem_pools->memory_used += needed; 
    11301136        Buffer_buflen(buffer)  = newsize; 
    11311137        return; 
    11321138    } 
     
    12391245    &&  pool->top_block->top  == (char *)Buffer_bufstart(str) + old_size) { 
    12401246        pool->top_block->free -= needed; 
    12411247        pool->top_block->top  += needed; 
     1248        interp->mem_pools->memory_used += needed; 
    12421249        Buffer_buflen(str) = new_size - sizeof (void *); 
    12431250        return; 
    12441251    } 
     
    12601267 
    12611268    /* Decrease usage */ 
    12621269    PARROT_ASSERT(Buffer_pool(str)); 
    1263     Buffer_pool(str)->freed  += ALIGNED_STRING_SIZE(Buffer_buflen(str)); 
     1270    Buffer_pool(str)->freed += old_size; 
     1271    interp->mem_pools->memory_used -= old_size; 
    12641272 
    12651273    /* copy mem from strstart, *not* bufstart */ 
    12661274    oldmem             = str->strstart; 
     
    15231531        ARGMOD(Fixed_Size_Pool *pool)) 
    15241532{ 
    15251533    ASSERT_ARGS(gc_ms_more_traceable_objects) 
     1534    size_t new_mem = mem_pools->memory_used - 
     1535                     mem_pools->mem_used_last_collect; 
    15261536 
    1527     if (pool->skip == GC_ONE_SKIP) 
    1528         pool->skip = GC_NO_SKIP; 
    1529     else if (pool->skip == GC_NEVER_SKIP 
    1530          || (pool->skip == GC_NO_SKIP 
    1531          &&  mem_pools->header_allocs_since_last_collect >= GC_SIZE_THRESHOLD)) 
    1532             Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG); 
     1537    if (new_mem > (mem_pools->mem_used_last_collect >> 1) 
     1538        && new_mem > GC_SIZE_THRESHOLD) { 
     1539        Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG); 
     1540    } 
    15331541 
    15341542    /* requires that num_free_objects be updated in Parrot_gc_mark_and_sweep. 
    15351543       If gc is disabled, then we must check the free list directly. */ 
     
    15571565 
    15581566static void 
    15591567gc_ms_add_free_object(SHIM_INTERP, 
    1560         SHIM(Memory_Pools *mem_pools), 
     1568        ARGMOD(Memory_Pools *mem_pools), 
    15611569        ARGMOD(Fixed_Size_Pool *pool), 
    15621570        ARGIN(void *to_add)) 
    15631571{ 
     
    15681576 
    15691577    object->next_ptr = pool->free_list; 
    15701578    pool->free_list  = object; 
     1579    mem_pools->memory_used -= pool->object_size; 
    15711580} 
    15721581 
    15731582/* 
     
    15881597PARROT_WARN_UNUSED_RESULT 
    15891598static void * 
    15901599gc_ms_get_free_object(PARROT_INTERP, 
    1591         ARGIN(Memory_Pools *mem_pools), 
     1600        ARGMOD(Memory_Pools *mem_pools), 
    15921601        ARGMOD(Fixed_Size_Pool *pool)) 
    15931602{ 
    15941603    ASSERT_ARGS(gc_ms_get_free_object) 
     
    16301639#endif 
    16311640 
    16321641    --pool->num_free_objects; 
     1642    mem_pools->memory_used += pool->object_size; 
    16331643 
    16341644    return ptr; 
    16351645} 
     
    16821692 
    16831693    if (alloc_size > POOL_MAX_BYTES) 
    16841694        pool->objects_per_alloc = POOL_MAX_BYTES / pool->object_size; 
    1685  
    1686     if (alloc_size > GC_SIZE_THRESHOLD) 
    1687         pool->skip = GC_NEVER_SKIP; 
    16881695} 
    16891696 
    16901697 
  • src/gc/gc_private.h

    diff --git a/src/gc/gc_private.h b/src/gc/gc_private.h
    index 66ffdb7..02ea617 100644
    a b  
    8888    INF  /*infinite memory core*/ 
    8989} gc_sys_type_enum; 
    9090 
    91 /* how often to skip a full GC when this pool has nothing free */ 
    92 typedef enum _gc_skip_type_enum { 
    93     GC_NO_SKIP = 0, 
    94     GC_ONE_SKIP, 
    95     GC_ALWAYS_SKIP, 
    96     GC_NEVER_SKIP 
    97 } gc_skip_type_enum; 
    98  
    9991typedef struct GC_Subsystem { 
    10092    /* Which GC subsystem are we using? See PARROT_GC_DEFAULT_TYPE in 
    10193     * include/parrot/settings.h for possible values */ 
     
    237229 
    238230    size_t objects_per_alloc; 
    239231 
    240     int skip; 
    241232    size_t replenish_level; 
    242233 
    243234    add_free_object_fn_type     add_free_object; /* adds a free object to 
     
    294285                                   * memory for headers or 
    295286                                   * internal structures or 
    296287                                   * anything */ 
     288    size_t  memory_used;              /* The total amount of 
     289                                       * memory used for 
     290                                       * buffers and headers */ 
     291    size_t  mem_used_last_collect;    /* The total amount of 
     292                                       * memory used after 
     293                                       * the last GC run */ 
    297294    UINTVAL memory_collected;     /* Total amount of memory copied 
    298295                                     during collection */ 
    299296    UINTVAL num_early_gc_PMCs;    /* how many PMCs want immediate destruction */ 
  • src/gc/mark_sweep.c

    diff --git a/src/gc/mark_sweep.c b/src/gc/mark_sweep.c
    index b6baba6..dfa3ae5 100644
    a b  
    3232/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */ 
    3333 
    3434static void free_buffer(SHIM_INTERP, 
    35     SHIM(Memory_Pools *mem_pools), 
     35    ARGMOD(Memory_Pools *mem_pools), 
    3636    ARGMOD(Fixed_Size_Pool *pool), 
    3737    ARGMOD(Buffer *b)) 
     38        __attribute__nonnull__(2) 
    3839        __attribute__nonnull__(3) 
    3940        __attribute__nonnull__(4) 
     41        FUNC_MODIFIES(*mem_pools) 
    4042        FUNC_MODIFIES(*pool) 
    4143        FUNC_MODIFIES(*b); 
    4244 
     
    7880        FUNC_MODIFIES(*mem_pools); 
    7981 
    8082#define ASSERT_ARGS_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    81        PARROT_ASSERT_ARG(pool) \ 
     83       PARROT_ASSERT_ARG(mem_pools) \ 
     84    , PARROT_ASSERT_ARG(pool) \ 
    8285    , PARROT_ASSERT_ARG(b)) 
    8386#define ASSERT_ARGS_free_pmc_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    8487       PARROT_ASSERT_ARG(interp) \ 
     
    665668 
    666669static void 
    667670free_buffer(SHIM_INTERP, 
    668         SHIM(Memory_Pools *mem_pools), 
     671        ARGMOD(Memory_Pools *mem_pools), 
    669672        ARGMOD(Fixed_Size_Pool *pool), 
    670673        ARGMOD(Buffer *b)) 
    671674{ 
     
    690693 
    691694            /* We can have shared buffers. Don't count them (yet) */ 
    692695            if (!(*buffer_flags & Buffer_shared_FLAG)) { 
    693                 block->freed  += ALIGNED_STRING_SIZE(Buffer_buflen(b)); 
     696                size_t size = ALIGNED_STRING_SIZE(Buffer_buflen(b)); 
     697                block->freed += size; 
     698                mem_pools->memory_used -= size; 
    694699            } 
    695700 
    696701        } 
     
    770775    /* Init the constant string header pool */ 
    771776    mem_pools->constant_string_header_pool       = new_string_pool(interp, mem_pools, 1); 
    772777    mem_pools->constant_string_header_pool->name = "constant_string_header"; 
    773     mem_pools->constant_string_header_pool->skip = GC_ALWAYS_SKIP; 
    774778 
    775779    /* Init the buffer header pool 
    776780     * 
     
    789793    /* constant PMCs */ 
    790794    mem_pools->constant_pmc_pool                    = new_pmc_pool(interp); 
    791795    mem_pools->constant_pmc_pool->name              = "constant_pmc"; 
    792     mem_pools->constant_pmc_pool->skip              = GC_ALWAYS_SKIP; 
    793796    mem_pools->constant_pmc_pool->objects_per_alloc = 
    794797        CONSTANT_PMC_HEADERS_PER_ALLOC; 
    795798}