7171#endif
7272#define HEAP_MIN_SLOTS 10000
7373#define FREE_MIN 4096
74+ #define HEAP_GROWTH_FACTOR 1.8
7475
7576typedef 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)
606610static void
607611set_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)
32923339void
32933340rb_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 );
0 commit comments