Skip to content

Commit

Permalink
Merge pull request #19 from github/2.1-gc-heap-growth
Browse files Browse the repository at this point in the history
Backport 2.1 gc heap growth patch
  • Loading branch information
dbussink committed Jun 13, 2014
2 parents 339fad1 + 96062ac commit 71c08a8
Showing 1 changed file with 24 additions and 18 deletions.
42 changes: 24 additions & 18 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,9 @@ typedef struct rb_objspace {
int parent_object_is_old;

int need_major_gc;

size_t last_major_gc;

size_t remembered_shady_object_count;
size_t remembered_shady_object_limit;
size_t old_object_count;
Expand Down Expand Up @@ -1193,26 +1196,30 @@ heap_add_pages(rb_objspace_t *objspace, rb_heap_t *heap, size_t add)
heap_pages_increment = 0;
}

static void
heap_set_increment(rb_objspace_t *objspace, size_t minimum_limit)
static size_t
heap_extend_pages(rb_objspace_t *objspace)
{
size_t used = heap_pages_used - heap_tomb->page_length;
size_t next_used_limit = (size_t)(used * gc_params.growth_factor);

if (gc_params.growth_max_slots > 0) {
size_t max_used_limit = (size_t)(used + gc_params.growth_max_slots/HEAP_OBJ_LIMIT);
if (next_used_limit > max_used_limit) next_used_limit = max_used_limit;
}
if (next_used_limit == heap_pages_used) next_used_limit++;

if (next_used_limit < minimum_limit) {
next_used_limit = minimum_limit;
return next_used_limit - used;
}

static void
heap_set_increment(rb_objspace_t *objspace, size_t additional_pages)
{
size_t used = heap_eden->page_length;
size_t next_used_limit = used + additional_pages;

if (next_used_limit == heap_pages_used) next_used_limit++;

heap_pages_increment = next_used_limit - used;
heap_pages_expand_sorted(objspace);

if (0) fprintf(stderr, "heap_set_increment: heap_pages_length: %d, heap_pages_used: %d, heap_pages_increment: %d, next_used_limit: %d\n",
(int)heap_pages_length, (int)heap_pages_used, (int)heap_pages_increment, (int)next_used_limit);
}

static int
Expand Down Expand Up @@ -2855,7 +2862,7 @@ gc_heap_prepare_minimum_pages(rb_objspace_t *objspace, rb_heap_t *heap)
{
if (!heap->free_pages) {
/* there is no free after page_sweep() */
heap_set_increment(objspace, 0);
heap_set_increment(objspace, 1);
if (!heap_increment(objspace, heap)) { /* can't allocate additional free objects */
during_gc = 0;
rb_memerror();
Expand Down Expand Up @@ -2994,15 +3001,13 @@ gc_after_sweep(rb_objspace_t *objspace)
(int)heap->total_slots, (int)heap_pages_swept_slots, (int)heap_pages_min_free_slots);

if (heap_pages_swept_slots < heap_pages_min_free_slots) {
heap_set_increment(objspace, (heap_pages_min_free_slots - heap_pages_swept_slots) / HEAP_OBJ_LIMIT);
heap_increment(objspace, heap);

#if USE_RGENGC
if (objspace->rgengc.remembered_shady_object_count + objspace->rgengc.old_object_count > (heap_pages_length * HEAP_OBJ_LIMIT) / 2) {
/* if [old]+[remembered shady] > [all object count]/2, then do major GC */
objspace->rgengc.need_major_gc = GPR_FLAG_MAJOR_BY_RESCAN;
if (objspace->rgengc.during_minor_gc && objspace->profile.count - objspace->rgengc.last_major_gc > 2 /* magic number */) {
objspace->rgengc.need_major_gc = GPR_FLAG_MAJOR_BY_NOFREE;
}
else {
heap_set_increment(objspace, heap_extend_pages(objspace));
heap_increment(objspace, heap);
}
#endif
}

gc_prof_set_heap_info(objspace);
Expand Down Expand Up @@ -4185,6 +4190,7 @@ gc_marks_body(rb_objspace_t *objspace, int full_mark)
}
else {
objspace->profile.major_gc_count++;
objspace->rgengc.last_major_gc = objspace->profile.count;
rgengc_mark_and_rememberset_clear(objspace, heap_eden);
}
#endif
Expand Down Expand Up @@ -5064,7 +5070,7 @@ heap_ready_to_gc(rb_objspace_t *objspace, rb_heap_t *heap)
if (dont_gc || during_gc) {
if (!heap->freelist && !heap->free_pages) {
if (!heap_increment(objspace, heap)) {
heap_set_increment(objspace, 0);
heap_set_increment(objspace, 1);
heap_increment(objspace, heap);
}
}
Expand Down

0 comments on commit 71c08a8

Please sign in to comment.