From 4cd2a4d74aa8f4ecb742208b0d083ff2417d8858 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 18 Sep 2014 00:36:37 +0000 Subject: 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 --- ChangeLog | 6 ++++++ inits.c | 1 + vm_method.c | 38 +++++++++++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0557a5a896..26db3bcd87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Thu Sep 18 09:36:37 2014 Scott Francis + + * 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 * test/-ext-/string/test_modify_expand.rb: increase limit diff --git a/inits.c b/inits.c index da8cfb1ed9..458eb64b1e 100644 --- a/inits.c +++ b/inits.c @@ -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) @@ -1725,6 +1732,31 @@ obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv) return Qfalse; } +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) { -- cgit v1.2.3