summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
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 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