116 
116 
#define GC_HEAP_OLDOBJECT_LIMIT_FACTOR 2.0

117 
117 
#endif

118 
118 


119 
#ifndef GC_HEAP_FREE_SLOTS_MIN_RATIO


120 
#define GC_HEAP_FREE_SLOTS_MIN_RATIO 0.3


121 
#endif


122 
#ifndef GC_HEAP_FREE_SLOTS_MAX_RATIO


123 
#define GC_HEAP_FREE_SLOTS_MAX_RATIO 0.8


124 
#endif


125 

119 
126 
#ifndef GC_MALLOC_LIMIT_MIN

120 
127 
#define GC_MALLOC_LIMIT_MIN (16 * 1024 * 1024 /* 16MB */)

121 
128 
#endif

...  ...  
1161 
1168 
heap_pages_increment = 0;

1162 
1169 
}

1163 
1170 

1164 

static void

1165 

heap_set_increment(rb_objspace_t *objspace, size_t minimum_limit)


1171 
static size_t


1172 
heap_extend_pages(rb_objspace_t *objspace)

1166 
1173 
{

1167 
1174 
size_t used = heap_pages_used  heap_tomb>page_length;

1168 
1175 
size_t next_used_limit = (size_t)(used * gc_params.growth_factor);


1176 

1169 
1177 
if (gc_params.growth_max_slots > 0) {

1170 
1178 
size_t max_used_limit = (size_t)(used + gc_params.growth_max_slots/HEAP_OBJ_LIMIT);

1171 
1179 
if (next_used_limit > max_used_limit) next_used_limit = max_used_limit;

1172 
1180 
}


1181 


1182 
return next_used_limit  used;


1183 
}


1184 


1185 
static void


1186 
heap_set_increment(rb_objspace_t *objspace, size_t additional_pages)


1187 
{


1188 
size_t used = heap_pages_used  heap_tomb>page_length;


1189 
size_t next_used_limit = used + additional_pages;


1190 

1173 
1191 
if (next_used_limit == heap_pages_used) next_used_limit++;

1174 
1192 

1175 

if (next_used_limit < minimum_limit) {

1176 

next_used_limit = minimum_limit;

1177 

}

1178 


1179 
1193 
heap_pages_increment = next_used_limit  used;

1180 
1194 
heap_pages_expand_sorted(objspace);

1181 


1182 

if (0) fprintf(stderr, "heap_set_increment: heap_pages_length: %d, heap_pages_used: %d, heap_pages_increment: %d, next_used_limit: %d\n",

1183 

(int)heap_pages_length, (int)heap_pages_used, (int)heap_pages_increment, (int)next_used_limit);

1184 
1195 
}

1185 
1196 

1186 
1197 
static int

...  ...  
2820 
2831 
rgengc_report(1, objspace, "page_sweep: end.\n");

2821 
2832 
}

2822 
2833 

2823 

/* allocate additional minimum page to work */


2834 
/* allocate minimum page to work */

2824 
2835 
static void


2836 
gc_heap_allocate_minimum_page(rb_objspace_t *objspace, rb_heap_t *heap)


2837 
{


2838 
heap_set_increment(objspace, 1);


2839 
if (!heap_increment(objspace, heap)) { /* can't allocate additional free objects */


2840 
during_gc = 0;


2841 
rb_memerror();


2842 
}


2843 
}


2844 


2845 
static void

2825 
2846 
gc_heap_prepare_minimum_pages(rb_objspace_t *objspace, rb_heap_t *heap)

