summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-18 00:36:37 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-18 00:36:37 +0000
commit4cd2a4d74aa8f4ecb742208b0d083ff2417d8858 (patch)
treee59a7f79c7c57ea290233b2e6d47078dfeb9393b /vm_method.c
parent11548f925390fc72d04be5276bc1fe77f99ddd02 (diff)
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
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/vm_method.c b/vm_method.c
index 17211a5..ffcf5be 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