diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-18 00:36:37 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-18 00:36:37 +0000 |
commit | 4cd2a4d74aa8f4ecb742208b0d083ff2417d8858 (patch) | |
tree | e59a7f79c7c57ea290233b2e6d47078dfeb9393b | |
parent | 11548f925390fc72d04be5276bc1fe77f99ddd02 (diff) | |
download | ruby-4cd2a4d74aa8f4ecb742208b0d083ff2417d8858.tar.gz |
vm_method.c: configurable global method cache size
* vm_method.c (Init_Method): make global method cache size
configurable by environment variable
"RUBY_GLOBAL_METHOD_CACHE_SIZE" [Fix GH-719]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47621 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | inits.c | 1 | ||||
-rw-r--r-- | vm_method.c | 38 |
3 files changed, 42 insertions, 3 deletions
@@ -1,3 +1,9 @@ +Thu Sep 18 09:36:37 2014 Scott Francis <scott.francis@shopify.com> + + * vm_method.c (Init_Method): make global method cache size + configurable by environment variable + "RUBY_GLOBAL_METHOD_CACHE_SIZE" [Fix GH-719] + Thu Sep 18 07:03:36 2014 Eric Wong <e@80x24.org> * test/-ext-/string/test_modify_expand.rb: increase limit @@ -17,6 +17,7 @@ void rb_call_inits(void) { + CALL(Method); CALL(RandomSeed); CALL(sym); CALL(var_tables); diff --git a/vm_method.c b/vm_method.c index 17211a5634..ffcf5be339 100644 --- a/vm_method.c +++ b/vm_method.c @@ -15,8 +15,8 @@ #define GLOBAL_METHOD_CACHE_MASK (GLOBAL_METHOD_CACHE_SIZE-1) #endif -#define GLOBAL_METHOD_CACHE_KEY(c,m) ((((c)>>3)^(m))&GLOBAL_METHOD_CACHE_MASK) -#define GLOBAL_METHOD_CACHE(c,m) (global_method_cache + GLOBAL_METHOD_CACHE_KEY(c,m)) +#define GLOBAL_METHOD_CACHE_KEY(c,m) ((((c)>>3)^(m))&(global_method_cache.mask)) +#define GLOBAL_METHOD_CACHE(c,m) (global_method_cache.entries + GLOBAL_METHOD_CACHE_KEY(c,m)) #else #define GLOBAL_METHOD_CACHE(c,m) (rb_bug("global method cache disabled improperly"), NULL) #endif @@ -47,7 +47,14 @@ struct cache_entry { }; #if OPT_GLOBAL_METHOD_CACHE -static struct cache_entry global_method_cache[GLOBAL_METHOD_CACHE_SIZE]; +static struct { + unsigned int size; + unsigned int mask; + struct cache_entry *entries; +} global_method_cache = { + GLOBAL_METHOD_CACHE_SIZE, + GLOBAL_METHOD_CACHE_MASK, +}; #endif #define ruby_running (GET_VM()->running) @@ -1726,6 +1733,31 @@ obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv) } void +Init_Method(void) +{ +#if OPT_GLOBAL_METHOD_CACHE + char *ptr = getenv("RUBY_GLOBAL_METHOD_CACHE_SIZE"); + int val; + + if (ptr != NULL && (val = atoi(ptr)) > 0) { + if ((val & (val - 1)) == 0) { /* ensure val is a power of 2 */ + global_method_cache.size = val; + global_method_cache.mask = val - 1; + } + else { + fprintf(stderr, "RUBY_GLOBAL_METHOD_CACHE_SIZE was set to %d but ignored because the value is not a power of 2.\n", val); + } + } + + global_method_cache.entries = (struct cache_entry *)calloc(global_method_cache.size, sizeof(struct cache_entry)); + if (global_method_cache.entries == NULL) { + fprintf(stderr, "[FATAL] failed to allocate memory\n"); + exit(EXIT_FAILURE); + } +#endif +} + +void Init_eval_method(void) { #undef rb_intern |