Project

General

Profile

gc.patch

ko1 (Koichi Sasada), 03/07/2014 09:07 AM

View differences:

gc.c (working copy)
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
	}