Index: gc.c =================================================================== --- gc.c (revision 26813) +++ gc.c (working copy) @@ -77,6 +77,7 @@ #ifndef GC_MALLOC_LIMIT #define GC_MALLOC_LIMIT 8000000 #endif +static unsigned int GC_MALLOC_LIMIT_VAL = GC_MALLOC_LIMIT; #define nomem_error GET_VM()->special_exceptions[ruby_error_nomemory] @@ -285,6 +286,8 @@ #define HEAP_MIN_SLOTS 10000 #define FREE_MIN 4096 +static unsigned int HEAP_MIN_SLOTS_VAL = HEAP_MIN_SLOTS; + struct gc_list { VALUE *varptr; struct gc_list *next; @@ -374,7 +377,7 @@ { rb_objspace_t *objspace = malloc(sizeof(rb_objspace_t)); memset(objspace, 0, sizeof(*objspace)); - malloc_limit = GC_MALLOC_LIMIT; + malloc_limit = GC_MALLOC_LIMIT_VAL; ruby_gc_stress = ruby_initial_gc_stress; return objspace; @@ -956,7 +959,7 @@ { size_t add, i; - add = HEAP_MIN_SLOTS / HEAP_OBJ_LIMIT; + add = HEAP_MIN_SLOTS_VAL / HEAP_OBJ_LIMIT; if (!add) { add = 1; @@ -1918,7 +1921,7 @@ GC_PROF_SET_MALLOC_INFO; if (malloc_increase > malloc_limit) { malloc_limit += (size_t)((malloc_increase - malloc_limit) * (double)live / (live + freed)); - if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; + if (malloc_limit < GC_MALLOC_LIMIT_VAL) malloc_limit = GC_MALLOC_LIMIT_VAL; } malloc_increase = 0; if (freed < free_min) { @@ -2981,6 +2984,73 @@ return UINT2NUM((&rb_objspace)->count); } +/* + * call-seq: + * GC.malloc_limit -> Integer + * + * The size of the malloc limit (minimum heap size). + * + * It returns the bare minimum size of the heap. + */ + +static VALUE +gc_malloc_limit_get(VALUE self) +{ + rb_objspace_t *objspace = &rb_objspace; + return UINT2NUM(malloc_limit); +} + +/* + * + * call-seq: + * GC.malloc_limit = integer -> Integer + * + * Updates the size of the malloc limit (minimum heap size). + * + * It returns the new bare minimum size of the heap. + */ + +static VALUE +gc_malloc_limit_set(VALUE self, VALUE new_limit) +{ + rb_objspace_t *objspace = &rb_objspace; + malloc_limit = GC_MALLOC_LIMIT_VAL = NUM2UINT(new_limit); + return new_limit; +} + +/* + * call-seq: + * GC.heap_min_slots -> Integer + * + * The minimum number of slots in each heap slab. + * + * It returns the number of slots to allocate for each heap slab. + */ + +static VALUE +gc_heap_min_slots_get(VALUE self) +{ + return UINT2NUM(HEAP_MIN_SLOTS_VAL); +} + +/* + * + * call-seq: + * GC.heap_min_slots = integer -> Integer + * + * Updates the minimum number of slots in each heap slab. + * + * It returns the new number of slots to allocate for each heap slab. + */ + +static VALUE +gc_heap_min_slots_set(VALUE self, VALUE new_num_slots) +{ + HEAP_MIN_SLOTS_VAL = NUM2UINT(new_num_slots); + return new_num_slots; +} + + #if CALC_EXACT_MALLOC_SIZE /* * call-seq: @@ -3147,6 +3217,10 @@ rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0); rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1); rb_define_singleton_method(rb_mGC, "count", gc_count, 0); + rb_define_singleton_method(rb_mGC, "malloc_limit", gc_malloc_limit_get, 0); + rb_define_singleton_method(rb_mGC, "malloc_limit=", gc_malloc_limit_set, 1); + rb_define_singleton_method(rb_mGC, "heap_slots", gc_heap_min_slots_get, 0); + rb_define_singleton_method(rb_mGC, "heap_slots=", gc_heap_min_slots_set, 1); rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); rb_mProfiler = rb_define_module_under(rb_mGC, "Profiler");