diff --git a/src/gc/alloc_resources.c b/src/gc/alloc_resources.c
index cd96ffb..6930bb8 100644
a
|
b
|
|
321 | 321 | * TODO pass required allocation size to the GC system, |
322 | 322 | * so that collection can be skipped if needed |
323 | 323 | */ |
| 324 | size_t new_mem = mem_pools->memory_used - |
| 325 | mem_pools->mem_used_last_collect; |
324 | 326 | 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) { |
326 | 329 | Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG); |
327 | 330 | |
328 | 331 | if (interp->gc_sys->sys_type != INF) { |
… |
… |
|
360 | 363 | return_val = pool->top_block->top; |
361 | 364 | pool->top_block->top += size; |
362 | 365 | pool->top_block->free -= size; |
| 366 | mem_pools->memory_used += size; |
363 | 367 | |
364 | 368 | return return_val; |
365 | 369 | } |
… |
… |
|
512 | 516 | /* How much is free. That's the total size minus the amount we used */ |
513 | 517 | new_block->free = new_block->size - (cur_spot - new_block->start); |
514 | 518 | mem_pools->memory_collected += (cur_spot - new_block->start); |
| 519 | mem_pools->memory_used += (cur_spot - new_block->start); |
515 | 520 | |
516 | 521 | free_old_mem_blocks(mem_pools, pool, new_block, total_size); |
517 | 522 | |
… |
… |
|
719 | 724 | else { |
720 | 725 | /* Note that we don't have it any more */ |
721 | 726 | mem_pools->memory_allocated -= cur_block->size; |
| 727 | mem_pools->memory_used -= |
| 728 | cur_block->size - cur_block->free - cur_block->freed; |
722 | 729 | |
723 | 730 | /* We know the pool body and pool header are a single chunk, so |
724 | 731 | * this is enough to get rid of 'em both */ |
diff --git a/src/gc/gc_ms.c b/src/gc/gc_ms.c
index c244730..e67d6f2 100644
a
|
b
|
|
35 | 35 | __attribute__nonnull__(1); |
36 | 36 | |
37 | 37 | static void gc_ms_add_free_object(SHIM_INTERP, |
38 | | SHIM(Memory_Pools *mem_pools), |
| 38 | ARGMOD(Memory_Pools *mem_pools), |
39 | 39 | ARGMOD(Fixed_Size_Pool *pool), |
40 | 40 | ARGIN(void *to_add)) |
| 41 | __attribute__nonnull__(2) |
41 | 42 | __attribute__nonnull__(3) |
42 | 43 | __attribute__nonnull__(4) |
| 44 | FUNC_MODIFIES(*mem_pools) |
43 | 45 | FUNC_MODIFIES(*pool); |
44 | 46 | |
45 | 47 | static void gc_ms_alloc_objects(PARROT_INTERP, |
… |
… |
|
134 | 136 | PARROT_CANNOT_RETURN_NULL |
135 | 137 | PARROT_WARN_UNUSED_RESULT |
136 | 138 | static void * gc_ms_get_free_object(PARROT_INTERP, |
137 | | ARGIN(Memory_Pools *mem_pools), |
| 139 | ARGMOD(Memory_Pools *mem_pools), |
138 | 140 | ARGMOD(Fixed_Size_Pool *pool)) |
139 | 141 | __attribute__nonnull__(1) |
140 | 142 | __attribute__nonnull__(2) |
141 | 143 | __attribute__nonnull__(3) |
| 144 | FUNC_MODIFIES(*mem_pools) |
142 | 145 | FUNC_MODIFIES(*pool); |
143 | 146 | |
144 | 147 | static size_t gc_ms_get_gc_info(PARROT_INTERP, Interpinfo_enum which) |
… |
… |
|
253 | 256 | #define ASSERT_ARGS_gc_ms_active_sized_buffers __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ |
254 | 257 | PARROT_ASSERT_ARG(mem_pools)) |
255 | 258 | #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) \ |
257 | 261 | , PARROT_ASSERT_ARG(to_add)) |
258 | 262 | #define ASSERT_ARGS_gc_ms_alloc_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ |
259 | 263 | PARROT_ASSERT_ARG(interp) \ |
… |
… |
|
560 | 564 | ++mem_pools->gc_mark_runs; |
561 | 565 | --mem_pools->gc_mark_block_level; |
562 | 566 | mem_pools->header_allocs_since_last_collect = 0; |
| 567 | mem_pools->mem_used_last_collect = mem_pools->memory_used; |
563 | 568 | |
564 | 569 | return; |
565 | 570 | } |
… |
… |
|
1098 | 1103 | && (pool->top_block->top == (char *)Buffer_bufstart(buffer) + old_size)) { |
1099 | 1104 | pool->top_block->free -= needed; |
1100 | 1105 | pool->top_block->top += needed; |
| 1106 | interp->mem_pools->memory_used += needed; |
1101 | 1107 | Buffer_buflen(buffer) = newsize; |
1102 | 1108 | return; |
1103 | 1109 | } |
… |
… |
|
1210 | 1216 | && pool->top_block->top == (char *)Buffer_bufstart(str) + old_size) { |
1211 | 1217 | pool->top_block->free -= needed; |
1212 | 1218 | pool->top_block->top += needed; |
| 1219 | interp->mem_pools->memory_used += needed; |
1213 | 1220 | Buffer_buflen(str) = new_size - sizeof (void *); |
1214 | 1221 | return; |
1215 | 1222 | } |
… |
… |
|
1231 | 1238 | |
1232 | 1239 | /* Decrease usage */ |
1233 | 1240 | PARROT_ASSERT(Buffer_pool(str)); |
1234 | | Buffer_pool(str)->freed += ALIGNED_STRING_SIZE(Buffer_buflen(str)); |
| 1241 | Buffer_pool(str)->freed += old_size; |
| 1242 | interp->mem_pools->memory_used -= old_size; |
1235 | 1243 | |
1236 | 1244 | /* copy mem from strstart, *not* bufstart */ |
1237 | 1245 | oldmem = str->strstart; |
… |
… |
|
1494 | 1502 | ARGMOD(Fixed_Size_Pool *pool)) |
1495 | 1503 | { |
1496 | 1504 | ASSERT_ARGS(gc_ms_more_traceable_objects) |
| 1505 | size_t new_mem = mem_pools->memory_used |
| 1506 | - mem_pools->mem_used_last_collect; |
1497 | 1507 | |
1498 | 1508 | if (pool->skip == GC_ONE_SKIP) |
1499 | 1509 | pool->skip = GC_NO_SKIP; |
1500 | 1510 | else if (pool->skip == GC_NEVER_SKIP |
1501 | 1511 | || (pool->skip == GC_NO_SKIP |
1502 | | && mem_pools->header_allocs_since_last_collect >= GC_SIZE_THRESHOLD)) |
| 1512 | && (new_mem > (mem_pools->mem_used_last_collect >> 1) |
| 1513 | && mem_pools->header_allocs_since_last_collect >= GC_SIZE_THRESHOLD))) |
1503 | 1514 | Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG); |
1504 | 1515 | |
1505 | 1516 | /* requires that num_free_objects be updated in Parrot_gc_mark_and_sweep. |
… |
… |
|
1523 | 1534 | |
1524 | 1535 | static void |
1525 | 1536 | gc_ms_add_free_object(SHIM_INTERP, |
1526 | | SHIM(Memory_Pools *mem_pools), |
| 1537 | ARGMOD(Memory_Pools *mem_pools), |
1527 | 1538 | ARGMOD(Fixed_Size_Pool *pool), |
1528 | 1539 | ARGIN(void *to_add)) |
1529 | 1540 | { |
… |
… |
|
1534 | 1545 | |
1535 | 1546 | object->next_ptr = pool->free_list; |
1536 | 1547 | pool->free_list = object; |
| 1548 | mem_pools->memory_used -= pool->object_size; |
1537 | 1549 | } |
1538 | 1550 | |
1539 | 1551 | /* |
… |
… |
|
1554 | 1566 | PARROT_WARN_UNUSED_RESULT |
1555 | 1567 | static void * |
1556 | 1568 | gc_ms_get_free_object(PARROT_INTERP, |
1557 | | ARGIN(Memory_Pools *mem_pools), |
| 1569 | ARGMOD(Memory_Pools *mem_pools), |
1558 | 1570 | ARGMOD(Fixed_Size_Pool *pool)) |
1559 | 1571 | { |
1560 | 1572 | ASSERT_ARGS(gc_ms_get_free_object) |
… |
… |
|
1584 | 1596 | } |
1585 | 1597 | |
1586 | 1598 | --pool->num_free_objects; |
| 1599 | mem_pools->memory_used += pool->object_size; |
1587 | 1600 | |
1588 | 1601 | return ptr; |
1589 | 1602 | } |
diff --git a/src/gc/gc_private.h b/src/gc/gc_private.h
index ad62b42..46bce80 100644
a
|
b
|
|
283 | 283 | * memory for headers or |
284 | 284 | * internal structures or |
285 | 285 | * anything */ |
| 286 | size_t memory_used; /* The total amount of |
| 287 | * memory used for |
| 288 | * buffers and headers */ |
| 289 | size_t mem_used_last_collect; /* The total amount of |
| 290 | * memory used after |
| 291 | * the last GC run */ |
286 | 292 | UINTVAL memory_collected; /* Total amount of memory copied |
287 | 293 | during collection */ |
288 | 294 | UINTVAL num_early_gc_PMCs; /* how many PMCs want immediate destruction */ |
diff --git a/src/gc/mark_sweep.c b/src/gc/mark_sweep.c
index 757a060..ea76511 100644
a
|
b
|
|
32 | 32 | /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ |
33 | 33 | |
34 | 34 | static void free_buffer(SHIM_INTERP, |
35 | | SHIM(Memory_Pools *mem_pools), |
| 35 | ARGMOD(Memory_Pools *mem_pools), |
36 | 36 | ARGMOD(Fixed_Size_Pool *pool), |
37 | 37 | ARGMOD(Buffer *b)) |
| 38 | __attribute__nonnull__(2) |
38 | 39 | __attribute__nonnull__(3) |
39 | 40 | __attribute__nonnull__(4) |
| 41 | FUNC_MODIFIES(*mem_pools) |
40 | 42 | FUNC_MODIFIES(*pool) |
41 | 43 | FUNC_MODIFIES(*b); |
42 | 44 | |
… |
… |
|
78 | 80 | FUNC_MODIFIES(*mem_pools); |
79 | 81 | |
80 | 82 | #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) \ |
82 | 85 | , PARROT_ASSERT_ARG(b)) |
83 | 86 | #define ASSERT_ARGS_free_pmc_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ |
84 | 87 | PARROT_ASSERT_ARG(interp) \ |
… |
… |
|
655 | 658 | |
656 | 659 | static void |
657 | 660 | free_buffer(SHIM_INTERP, |
658 | | SHIM(Memory_Pools *mem_pools), |
| 661 | ARGMOD(Memory_Pools *mem_pools), |
659 | 662 | ARGMOD(Fixed_Size_Pool *pool), |
660 | 663 | ARGMOD(Buffer *b)) |
661 | 664 | { |
… |
… |
|
680 | 683 | |
681 | 684 | /* We can have shared buffers. Don't count them (yet) */ |
682 | 685 | if (!(*buffer_flags & Buffer_shared_FLAG)) { |
683 | | block->freed += ALIGNED_STRING_SIZE(Buffer_buflen(b)); |
| 686 | size_t size = ALIGNED_STRING_SIZE(Buffer_buflen(b)); |
| 687 | block->freed += size; |
| 688 | mem_pools->memory_used -= size; |
684 | 689 | } |
685 | 690 | |
686 | 691 | } |