From eb807d42eca121df22f72b95465bba52a4e7fefa Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 7 Mar 2011 08:39:39 +0000 Subject: * gc.c (rb_gc_set_params): allow GC parameter configuration by environment variables. based on a patch from funny-falcon at https://gist.github.com/856296, but honors safe level. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31044 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- gc.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'gc.c') diff --git a/gc.c b/gc.c index 39979138bb..0675048126 100644 --- a/gc.c +++ b/gc.c @@ -78,6 +78,47 @@ void *alloca (); #ifndef GC_MALLOC_LIMIT #define GC_MALLOC_LIMIT 8000000 #endif +#define HEAP_MIN_SLOTS 10000 +#define FREE_MIN 4096 + +static unsigned int initial_malloc_limit = GC_MALLOC_LIMIT; +static unsigned int initial_heap_min_slots = HEAP_MIN_SLOTS; +static unsigned int initial_free_min = FREE_MIN; + +void +rb_gc_set_params(void) +{ + char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr; + + if (rb_safe_level() > 0) return; + + malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); + if (malloc_limit_ptr != NULL) { + int malloc_limit_i = atoi(malloc_limit_ptr); + printf("malloc_limit=%d (%d)\n", malloc_limit_i, initial_malloc_limit); + if (malloc_limit_i > 0) { + initial_malloc_limit = malloc_limit_i; + } + } + + heap_min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); + if (heap_min_slots_ptr != NULL) { + int heap_min_slots_i = atoi(heap_min_slots_ptr); + printf("heap_min_slots=%d (%d)\n", heap_min_slots_i, initial_heap_min_slots); + if (heap_min_slots_i > 0) { + initial_heap_min_slots = heap_min_slots_i; + } + } + + free_min_ptr = getenv("RUBY_FREE_MIN"); + if (free_min_ptr != NULL) { + int free_min_i = atoi(free_min_ptr); + printf("free_min=%d (%d)\n", free_min_i, initial_free_min); + if (free_min_i > 0) { + initial_free_min = free_min_i; + } + } +} #define nomem_error GET_VM()->special_exceptions[ruby_error_nomemory] @@ -297,9 +338,6 @@ struct sorted_heaps_slot { struct heaps_slot *slot; }; -#define HEAP_MIN_SLOTS 10000 -#define FREE_MIN 4096 - struct gc_list { VALUE *varptr; struct gc_list *next; @@ -363,7 +401,7 @@ typedef struct rb_objspace { static int ruby_initial_gc_stress = 0; int *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress; #else -static rb_objspace_t rb_objspace = {{GC_MALLOC_LIMIT}, {HEAP_MIN_SLOTS}}; +static rb_objspace_t rb_objspace = {{initial_malloc_limit}, {initial_heap_min_slots}}; int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress; #endif #define malloc_limit objspace->malloc_params.limit @@ -394,7 +432,7 @@ rb_objspace_alloc(void) { rb_objspace_t *objspace = malloc(sizeof(rb_objspace_t)); memset(objspace, 0, sizeof(*objspace)); - malloc_limit = GC_MALLOC_LIMIT; + malloc_limit = initial_malloc_limit; ruby_gc_stress = ruby_initial_gc_stress; return objspace; @@ -998,7 +1036,7 @@ init_heap(rb_objspace_t *objspace) { size_t add, i; - add = HEAP_MIN_SLOTS / HEAP_OBJ_LIMIT; + add = initial_heap_min_slots / HEAP_OBJ_LIMIT; if (!add) { add = 1; @@ -1986,9 +2024,9 @@ before_gc_sweep(rb_objspace_t *objspace) freelist = 0; objspace->heap.do_heap_free = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.65); objspace->heap.free_min = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.2); - if (objspace->heap.free_min < FREE_MIN) { + if (objspace->heap.free_min < initial_free_min) { objspace->heap.do_heap_free = heaps_used * HEAP_OBJ_LIMIT; - objspace->heap.free_min = FREE_MIN; + objspace->heap.free_min = initial_free_min; } objspace->heap.sweep_slots = heaps; objspace->heap.free_num = 0; @@ -2011,7 +2049,7 @@ after_gc_sweep(rb_objspace_t *objspace) if (malloc_increase > malloc_limit) { malloc_limit += (size_t)((malloc_increase - malloc_limit) * (double)objspace->heap.live_num / (heaps_used * HEAP_OBJ_LIMIT)); - if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; + if (malloc_limit < initial_malloc_limit) malloc_limit = initial_malloc_limit; } malloc_increase = 0; @@ -2530,7 +2568,7 @@ objspace_each_objects(VALUE arg) while (i < heaps_used) { while (0 < i && (uintptr_t)membase < (uintptr_t)objspace->heap.sorted[i-1].slot->membase) i--; - while (i < heaps_used && (uintptr_t)objspace->heap.sorted[i].slot->membase <= (uintptr_t)membase ) + while (i < heaps_used && (uintptr_t)objspace->heap.sorted[i].slot->membase <= (uintptr_t)membase) i++; if (heaps_used <= i) break; -- cgit v1.2.3