2826 
2847 
{

2827 
2848 
if (!heap>free_pages) {

2828 

/* there is no free after page_sweep() */

2829 

heap_set_increment(objspace, 0);

2830 

if (!heap_increment(objspace, heap)) { /* can't allocate additional free objects */

2831 

during_gc = 0;

2832 

rb_memerror();


2849 
#if USE_RGENGC


2850 
if (objspace>rgengc.during_minor_gc) {


2851 
/* do full GC */


2852 
garbage_collect(objspace, TRUE, TRUE, GPR_FLAG_NEWOBJ  GPR_FLAG_MAJOR_BY_NOFREE);

2833 
2853 
}


2854 
else {


2855 
gc_heap_allocate_minimum_page(objspace, heap);


2856 
}


2857 
#else


2858 
gc_heap_allocate_minimum_page(objspace, heap);


2859 
#endif

2834 
2860 
}

2835 
2861 
}

2836 
2862 

...  ...  
2870 
2896 
heap_pages_swept_slots = 0;

2871 
2897 
total_limit_slot = objspace_total_slot(objspace);

2872 
2898 

2873 

heap_pages_min_free_slots = (size_t)(total_limit_slot * 0.30);


2899 
heap_pages_min_free_slots = (size_t)(total_limit_slot * GC_HEAP_FREE_SLOTS_MIN_RATIO);

2874 
2900 
if (heap_pages_min_free_slots < gc_params.heap_free_slots) {

2875 
2901 
heap_pages_min_free_slots = gc_params.heap_free_slots;

2876 
2902 
}

2877 

heap_pages_max_free_slots = (size_t)(total_limit_slot * 0.80);


2903 
heap_pages_max_free_slots = (size_t)(total_limit_slot * GC_HEAP_FREE_SLOTS_MAX_RATIO);

2878 
2904 
if (heap_pages_max_free_slots < gc_params.heap_init_slots) {

2879 
2905 
heap_pages_max_free_slots = gc_params.heap_init_slots;

2880 
2906 
}

...  ...  
2959 
2985 
static void

2960 
2986 
gc_after_sweep(rb_objspace_t *objspace)

2961 
2987 
{

2962 

rb_heap_t *heap = heap_eden;


2988 
/* extend heap when space is not enough */


2989 
#if USE_RGENGC


2990 
if (objspace>rgengc.during_minor_gc) {


2991 
if (heap_pages_swept_slots < heap_pages_min_free_slots) {


2992 
objspace>rgengc.need_major_gc = GPR_FLAG_MAJOR_BY_RESCAN;


2993 
}


2994 
}


2995 
else {


2996 
/* check slots for newobj */


2997 
if (heap_pages_swept_slots < heap_pages_min_free_slots) {


2998 
/* do not have enough slots for new objects */


2999 
heap_set_increment(objspace, heap_extend_pages(objspace));


3000 
}


3001 
else if (gc_params.oldobject_limit_factor > 1) {


3002 
size_t old_object_count = objspace>rgengc.old_object_count;


3003 
size_t old_object_max = (size_t)(objspace>rgengc.old_object_limit * (1  GC_HEAP_FREE_SLOTS_MIN_RATIO));

2963 
3004 

2964 

rgengc_report(1, objspace, "after_gc_sweep: heap>total_slots: %d, heap>swept_slots: %d, min_free_slots: %d\n",

2965 

(int)heap>total_slots, (int)heap_pages_swept_slots, (int)heap_pages_min_free_slots);


3005 
if (old_object_count > old_object_max) {


3006 
/* not enough old object space */


3007 
heap_set_increment(objspace, (old_object_count  old_object_max) / HEAP_OBJ_LIMIT + 1);


3008 
}


3009 
}

2966 
3010 

2967 

if (heap_pages_swept_slots < heap_pages_min_free_slots) {

2968 

heap_set_increment(objspace, (heap_pages_min_free_slots  heap_pages_swept_slots) / HEAP_OBJ_LIMIT);

2969 

heap_increment(objspace, heap);


3011 
/* setup old_object_limit & remembered_shady_object_limit */


3012 
{


3013 
/* See the comment about RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR */


3014 
size_t old_object_count = objspace>rgengc.old_object_count;


3015 
size_t old_limit_by_total_slots = (size_t)(objspace_total_slot(objspace) * (1  GC_HEAP_FREE_SLOTS_MIN_RATIO));


3016 
const double r = gc_params.oldobject_limit_factor;


3017 
size_t old_limit_by_old_num = (size_t)(old_object_count * r);

2970 
3018 

2971 

#if USE_RGENGC

2972 

if (objspace>rgengc.remembered_shady_object_count + objspace>rgengc.old_object_count > (heap_pages_length * HEAP_OBJ_LIMIT) / 2) {

2973 

/* if [old]+[remembered shady] > [all object count]/2, then do major GC */

2974 

objspace>rgengc.need_major_gc = GPR_FLAG_MAJOR_BY_RESCAN;


3019 
objspace>rgengc.old_object_limit =


3020 
old_limit_by_total_slots > old_limit_by_old_num ?


3021 
old_limit_by_old_num : old_limit_by_total_slots;


3022 


3023 
/* should we merge remembered shady object limit? */


3024 
objspace>rgengc.remembered_shady_object_limit = (size_t)(objspace>rgengc.remembered_shady_object_count * r);

2975 
3025 
}


3026 
}


3027 
#else


3028 
if (heap_pages_swept_slots < heap_pages_min_free_slots) {


3029 
/* do not have enough slots for new objects */


3030 
heap_set_increment(objspace, heap_extend_pages(objspace));


3031 
}

2976 
3032 
#endif

2977 

}

2978 
3033 

2979 
3034 
gc_prof_set_heap_info(objspace);

2980 
3035 

...  ...  
3082 
3137 
}

3083 
3138 
gc_heap_lazy_sweep(objspace, heap_eden);

3084 
3139 
}

3085 


3086 

gc_heap_prepare_minimum_pages(objspace, heap_eden);

3087 
3140 
}

3088 
3141 

3089 
3142 
/* Marking  Marking stack */

...  ...  
4524 
4577 
#endif

4525 
4578 

4526 
4579 
gc_marks_body(objspace, TRUE);

4527 

{

4528 

/* See the comment about RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR */

4529 

const double r = gc_params.oldobject_limit_factor;

4530 

objspace>rgengc.remembered_shady_object_limit = (size_t)(objspace>rgengc.remembered_shady_object_count * r);

4531 

objspace>rgengc.old_object_limit = (size_t)(objspace>rgengc.old_object_count * r);

4532 

}

4533 
4580 
}

4534 
4581 
else { /* minor GC */

4535 
4582 
gc_marks_body(objspace, FALSE);

...  ...  
5047 
5094 
}

5048 
5095 
gc_prof_timer_stop(objspace);

5049 
5096 


5097 
gc_heap_prepare_minimum_pages(objspace, heap_eden);


5098 

5050 
5099 
if (GC_NOTIFY) fprintf(stderr, "end garbage_collect()\n");

5051 
5100 
return TRUE;

5052 
5101 
}

...  ...  
5057 
5106 
if (dont_gc  during_gc) {

5058 
5107 
if (!heap>freelist && !heap>free_pages) {

5059 
5108 
if (!heap_increment(objspace, heap)) {

5060 

heap_set_increment(objspace, 0);


5109 
heap_set_increment(objspace, 1);

5061 
5110 
heap_increment(objspace, heap);

5062 
5111 
}

5063 
5112 
}
