Skip to content

Commit 0c2a8ff

Browse files
author
Charlie Somerville
committed
Apply gc stats patch
1 parent 04a8f3a commit 0c2a8ff

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

gc.c

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,13 @@
7171
#endif
7272
#define HEAP_MIN_SLOTS 10000
7373
#define FREE_MIN 4096
74+
#define HEAP_GROWTH_FACTOR 1.8
7475

7576
typedef struct {
7677
unsigned int initial_malloc_limit;
7778
unsigned int initial_heap_min_slots;
7879
unsigned int initial_free_min;
80+
double initial_growth_factor;
7981
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
8082
int gc_stress;
8183
#endif
@@ -85,6 +87,7 @@ static ruby_gc_params_t initial_params = {
8587
GC_MALLOC_LIMIT,
8688
HEAP_MIN_SLOTS,
8789
FREE_MIN,
90+
HEAP_GROWTH_FACTOR,
8891
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
8992
FALSE,
9093
#endif
@@ -288,6 +291,7 @@ int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;
288291
#define initial_malloc_limit initial_params.initial_malloc_limit
289292
#define initial_heap_min_slots initial_params.initial_heap_min_slots
290293
#define initial_free_min initial_params.initial_free_min
294+
#define initial_growth_factor initial_params.initial_growth_factor
291295

292296
#define is_lazy_sweeping(objspace) ((objspace)->heap.sweep_slots != 0)
293297

@@ -315,8 +319,8 @@ int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;
315319
#define MARKED_IN_BITMAP(bits, p) (bits[BITMAP_INDEX(p)] & ((uintptr_t)1 << BITMAP_OFFSET(p)))
316320

317321
#ifndef HEAP_ALIGN_LOG
318-
/* default tiny heap size: 16KB */
319-
#define HEAP_ALIGN_LOG 14
322+
/* default heap size: 64KB */
323+
#define HEAP_ALIGN_LOG 16
320324
#endif
321325

322326
#define CEILDIV(i, mod) (((i) + (mod) - 1)/(mod))
@@ -606,7 +610,7 @@ initial_expand_heap(rb_objspace_t *objspace)
606610
static void
607611
set_heaps_increment(rb_objspace_t *objspace)
608612
{
609-
size_t next_heaps_length = (size_t)(heaps_used * 1.8);
613+
size_t next_heaps_length = (size_t)(heaps_used * initial_growth_factor);
610614

611615
if (next_heaps_length == heaps_used) {
612616
next_heaps_length++;
@@ -3120,6 +3124,49 @@ rb_during_gc(void)
31203124
return during_gc;
31213125
}
31223126

3127+
/*
3128+
* ObjectSpace.free_slots => number
3129+
*
3130+
* Returns the count of free slots available for new objects.
3131+
*/
3132+
static
3133+
VALUE os_free_slots(VALUE self)
3134+
{
3135+
rb_objspace_t *objspace = &rb_objspace;
3136+
return SIZET2NUM((heaps_used * HEAP_OBJ_LIMIT - objspace_live_num(objspace)));
3137+
}
3138+
3139+
/* call-seq:
3140+
* ObjectSpace.live_objects => number
3141+
*/
3142+
static
3143+
VALUE os_live_objects(VALUE self)
3144+
{
3145+
rb_objspace_t *objspace = &rb_objspace;
3146+
return SIZET2NUM(objspace_live_num(objspace));
3147+
}
3148+
3149+
/* call-seq:
3150+
* ObjectSpace.allocated_objects => number
3151+
*
3152+
* Returns the count of objects allocated since the Ruby interpreter has
3153+
* started. This number can only increase. To know how many objects are
3154+
* currently allocated, use ObjectSpace::live_objects
3155+
*/
3156+
static
3157+
VALUE os_allocated_objects(VALUE self)
3158+
{
3159+
rb_objspace_t *objspace = &rb_objspace;
3160+
return SIZET2NUM(objspace->total_allocated_object_num);
3161+
}
3162+
3163+
size_t
3164+
rb_os_allocated_objects(void)
3165+
{
3166+
rb_objspace_t *objspace = &rb_objspace;
3167+
return objspace->total_allocated_object_num;
3168+
}
3169+
31233170
/*
31243171
* call-seq:
31253172
* GC.count -> Integer
@@ -3292,7 +3339,7 @@ rb_gc_disable(void)
32923339
void
32933340
rb_gc_set_params(void)
32943341
{
3295-
char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr;
3342+
char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr, *growth_factor_ptr;
32963343

32973344
if (rb_safe_level() > 0) return;
32983345

@@ -3319,6 +3366,16 @@ rb_gc_set_params(void)
33193366
}
33203367
}
33213368

3369+
growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR");
3370+
if (growth_factor_ptr != NULL) {
3371+
double growth_factor_f = atof(growth_factor_ptr);
3372+
if (RTEST(ruby_verbose))
3373+
fprintf(stderr, "growth_factor=%f (%f)\n", growth_factor_f, initial_growth_factor);
3374+
if (growth_factor_f > 0) {
3375+
initial_growth_factor = growth_factor_f;
3376+
}
3377+
}
3378+
33223379
free_min_ptr = getenv("RUBY_FREE_MIN");
33233380
if (free_min_ptr != NULL) {
33243381
int free_min_i = atoi(free_min_ptr);
@@ -4508,6 +4565,9 @@ Init_GC(void)
45084565
rb_mObSpace = rb_define_module("ObjectSpace");
45094566
rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1);
45104567
rb_define_module_function(rb_mObSpace, "garbage_collect", rb_gc_start, 0);
4568+
rb_define_module_function(rb_mObSpace, "allocated_objects", os_allocated_objects, 0);
4569+
rb_define_module_function(rb_mObSpace, "live_objects", os_live_objects, 0);
4570+
rb_define_module_function(rb_mObSpace, "free_slots", os_free_slots, 0);
45114571

45124572
rb_define_module_function(rb_mObSpace, "define_finalizer", define_final, -1);
45134573
rb_define_module_function(rb_mObSpace, "undefine_finalizer", undefine_final, 1);

gc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ int ruby_get_stack_grow_direction(volatile VALUE *addr);
8888
#endif
8989

9090
/* exports for objspace module */
91+
size_t rb_os_allocated_objects(void);
9192
size_t rb_objspace_data_type_memsize(VALUE obj);
9293
void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data);
9394
int rb_objspace_markable_object_p(VALUE obj);

0 commit comments

Comments
 (0)