Skip to content

Backport 2.1 gc heap growth patch #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 13, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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