Created
December 6, 2011 08:02
-
-
Save SkyWriter/1437305 to your computer and use it in GitHub Desktop.
Патч для ускорения загрузки Rails + твики работы с памятью
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/gc.c b/gc.c | |
--- a/gc.c | |
+++ b/gc.c | |
@@ -77,6 +77,41 @@ void *alloca (); | |
#ifndef GC_MALLOC_LIMIT | |
#define GC_MALLOC_LIMIT 8000000 | |
#endif | |
+#define HEAP_MIN_SLOTS 10000 | |
+#define FREE_MIN 4096 | |
+ | |
+static unsigned int initial_malloc_limit = GC_MALLOC_LIMIT; | |
+static unsigned int initial_heap_min_slots = HEAP_MIN_SLOTS; | |
+static unsigned int initial_free_min = FREE_MIN; | |
+ | |
+static void set_gc_parameters() | |
+{ | |
+ char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr; | |
+ | |
+ malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); | |
+ if ( malloc_limit_ptr != NULL ) { | |
+ int malloc_limit_i = atoi(malloc_limit_ptr); | |
+ if ( malloc_limit_i > 0 ) { | |
+ initial_malloc_limit = malloc_limit_i; | |
+ } | |
+ } | |
+ | |
+ heap_min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); | |
+ if ( heap_min_slots_ptr != NULL ) { | |
+ int heap_min_slots_i = atoi(heap_min_slots_ptr); | |
+ if ( heap_min_slots_i > 0 ) { | |
+ initial_heap_min_slots = heap_min_slots_i; | |
+ } | |
+ } | |
+ | |
+ free_min_ptr = getenv("RUBY_FREE_MIN"); | |
+ if ( free_min_ptr != NULL ) { | |
+ int free_min_i = atoi(free_min_ptr); | |
+ if ( free_min_i > 0 ) { | |
+ initial_free_min = free_min_i; | |
+ } | |
+ } | |
+} | |
#define nomem_error GET_VM()->special_exceptions[ruby_error_nomemory] | |
@@ -283,9 +318,6 @@ struct heaps_slot { | |
int finalize_flag; | |
}; | |
-#define HEAP_MIN_SLOTS 10000 | |
-#define FREE_MIN 4096 | |
- | |
struct gc_list { | |
VALUE *varptr; | |
struct gc_list *next; | |
@@ -341,7 +373,7 @@ typedef struct rb_objspace { | |
static int ruby_initial_gc_stress = 0; | |
int *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress; | |
#else | |
-static rb_objspace_t rb_objspace = {{GC_MALLOC_LIMIT}, {HEAP_MIN_SLOTS}}; | |
+static rb_objspace_t rb_objspace = {{initial_malloc_limit}, {initial_heap_min_slots}}; | |
int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress; | |
#endif | |
#define malloc_limit objspace->malloc_params.limit | |
@@ -375,7 +407,7 @@ rb_objspace_alloc(void) | |
{ | |
rb_objspace_t *objspace = malloc(sizeof(rb_objspace_t)); | |
memset(objspace, 0, sizeof(*objspace)); | |
- malloc_limit = GC_MALLOC_LIMIT; | |
+ malloc_limit = initial_malloc_limit; | |
ruby_gc_stress = ruby_initial_gc_stress; | |
return objspace; | |
@@ -958,7 +990,7 @@ init_heap(rb_objspace_t *objspace) | |
{ | |
size_t add, i; | |
- add = HEAP_MIN_SLOTS / HEAP_OBJ_LIMIT; | |
+ add = initial_heap_min_slots / HEAP_OBJ_LIMIT; | |
if (!add) { | |
add = 1; | |
@@ -1862,9 +1894,9 @@ gc_sweep(rb_objspace_t *objspace) | |
do_heap_free = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.65); | |
free_min = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.2); | |
- if (free_min < FREE_MIN) { | |
+ if (free_min < initial_free_min) { | |
do_heap_free = heaps_used * HEAP_OBJ_LIMIT; | |
- free_min = FREE_MIN; | |
+ free_min = initial_free_min; | |
} | |
freelist = 0; | |
@@ -1926,7 +1958,7 @@ gc_sweep(rb_objspace_t *objspace) | |
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 < initial_malloc_limit) malloc_limit = initial_malloc_limit; | |
} | |
malloc_increase = 0; | |
if (freed < free_min) { | |
@@ -2298,6 +2330,7 @@ Init_stack(volatile VALUE *addr) | |
void | |
Init_heap(void) | |
{ | |
+ set_gc_parameters(); | |
init_heap(&rb_objspace); | |
} | |
--- a/load.c 2010-10-23 05:36:38.000000000 -0400 | |
+++ b/patchload.c 2011-06-05 08:58:00.000000000 -0400 | |
@@ -81,16 +73,27 @@ | |
int type, VALUE load_path) | |
{ | |
long i; | |
+ long plen; | |
+ const char *e; | |
+ if(vlen < len) return 0; | |
+ if (!strncmp(name+(vlen-len),feature,len)){ | |
+ plen = vlen - len - 1; | |
+ } else { | |
+ for (e = name + vlen; name != e && *e != '.' && *e != '/'; --e); | |
+ if (*e!='.' || | |
+ e-name < len || | |
+ strncmp(e-len,feature,len) ) | |
+ return 0; | |
+ plen = e - name - len - 1; | |
+ } | |
for (i = 0; i < RARRAY_LEN(load_path); ++i) { | |
VALUE p = RARRAY_PTR(load_path)[i]; | |
const char *s = StringValuePtr(p); | |
long n = RSTRING_LEN(p); | |
- if (vlen < n + len + 1) continue; | |
+ if (n != plen ) continue; | |
if (n && (strncmp(name, s, n) || name[n] != '/')) continue; | |
- if (strncmp(name + n + 1, feature, len)) continue; | |
- if (name[n+len+1] && name[n+len+1] != '.') continue; | |
switch (type) { | |
case 's': | |
if (IS_DLEXT(&name[n+len+1])) return p; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment