[macruby-changes] [4181] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Jun 1 02:27:13 PDT 2010


Revision: 4181
          http://trac.macosforge.org/projects/ruby/changeset/4181
Author:   lsansonetti at apple.com
Date:     2010-06-01 02:27:08 -0700 (Tue, 01 Jun 2010)
Log Message:
-----------
per-vm method cache + misc fixes/improvements

Modified Paths:
--------------
    MacRuby/trunk/MacRuby.m
    MacRuby/trunk/NSDictionary.m
    MacRuby/trunk/NSString.m
    MacRuby/trunk/array.c
    MacRuby/trunk/bridgesupport.cpp
    MacRuby/trunk/bridgesupport.h
    MacRuby/trunk/class.c
    MacRuby/trunk/class.h
    MacRuby/trunk/compar.c
    MacRuby/trunk/compiler.cpp
    MacRuby/trunk/compiler.h
    MacRuby/trunk/complex.c
    MacRuby/trunk/dispatcher.cpp
    MacRuby/trunk/enum.c
    MacRuby/trunk/enumerator.c
    MacRuby/trunk/error.c
    MacRuby/trunk/exported_symbols_list
    MacRuby/trunk/ext/libyaml/rubyext.c
    MacRuby/trunk/ext/openssl/ossl_ssl.c
    MacRuby/trunk/file.c
    MacRuby/trunk/hash.c
    MacRuby/trunk/hash.h
    MacRuby/trunk/id.c
    MacRuby/trunk/id.h
    MacRuby/trunk/include/ruby/ruby.h
    MacRuby/trunk/io.c
    MacRuby/trunk/kernel.c
    MacRuby/trunk/numeric.c
    MacRuby/trunk/object.c
    MacRuby/trunk/proc.c
    MacRuby/trunk/process.c
    MacRuby/trunk/random.c
    MacRuby/trunk/range.c
    MacRuby/trunk/rational.c
    MacRuby/trunk/signal.c
    MacRuby/trunk/spec/macruby/core/constant_spec.rb
    MacRuby/trunk/string.c
    MacRuby/trunk/variable.c
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h
    MacRuby/trunk/vm_eval.c
    MacRuby/trunk/vm_method.c

Modified: MacRuby/trunk/MacRuby.m
===================================================================
--- MacRuby/trunk/MacRuby.m	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/MacRuby.m	2010-06-01 09:27:08 UTC (rev 4181)
@@ -87,7 +87,7 @@
 	}
     }
 
-    return RB2OC(rb_vm_call(OC2RB(self), sel, argc, rargv, false));
+    return RB2OC(rb_vm_call(OC2RB(self), sel, argc, rargv));
 }
 
 - (id)performRubySelector:(SEL)sel withArguments:firstArg, ...

Modified: MacRuby/trunk/NSDictionary.m
===================================================================
--- MacRuby/trunk/NSDictionary.m	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/NSDictionary.m	2010-06-01 09:27:08 UTC (rev 4181)
@@ -432,7 +432,7 @@
 	tmp = INT2FIX(1);
 	argv = &tmp;
     }
-    rb_vm_call((VALUE)ary, sel_registerName("flatten!:"), argc, argv, false);
+    rb_vm_call((VALUE)ary, sel_registerName("flatten!:"), argc, argv);
     return ary;
 }
 

Modified: MacRuby/trunk/NSString.m
===================================================================
--- MacRuby/trunk/NSString.m	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/NSString.m	2010-06-01 09:27:08 UTC (rev 4181)
@@ -206,8 +206,7 @@
 static VALUE
 nsstr_forward_m1(id rcv, SEL sel, int argc, VALUE *argv)
 {
-    return rb_vm_call_with_cache2(rb_vm_get_call_cache(sel),
-	    rb_vm_current_block(), nsstr_to_rstr(rcv), 0, sel, argc, argv);
+    return rb_vm_call2(rb_vm_current_block(), nsstr_to_rstr(rcv), 0, sel, argc, argv);
 }
 
 static VALUE
@@ -241,8 +240,7 @@
 {
     CHECK_MUTABLE(rcv);
     VALUE rcv_rstr = nsstr_to_rstr(rcv);
-    VALUE ret = rb_vm_call_with_cache2(rb_vm_get_call_cache(sel),
-	    rb_vm_current_block(), rcv_rstr, 0, sel, argc, argv);
+    VALUE ret = rb_vm_call2(rb_vm_current_block(), rcv_rstr, 0, sel, argc, argv);
     TRY_MOP([rcv setString:(id)rcv_rstr]);
     return ret;
 }

Modified: MacRuby/trunk/array.c
===================================================================
--- MacRuby/trunk/array.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/array.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -1565,12 +1565,10 @@
 static VALUE
 rary_sort_by_bang(VALUE ary, SEL sel)
 {
-    VALUE sorted;
-
     RETURN_ENUMERATOR(ary, 0, 0);
     rb_ary_modify(ary);
-    sorted = rb_objc_block_call(ary, sel_registerName("sort_by"), NULL, 0, 0,
-	sort_by_i, 0);
+    VALUE sorted = rb_objc_block_call(ary, sel_registerName("sort_by"), 0, 0,
+	    sort_by_i, 0);
     rb_ary_replace(ary, sorted);
     return ary;
 }
@@ -2058,8 +2056,8 @@
     args[0] = result;
     args[1] = (VALUE)n;
     
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0,
-	    (VALUE(*)(ANYARGS))take_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, (VALUE(*)(ANYARGS))take_i,
+	    (VALUE)args);
 
     return result;
 }

Modified: MacRuby/trunk/bridgesupport.cpp
===================================================================
--- MacRuby/trunk/bridgesupport.cpp	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/bridgesupport.cpp	2010-06-01 09:27:08 UTC (rev 4181)
@@ -405,7 +405,7 @@
     char buf[100];
     snprintf(buf, sizeof buf, "%s=:", bs_boxed->as.s->fields[idx].name);
 
-    return rb_vm_call(rcv, sel_registerName(buf), 1, &val, false);
+    return rb_vm_call(rcv, sel_registerName(buf), 1, &val);
 }
 
 static VALUE
@@ -1313,7 +1313,8 @@
     if (!ok) {
 	rb_raise(rb_eRuntimeError, "%s", error);
     }
-#if defined(__LP64__)
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+# if defined(__LP64__)
     static bool R6399046_fixed = false;
     // XXX work around for
     // <rdar://problem/6399046> NSNotFound 64-bit value is incorrect
@@ -1327,6 +1328,7 @@
 	    R6399046_fixed = true;
 	}
     }
+# endif
 #endif
 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
     static bool R6401816_fixed = false;

Modified: MacRuby/trunk/bridgesupport.h
===================================================================
--- MacRuby/trunk/bridgesupport.h	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/bridgesupport.h	2010-06-01 09:27:08 UTC (rev 4181)
@@ -13,6 +13,8 @@
 extern "C" {
 #endif
 
+#include "bs.h"
+
 void *rb_pointer_get_data(VALUE rcv, const char *type);
 VALUE rb_pointer_new(const char *type_str, void *val, size_t len);
 VALUE rb_pointer_new2(const char *type_str, VALUE val);
@@ -21,8 +23,6 @@
 #if defined(__cplusplus)
 } // extern "C"
 
-#include "bs.h"
-
 typedef struct rb_vm_bs_boxed {
     bs_element_type_t bs_type;
     bool is_struct(void) { return bs_type == BS_ELEMENT_STRUCT; }

Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/class.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -61,20 +61,20 @@
 	return false;
     }
     VALUE arg = OC2RB(obj);
-    return rb_vm_call((VALUE)rcv, selEq, 1, &arg, false) == Qtrue;
+    return rb_vm_call((VALUE)rcv, selEq, 1, &arg) == Qtrue;
 }
 
 static void *
 rb_obj_imp_init(void *rcv, SEL sel)
 {
-    rb_vm_call((VALUE)rcv, selInitialize, 0, NULL, false);
+    rb_vm_call((VALUE)rcv, selInitialize, 0, NULL);
     return rcv;
 }
 
 static void *
 rb_obj_imp_description(void *rcv, SEL sel)
 {
-    return (void *)rb_vm_call(OC2RB(rcv), selToS, 0, NULL, false);
+    return (void *)rb_vm_call(OC2RB(rcv), selToS, 0, NULL);
 }
 
 static VALUE
@@ -415,7 +415,7 @@
 	if (super == 0) {
 	    super = rb_cObject;
 	}
-	return rb_vm_call(super, selInherited, 1, &klass, false);
+	return rb_vm_call(super, selInherited, 1, &klass);
     }
     return Qnil;
 }
@@ -1258,8 +1258,8 @@
 void
 Init_PreClass(void)
 {
-    rb_class_flags = (rb_class_flags_cache_t *)calloc(CACHE_SIZE,
-	    sizeof(rb_class_flags_cache_t));
+    rb_class_flags = (rb_class_flags_cache_t *)calloc(
+	    CLASS_FLAGS_CACHE_SIZE, sizeof(rb_class_flags_cache_t));
     assert(rb_class_flags != NULL);
 }
 

Modified: MacRuby/trunk/class.h
===================================================================
--- MacRuby/trunk/class.h	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/class.h	2010-06-01 09:27:08 UTC (rev 4181)
@@ -30,14 +30,14 @@
     struct rb_class_flags_cache *next;
 } rb_class_flags_cache_t;
 
-#define CACHE_SIZE 0x1000
+#define CLASS_FLAGS_CACHE_SIZE 0x1000
 
 extern rb_class_flags_cache_t *rb_class_flags;
 
 static unsigned int
 rb_class_flags_hash(Class k)
 {
-    return ((unsigned long)k >> 2) & (CACHE_SIZE - 1);
+    return ((unsigned long)k >> 2) & (CLASS_FLAGS_CACHE_SIZE - 1);
 }
 
 static inline unsigned long

Modified: MacRuby/trunk/compar.c
===================================================================
--- MacRuby/trunk/compar.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/compar.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -16,7 +16,6 @@
 VALUE rb_mComparable;
 
 static SEL cmp = 0;
-static struct mcache *cmp_cache = NULL;
 
 void
 rb_cmperr(VALUE x, VALUE y)
@@ -37,15 +36,13 @@
 VALUE
 rb_objs_cmp(VALUE x, VALUE y)
 {
-    return rb_vm_call_with_cache(cmp_cache, x, cmp, 1, &y);
+    return rb_vm_call(x, cmp, 1, &y);
 }
 
 static VALUE
 cmp_eq(VALUE *a)
 {
-    //VALUE c = rb_funcall(a[0], cmp, 1, a[1]);
-    VALUE c = rb_vm_call_with_cache(cmp_cache, a[0], cmp, 1, &a[1]);
-
+    VALUE c = rb_vm_call(a[0], cmp, 1, &a[1]);
     if (NIL_P(c)) {
 	return Qfalse;
     }
@@ -92,10 +89,10 @@
 static VALUE
 cmp_gt(VALUE x, SEL sel, VALUE y)
 {
-    //VALUE c = rb_funcall(x, cmp, 1, y);
-    VALUE c = rb_vm_call_with_cache(cmp_cache, x, cmp, 1, &y);
-
-    if (rb_cmpint(c, x, y) > 0) return Qtrue;
+    VALUE c = rb_vm_call(x, cmp, 1, &y);
+    if (rb_cmpint(c, x, y) > 0) {
+	return Qtrue;
+    }
     return Qfalse;
 }
 
@@ -110,10 +107,10 @@
 static VALUE
 cmp_ge(VALUE x, SEL sel, VALUE y)
 {
-    //VALUE c = rb_funcall(x, cmp, 1, y);
-    VALUE c = rb_vm_call_with_cache(cmp_cache, x, cmp, 1, &y);
-
-    if (rb_cmpint(c, x, y) >= 0) return Qtrue;
+    VALUE c = rb_vm_call(x, cmp, 1, &y);
+    if (rb_cmpint(c, x, y) >= 0) {
+	return Qtrue;
+    }
     return Qfalse;
 }
 
@@ -128,10 +125,10 @@
 static VALUE
 cmp_lt(VALUE x, SEL sel, VALUE y)
 {
-    //VALUE c = rb_funcall(x, cmp, 1, y);
-    VALUE c = rb_vm_call_with_cache(cmp_cache, x, cmp, 1, &y);
-
-    if (rb_cmpint(c, x, y) < 0) return Qtrue;
+    VALUE c = rb_vm_call(x, cmp, 1, &y);
+    if (rb_cmpint(c, x, y) < 0) {
+	return Qtrue;
+    }
     return Qfalse;
 }
 
@@ -146,10 +143,10 @@
 static VALUE
 cmp_le(VALUE x, SEL sel, VALUE y)
 {
-    //VALUE c = rb_funcall(x, cmp, 1, y);
-    VALUE c = rb_vm_call_with_cache(cmp_cache, x, cmp, 1, &y);
-
-    if (rb_cmpint(c, x, y) <= 0) return Qtrue;
+    VALUE c = rb_vm_call(x, cmp, 1, &y);
+    if (rb_cmpint(c, x, y) <= 0) {
+	return Qtrue;
+    }
     return Qfalse;
 }
 
@@ -225,5 +222,4 @@
     rb_objc_define_method(rb_mComparable, "between?", cmp_between, 2);
 
     cmp = sel_registerName("<=>:");
-    cmp_cache = rb_vm_get_call_cache(cmp);
 }

Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/compiler.cpp	2010-06-01 09:27:08 UTC (rev 4181)
@@ -306,7 +306,6 @@
     Value *condVal;
     if (comparedToVal != NULL) {
 	std::vector<Value *> params;
-	params.push_back(compile_mcache(selEqq, false));
 	params.push_back(current_self);
 	params.push_back(subnodeVal);
 	params.push_back(compile_sel(selEqq));
@@ -463,12 +462,11 @@
 {
     GlobalVariable *is_redefined = GET_CORE()->redefined_op_gvar(selEqq, true);
     Value *args[] = {
-	compile_mcache(selEqq, false),
 	new LoadInst(is_redefined, "", bb),
 	comparedToVal,
 	splatVal
     };
-    return compile_protected_call(whenSplatFunc, args, args + 4);
+    return compile_protected_call(whenSplatFunc, args, args + 3);
 }
 
 GlobalVariable *
@@ -538,55 +536,6 @@
 }
 
 Value *
-RoxorCompiler::compile_get_mcache(Value *sel, bool super)
-{
-    if (getCacheFunc == NULL) {
-	// void *rb_vm_get_call_cache2(SEL sel, unsigned char super);
-	getCacheFunc = 
-	    cast<Function>(module->getOrInsertFunction(
-			"rb_vm_get_call_cache2", PtrTy, PtrTy, Int8Ty,
-			NULL));
-    }
-
-    Value *args[] = {
-	sel,
-	ConstantInt::get(Int8Ty, super ? 1 : 0)
-    };
-    return CallInst::Create(getCacheFunc, args, args + 2, "", bb);
-}
-
-Value *
-RoxorCompiler::compile_mcache(SEL sel, bool super)
-{
-    struct mcache *cache = GET_CORE()->method_cache_get(sel, super);
-    return compile_const_pointer(cache);
-}
-
-Value *
-RoxorAOTCompiler::compile_mcache(SEL sel, bool super)
-{
-    if (super) {
-	char buf[100];
-	snprintf(buf, sizeof buf, "__super__:%s", sel_getName(sel));
-        sel = sel_registerName(buf);
-    }
-
-    GlobalVariable *gvar;
-    std::map<SEL, GlobalVariable *>::iterator iter = mcaches.find(sel);
-    if (iter == mcaches.end()) {
-	gvar = new GlobalVariable(*RoxorCompiler::module, PtrTy, false,
-		GlobalValue::InternalLinkage, Constant::getNullValue(PtrTy),
-		"");
-	assert(gvar != NULL);
-	mcaches[sel] = gvar;
-    }
-    else {
-	gvar = iter->second;
-    }
-    return new LoadInst(gvar, "", bb);
-}
-
-Value *
 RoxorCompiler::compile_ccache(ID name)
 {
     struct ccache *cache = GET_CORE()->constant_cache_get(name);
@@ -716,10 +665,9 @@
 RoxorCompiler::compile_dispatch_call(std::vector<Value *> &params)
 {
     if (dispatcherFunc == NULL) {
-	// VALUE rb_vm_dispatch(struct mcache *cache, VALUE top, VALUE self,
-	// 	SEL sel, void *block, unsigned char opt, int argc, ...);
+	// VALUE rb_vm_dispatch(VALUE top, VALUE self, SEL sel, void *block,
+	// 	unsigned char opt, int argc, ...);
 	std::vector<const Type *> types;
-	types.push_back(PtrTy);
 	types.push_back(RubyObjTy);
 	types.push_back(RubyObjTy);
 	types.push_back(PtrTy);
@@ -764,7 +712,6 @@
 
     std::vector<Value *> params;
     const SEL sel = mid_to_sel(mid, argc);
-    params.push_back(compile_mcache(sel, false));
     params.push_back(current_self);
     params.push_back(recv);
     params.push_back(compile_sel(sel));
@@ -1891,7 +1838,7 @@
 	    return NULL;
 	}
 	
-	Value *val = params[2]; // self
+	Value *val = params[1]; // self
 
 	Function *f = bb->getParent();
 
@@ -1922,7 +1869,7 @@
 	    return NULL;
 	}
 
-	Value *leftVal = params[2]; // self
+	Value *leftVal = params[1]; // self
 	Value *rightVal = params.back();
 
 	Function *func = NULL;
@@ -1964,12 +1911,11 @@
 	GlobalVariable *is_redefined = GET_CORE()->redefined_op_gvar(sel, true);
 
 	Value *args[] = {
-	    compile_mcache(sel, false),
 	    leftVal,
 	    rightVal,
 	    new LoadInst(is_redefined, "", bb)
 	};
-	return compile_protected_call(func, args, args + 4);
+	return compile_protected_call(func, args, args + 3);
     }
     // Other operators (#<< or #[] or #[]=)
     else if (sel == selLTLT || sel == selAREF || sel == selASET) {
@@ -1979,7 +1925,7 @@
 	    return NULL;
 	}
 
-	if (params.size() - argc > 7) {
+	if (params.size() - argc > 6) {
 	    // Looks like there is a splat argument there, we can't handle this
 	    // in the primitives.
 	    return NULL;
@@ -1998,14 +1944,13 @@
 	assert(func != NULL);
 
 	std::vector<Value *> new_params;
-	new_params.push_back(params[2]);		// self
+	new_params.push_back(params[1]);		// self
 	if (argc == 1) {
 	    new_params.push_back(params.back());	// other
 	}
 	else {
 	    new_params.insert(new_params.end(), params.end() - 2, params.end());
 	}
-	new_params.push_back(params[0]);		// cache
 
 	GlobalVariable *is_redefined = GET_CORE()->redefined_op_gvar(sel, true);
 	new_params.push_back(new LoadInst(is_redefined, "", bb));
@@ -2044,16 +1989,15 @@
 
 	bb = thenBB;
 	std::vector<Value *> new_params;
-	new_params.push_back(compile_mcache(new_sel, false));
 	// Compile a null top reference, to ignore protected visibility.
 	new_params.push_back(ConstantInt::get(RubyObjTy, 0));
-	new_params.push_back(params[2]);
+	new_params.push_back(params[1]);
 	new_params.push_back(compile_sel(new_sel));
-	new_params.push_back(params[4]);
+	new_params.push_back(params[3]);
 	new_params.push_back(ConstantInt::get(Int8Ty, DISPATCH_FCALL));
 	new_params.push_back(ConstantInt::get(Int32Ty, argc - 1));
 	for (int i = 0; i < argc - 1; i++) {
-	    new_params.push_back(params[8 + i]);
+	    new_params.push_back(params[7 + i]);
 	}
 	Value *thenVal = compile_dispatch_call(new_params);
 	thenBB = bb;
@@ -2899,7 +2843,6 @@
 		    assert(node->nd_next->nd_vid > 0);
 		    sel = mid_to_sel(node->nd_next->nd_vid, 0);
 		}
-		params.push_back(compile_mcache(sel, false));
 		params.push_back(current_self);
 		params.push_back(recv);
 		params.push_back(compile_sel(sel));
@@ -2959,7 +2902,6 @@
 			? node->nd_mid : node->nd_next->nd_mid;
 		    sel = mid_to_sel(mid, 1);
 		    params.clear();
-		    params.push_back(compile_mcache(sel, false));
 		    params.push_back(current_self);
 		    params.push_back(tmp);
 		    params.push_back(compile_sel(sel));
@@ -2984,7 +2926,6 @@
 		    sel = mid_to_sel(node->nd_next->nd_aid, 1);
 		}
 		params.clear();
-		params.push_back(compile_mcache(sel, false));
 		params.push_back(current_self);
 		params.push_back(recv);
 		params.push_back(compile_sel(sel));
@@ -3036,7 +2977,6 @@
 		}
 
 		std::vector<Value *> params;
-		params.push_back(compile_mcache(selBackquote, false));
 		params.push_back(current_self);
 		params.push_back(current_self);
 		params.push_back(compile_sel(selBackquote));
@@ -3477,7 +3417,7 @@
 		// Prepare the dispatcher parameters.
 		std::vector<Value *> params;
 
-		// Method cache (and prepare the selector).
+		// Prepare the selector.
 		Value *sel_val;
 		SEL sel;
 		if (mid != 0) {
@@ -3503,18 +3443,13 @@
 				dyn_sel, compile_const_pointer(NULL));
 			sel_val = SelectInst::Create(is_null, sel_val, dyn_sel,
 				"", bb);
-			params.push_back(compile_get_mcache(sel_val, true));
 		    }
-		    else {
-			params.push_back(compile_mcache(sel, super_call));
-		    }
 		}
 		else {
 		    assert(super_call);
 		    // A super call outside a method definition. Compile a
 		    // null selector, the runtime will raise an exception.
 		    sel = 0;
-		    params.push_back(compile_const_pointer(NULL));
 		    sel_val = compile_const_pointer(NULL);
 		}
 
@@ -3626,7 +3561,7 @@
 			blockVal = compile_const_pointer(NULL);
 		    }
 		}
-		params[4] = blockVal;
+		params[3] = blockVal;
 
 		// If we are calling a method that needs a top-level binding
 		// object, let's create it.
@@ -3845,7 +3780,6 @@
 		}
 
 		std::vector<Value *> params;
-		params.push_back(compile_mcache(selEqTilde, false));
 		params.push_back(current_self);
 		params.push_back(reTarget);
 		params.push_back(compile_sel(selEqTilde));
@@ -4424,7 +4358,6 @@
 		    // dispatch #each on the receiver
 		    std::vector<Value *> params;
 
-		    params.push_back(compile_mcache((is_lambda ? selLambda : selEach), false));
 		    params.push_back(current_self);
 
 		    if (!is_lambda) {
@@ -4641,7 +4574,6 @@
 
 		std::vector<Value *> params;
 		SEL sel = sel_registerName("at_exit");
-		params.push_back(compile_mcache(sel, false));
 		params.push_back(current_self);
 		params.push_back(compile_nsobject());
 		params.push_back(compile_sel(sel));
@@ -4723,33 +4655,6 @@
 	function->getEntryBlock().getInstList();
     bb = &function->getEntryBlock();
 
-    // Compile method caches.
-
-    Function *getMethodCacheFunc = cast<Function>(module->getOrInsertFunction(
-		"rb_vm_get_method_cache",
-		PtrTy, PtrTy, NULL));
-
-    for (std::map<SEL, GlobalVariable *>::iterator i = mcaches.begin();
-	 i != mcaches.end();
-	 ++i) {
-
-	SEL sel = i->first;
-	GlobalVariable *gvar = i->second;
-
-	Value *load = compile_sel(sel, false);
-
-	Instruction *call = CallInst::Create(getMethodCacheFunc, load, "");
-
-	Instruction *assign = new StoreInst(call, gvar, "");
-
-	list.insert(list.begin(), assign);
-	list.insert(list.begin(), call);
-	Instruction *load_insn = dyn_cast<Instruction>(load);
-	if (load_insn != NULL) {
-	    list.insert(list.begin(), load_insn);
-	}
-    }
-
     // Compile constant caches.
 
     Function *getConstCacheFunc = cast<Function>(module->getOrInsertFunction(
@@ -6359,10 +6264,12 @@
     rescue_invoke_bb = old_rescue_invoke_bb;
 #endif
 
-    // Now that the function is finished, we can inline the Ruby method.
-    if (CallInst::classof(ruby_call_insn)) {
-	CallInst *insn = cast<CallInst>(ruby_call_insn);
-	InlineFunction(insn);
+    if (ruby_func != NULL) {
+	// Now that the function is finished, we can inline the Ruby method.
+	if (CallInst::classof(ruby_call_insn)) {
+	    CallInst *insn = cast<CallInst>(ruby_call_insn);
+	    InlineFunction(insn);
+	}
     }
 
     return f;

Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/compiler.h	2010-06-01 09:27:08 UTC (rev 4181)
@@ -357,8 +357,6 @@
 	void compile_return_from_block(Value *val, int id);
 	void compile_return_from_block_handler(int id);
 	Value *compile_jump(NODE *node);
-	virtual Value *compile_mcache(SEL sel, bool super);
-	Value *compile_get_mcache(Value *sel, bool super);
 	virtual Value *compile_ccache(ID id);
 	virtual Value *compile_sel(SEL sel, bool add_to_bb=true) {
 	    return compile_const_pointer(sel, PtrTy);
@@ -431,7 +429,6 @@
 	Function *compile_main_function(NODE *node);
 
     private:
-	std::map<SEL, GlobalVariable *> mcaches;
 	std::map<ID, GlobalVariable *> ccaches;
 	std::map<SEL, GlobalVariable *> sels;
 	std::map<ID, GlobalVariable *> ids;
@@ -443,7 +440,6 @@
 	GlobalVariable *cStandardError_gvar;
 	std::vector<GlobalVariable *> class_gvars;
 
-	Value *compile_mcache(SEL sel, bool super);
 	Value *compile_ccache(ID id);
 	Value *compile_sel(SEL sel, bool add_to_bb=true);
 	void compile_prepare_method(Value *classVal, Value *sel,

Modified: MacRuby/trunk/complex.c
===================================================================
--- MacRuby/trunk/complex.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/complex.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -31,28 +31,28 @@
 inline static VALUE \
 f_##n(VALUE x, VALUE y)\
 {\
-    return rb_vm_call(x, op, 1, &y, false);\
+    return rb_vm_call(x, op, 1, &y);\
 }
 
 #define fun1(n) \
 inline static VALUE \
 f_##n(VALUE x)\
 {\
-    return rb_vm_call(x, sel_##n, 0, NULL, false);\
+    return rb_vm_call(x, sel_##n, 0, NULL);\
 }
 
 #define fun2(n) \
 inline static VALUE \
 f_##n(VALUE x, VALUE y)\
 {\
-    return rb_vm_call(x, sel_##n, 1, &y, false);\
+    return rb_vm_call(x, sel_##n, 1, &y);\
 }
 
 #define math1(n) \
 inline static VALUE \
 m_##n(VALUE x)\
 {\
-    return rb_vm_call(rb_mMath, sel_##n, 1, &x, false);\
+    return rb_vm_call(rb_mMath, sel_##n, 1, &x);\
 }
 
 #define math2(n) \
@@ -60,7 +60,7 @@
 m_##n(VALUE x, VALUE y)\
 {\
     VALUE args[2]; args[0] = x; args[1] = y;\
-    return rb_vm_call(rb_mMath, sel_##n, 2, args, false);\
+    return rb_vm_call(rb_mMath, sel_##n, 2, args);\
 }
 
 #define PRESERVE_SIGNEDZERO
@@ -74,7 +74,7 @@
     else if (FIXNUM_P(x) && FIX2LONG(x) == 0)
 	return y;
 #endif
-    return rb_vm_call(x, selPLUS, 1, &y, false);
+    return rb_vm_call(x, selPLUS, 1, &y);
 }
 
 inline static VALUE
@@ -90,31 +90,34 @@
 	}
 	return INT2FIX(c);
     }
-    return rb_vm_call(x, selCmp, 1, &y, false);
+    return rb_vm_call(x, selCmp, 1, &y);
 }
 
 inline static VALUE
 f_div(VALUE x, VALUE y)
 {
-    if (FIXNUM_P(y) && FIX2LONG(y) == 1)
+    if (FIXNUM_P(y) && FIX2LONG(y) == 1) {
 	return x;
-    return rb_vm_call(x, selDIV, 1, &y, false);
+    }
+    return rb_vm_call(x, selDIV, 1, &y);
 }
 
 inline static VALUE
 f_gt_p(VALUE x, VALUE y)
 {
-    if (FIXNUM_P(x) && FIXNUM_P(y))
+    if (FIXNUM_P(x) && FIXNUM_P(y)) {
 	return f_boolcast(FIX2LONG(x) > FIX2LONG(y));
-    return rb_vm_call(x, selGT, 1, &y, false);
+    }
+    return rb_vm_call(x, selGT, 1, &y);
 }
 
 inline static VALUE
 f_lt_p(VALUE x, VALUE y)
 {
-    if (FIXNUM_P(x) && FIXNUM_P(y))
+    if (FIXNUM_P(x) && FIXNUM_P(y)) {
 	return f_boolcast(FIX2LONG(x) < FIX2LONG(y));
-    return rb_vm_call(x, selLT, 1, &y, false);
+    }
+    return rb_vm_call(x, selLT, 1, &y);
 }
 
 binop(mod, selMOD)
@@ -142,7 +145,7 @@
 	    return y;
     }
 #endif
-    return rb_vm_call(x, selMULT, 1, &y, false);
+    return rb_vm_call(x, selMULT, 1, &y);
 }
 
 inline static VALUE
@@ -152,7 +155,7 @@
     if (FIXNUM_P(y) && FIX2LONG(y) == 0)
 	return x;
 #endif
-    return rb_vm_call(x, selMINUS, 1, &y, false);
+    return rb_vm_call(x, selMINUS, 1, &y);
 }
 
 fun1(abs)
@@ -181,7 +184,7 @@
     if (FIXNUM_P(x) && FIXNUM_P(y)) {
 	return f_boolcast(FIX2LONG(x) == FIX2LONG(y));
     }
-    return rb_vm_call(x, selEq, 1, &y, false);
+    return rb_vm_call(x, selEq, 1, &y);
 }
 
 fun2(expt)
@@ -196,7 +199,7 @@
 	return f_boolcast(FIX2LONG(x) < 0);
     }
     VALUE v = ZERO;
-    return rb_vm_call(x, selLT, 1, &v, false);
+    return rb_vm_call(x, selLT, 1, &v);
 }
 
 #define f_positive_p(x) (!f_negative_p(x))
@@ -217,7 +220,7 @@
       }
     }
     VALUE v = ZERO;
-    return rb_vm_call(x, selEq, 1, &v, false);
+    return rb_vm_call(x, selEq, 1, &v);
 }
 
 #define f_nonzero_p(x) (!f_zero_p(x))
@@ -240,7 +243,7 @@
       }
     }
     VALUE v = ONE;
-    return rb_vm_call(x, selEq, 1, &v, false);
+    return rb_vm_call(x, selEq, 1, &v);
 }
 
 inline static VALUE
@@ -479,7 +482,7 @@
 static VALUE
 nucomp_f_complex(VALUE klass, SEL sel, int argc, VALUE *argv)
 {
-    return rb_vm_call(rb_cComplex, sel_convert, argc, argv, false);
+    return rb_vm_call(rb_cComplex, sel_convert, argc, argv);
 }
 
 #define imp1(n) \

Modified: MacRuby/trunk/dispatcher.cpp
===================================================================
--- MacRuby/trunk/dispatcher.cpp	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/dispatcher.cpp	2010-06-01 09:27:08 UTC (rev 4181)
@@ -347,10 +347,8 @@
 	return Qnil; // never reached
     }
     else {
-	struct mcache *cache = GET_CORE()->method_cache_get(selMethodMissing,
-		false);
-	return rb_vm_call_with_cache2(cache, block, obj, NULL, selMethodMissing,
-		argc + 1, new_argv);
+	return rb_vm_call2(block, obj, (VALUE)k, selMethodMissing, argc + 1,
+		new_argv);
     }
 }
 
@@ -464,8 +462,9 @@
 	rb_vm_method_node_t *node)
 {
     cache->flag = MCACHE_RCALL;
-    rcache.klass = klass;
-    rcache.node = node;
+    cache->sel = sel;
+    cache->klass = klass;
+    cache->as.rcall.node = node;
 }
 
 static void
@@ -473,12 +472,13 @@
 	    Method method, int argc)
 {
     cache->flag = MCACHE_OCALL;
-    ocache.klass = klass;
-    ocache.imp = imp;
-    ocache.bs_method = GET_CORE()->find_bs_method(klass, sel);
+    cache->sel = sel;
+    cache->klass = klass;
+    cache->as.ocall.imp = imp;
+    cache->as.ocall.bs_method = GET_CORE()->find_bs_method(klass, sel);
 
     char types[200];
-    if (!rb_objc_get_types(self, klass, sel, method, ocache.bs_method,
+    if (!rb_objc_get_types(self, klass, sel, method, cache->as.ocall.bs_method,
 		types, sizeof types)) {
 	printf("cannot get encoding types for %c[%s %s]\n",
 		class_isMetaClass(klass) ? '+' : '-',
@@ -487,8 +487,8 @@
 	abort();
     }
     bool variadic = false;
-    if (ocache.bs_method != NULL && ocache.bs_method->variadic
-	&& method != NULL) {
+    if (cache->as.ocall.bs_method != NULL
+	    && cache->as.ocall.bs_method->variadic && method != NULL) {
 	// TODO honor printf_format
 	const int real_argc = method_getNumberOfArguments(method) - 2;
 	if (real_argc < argc) {
@@ -501,8 +501,8 @@
 	}
 	variadic = true;
     }
-    ocache.stub = (rb_vm_objc_stub_t *)GET_CORE()->gen_stub(types, variadic,
-	    argc, true);
+    cache->as.ocall.stub = (rb_vm_objc_stub_t *)GET_CORE()->gen_stub(types,
+	    variadic, argc, true);
 }
 
 static bool
@@ -520,7 +520,6 @@
     }
 
     GET_CORE()->retype_method(klass, node, method_getTypeEncoding(m), types);
-
     return true;
 }
 
@@ -536,22 +535,34 @@
     return x_imp == y_imp;
 }
 
+static int
+mcache_hash(Class klass, SEL sel)
+{
+    return (((unsigned long)klass >> 3) ^ (unsigned long)sel)
+	& (VM_MCACHE_SIZE - 1);
+}
+
+static struct mcache *
+mcache_get(RoxorVM *vm, Class klass, SEL sel, bool super)
+{
+    struct mcache *cache;
+    if (super) {
+	const int hash = mcache_hash(klass, sel) + 1;
+	cache = &vm->get_mcache()[hash];
+	cache->flag = 0; // TODO
+    }
+    else {
+	const int hash = mcache_hash(klass, sel);
+	cache = &vm->get_mcache()[hash];
+    }
+    return cache;
+}
+
 static force_inline VALUE
-__rb_vm_dispatch(RoxorVM *vm, struct mcache *cache, VALUE top, VALUE self,
+vm_call_with_cache(RoxorVM *vm, struct mcache *cache, VALUE top, VALUE self,
 	Class klass, SEL sel, rb_vm_block_t *block, unsigned char opt,
 	int argc, const VALUE *argv)
 {
-    if (cache == NULL) {
-	if (sel == 0 && opt == DISPATCH_SUPER) {
-	    rb_raise(rb_eNoMethodError, "super called outside of method");
-	}
-	abort(); 
-    }
-
-    if (klass == NULL) {
-	klass = (Class)CLASS_OF(self);
-    }
-
 #if ROXOR_VM_DEBUG
     bool cached = true;
 #endif
@@ -560,14 +571,7 @@
     Class current_super_class = vm->get_current_super_class();
     SEL current_super_sel = vm->get_current_super_sel();
 
-    // XXX: super method cache is disabled because it causes random runtime
-    // bugs in rails. Instead of fixing the problem, we wait for the new
-    // method cache implementation which should be different (and thread-safe).
-    if (opt == DISPATCH_SUPER) {
-	cache->flag = 0;
-    }
-
-    if (cache->flag == 0) {
+    if (cache->sel != sel || cache->klass != klass || cache->flag == 0) {
 recache:
 #if ROXOR_VM_DEBUG
 	cached = false;
@@ -606,6 +610,10 @@
 		// objc call
 		fill_ocache(cache, self, klass, imp, sel, method, argc);
 	    }
+
+	    if (opt == DISPATCH_SUPER) {
+		cache->flag |= MCACHE_SUPER;
+	    }
 	}
 	else {
 	    // Method is not found...
@@ -705,11 +713,13 @@
 		vm_gen_bs_func_types(argc, argv, bs_func, types);
 
 		cache->flag = MCACHE_FCALL;
-		fcache.bs_function = bs_func;
-		fcache.imp = (IMP)dlsym(RTLD_DEFAULT, bs_func->name);
-		assert(fcache.imp != NULL);
-		fcache.stub = (rb_vm_c_stub_t *)GET_CORE()->gen_stub(types,
-			bs_func->variadic, bs_func->args_count, false);
+		cache->sel = sel;
+		cache->klass = klass;
+		cache->as.fcall.bs_function = bs_func;
+		cache->as.fcall.imp = (IMP)dlsym(RTLD_DEFAULT, bs_func->name);
+		assert(cache->as.fcall.imp != NULL);
+		cache->as.fcall.stub = (rb_vm_c_stub_t *)GET_CORE()->gen_stub(
+			types, bs_func->variadic, bs_func->args_count, false);
 	    }
 	    else {
 		// Still nothing, then let's call #method_missing.
@@ -719,10 +729,7 @@
     }
 
 dispatch:
-    if (cache->flag == MCACHE_RCALL) {
-	if (rcache.klass != klass) {
-	    goto recache;
-	}
+    if (cache->flag & MCACHE_RCALL) {
 	if (!cache_method) {
 	    cache->flag = 0;
 	}
@@ -733,7 +740,7 @@
 		class_getName(klass),
 		(void *)self,
 		sel_getName(sel),
-		rcache.node->ruby_imp,
+		cache->as.rcall.node->ruby_imp,
 		block,
 		argc,
 		opt,
@@ -791,8 +798,8 @@
 	    MACRUBY_METHOD_ENTRY(class_name, method_name, file, line);
 	}
 
-	VALUE v = __rb_vm_ruby_dispatch(top, self, sel, rcache.node, opt,
-		argc, argv);
+	VALUE v = __rb_vm_ruby_dispatch(top, self, sel, cache->as.rcall.node,
+		opt, argc, argv);
 
 	// DTrace probe: method__return
 	if (MACRUBY_METHOD_RETURN_ENABLED()) {
@@ -807,10 +814,7 @@
 
 	return v;
     }
-    else if (cache->flag == MCACHE_OCALL) {
-	if (ocache.klass != klass) {
-	    goto recache;
-	}
+    else if (cache->flag & MCACHE_OCALL) {
 	if (!cache_method) {
 	    cache->flag = 0;
 	}
@@ -843,21 +847,24 @@
 	}
 
 #if ROXOR_VM_DEBUG
-	printf("objc dispatch %c[<%s %p> %s] imp=%p argc=%d (cached=%s)\n",
+	printf("objc dispatch %c[<%s %p> %s] imp=%p cache=%p argc=%d (cached=%s)\n",
 		class_isMetaClass(klass) ? '+' : '-',
 		class_getName(klass),
 		(void *)self,
 		sel_getName(sel),
-		ocache.imp,
+		cache->as.ocall.imp,
+		cache,
 		argc,
 		cached ? "true" : "false");
 #endif
 
 	id ocrcv = RB2OC(self);
 
- 	if (ocache.bs_method != NULL) {
-	    for (int i = 0; i < (int)ocache.bs_method->args_count; i++) {
-		bs_element_arg_t *arg = &ocache.bs_method->args[i];
+ 	if (cache->as.ocall.bs_method != NULL) {
+	    Class ocklass = object_getClass(ocrcv);
+	    for (int i = 0; i < (int)cache->as.ocall.bs_method->args_count;
+		    i++) {
+		bs_element_arg_t *arg = &cache->as.ocall.bs_method->args[i];
 		if (arg->sel_of_type != NULL) {
 		    // BridgeSupport tells us that this argument contains a
 		    // selector of the given type, but we don't have any
@@ -870,12 +877,12 @@
 		    // that either the receiver or one of the arguments of this
 		    // call is the future target.
 		    const int arg_i = arg->index;
-		    assert(arg_i >= 0);
+		    assert(arg_i >= 0 && arg_i < argc);
 		    if (argv[arg_i] != Qnil) {
 			ID arg_selid = rb_to_id(argv[arg_i]);
 			SEL arg_sel = sel_registerName(rb_id2name(arg_selid));
 
-			if (reinstall_method_maybe(*(Class *)ocrcv, arg_sel,
+			if (reinstall_method_maybe(ocklass, arg_sel,
 				    arg->sel_of_type)) {
 			    goto sel_target_found;
 			}
@@ -896,18 +903,18 @@
 	    }
 	}
 
-	return __rb_vm_objc_dispatch(ocache.stub, ocache.imp, ocrcv, sel,
-		argc, argv);
+	return __rb_vm_objc_dispatch(cache->as.ocall.stub, cache->as.ocall.imp,
+		ocrcv, sel, argc, argv);
     }
-    else if (cache->flag == MCACHE_FCALL) {
+    else if (cache->flag & MCACHE_FCALL) {
 #if ROXOR_VM_DEBUG
 	printf("C dispatch %s() imp=%p argc=%d (cached=%s)\n",
-		fcache.bs_function->name,
-		fcache.imp,
+		cache->as.fcall.bs_function->name,
+		cache->as.fcall.imp,
 		argc,
 		cached ? "true" : "false");
 #endif
-	return (*fcache.stub)(fcache.imp, argc, argv);
+	return (*cache->as.fcall.stub)(cache->as.fcall.imp, argc, argv);
     }
 
     printf("method dispatch is b0rked\n");
@@ -964,6 +971,15 @@
     return method_missing((VALUE)self, sel, block, argc, argv, status);
 }
 
+static force_inline VALUE
+vm_call(RoxorVM *vm, VALUE top, VALUE self, Class klass, SEL sel,
+	rb_vm_block_t *block, unsigned char opt, int argc, const VALUE *argv)
+{
+    struct mcache *cache = mcache_get(vm, klass, sel, opt == DISPATCH_SUPER);
+    return vm_call_with_cache(vm, cache, top, self, klass, sel, block, opt,
+	    argc, argv);
+}
+
 static force_inline void
 __rb_vm_resolve_args(VALUE **pargv, size_t argv_size, int *pargc, va_list ar)
 {
@@ -1022,9 +1038,16 @@
 
 extern "C"
 VALUE
-rb_vm_dispatch(struct mcache *cache, VALUE top, VALUE self, SEL sel,
-	rb_vm_block_t *block, unsigned char opt, int argc, ...)
+rb_vm_dispatch(VALUE top, VALUE self, SEL sel, rb_vm_block_t *block,
+	unsigned char opt, int argc, ...)
 {
+    if (sel == 0) {
+	if (opt == DISPATCH_SUPER) {
+	    rb_raise(rb_eNoMethodError, "super called outside of method");
+	}
+	abort(); 
+    }
+
     VALUE base_argv[MAX_DISPATCH_ARGS];
     VALUE *argv = base_argv;
     if (argc > 0) {
@@ -1056,47 +1079,36 @@
 	~Finally() { vm->pop_current_binding(); }
     } finalizer(vm);
 
-    VALUE retval = __rb_vm_dispatch(vm, cache, top, self, NULL, sel, block,
+    return vm_call(vm, top, self, (Class)CLASS_OF(self), sel, block,
 	    opt, argc, argv);
-
-    return retval;
 }
 
 extern "C"
 VALUE
-rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *argv, bool super)
+rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *argv)
 {
-    struct mcache *cache;
-    unsigned char opt = DISPATCH_FCALL;
-    if (super) {
-	cache = (struct mcache *)alloca(sizeof(struct mcache));
-	cache->flag = 0;
-	opt = DISPATCH_SUPER;
-    }
-    else {
-	cache = GET_CORE()->method_cache_get(sel, false);
-    }
-
-    return __rb_vm_dispatch(GET_VM(), cache, 0, self, NULL, sel, NULL, opt,
-	    argc, argv);
+    return vm_call(GET_VM(), 0, self, (Class)CLASS_OF(self), sel, NULL,
+	    DISPATCH_FCALL, argc, argv);
 }
 
 extern "C"
 VALUE
-rb_vm_call_with_cache(void *cache, VALUE self, SEL sel, int argc, 
-	const VALUE *argv)
+rb_vm_call_super(VALUE self, SEL sel, int argc, const VALUE *argv)
 {
-    return __rb_vm_dispatch(GET_VM(), (struct mcache *)cache, 0, self, NULL,
-	    sel, NULL, DISPATCH_FCALL, argc, argv);
+    return vm_call(GET_VM(), 0, self, (Class)CLASS_OF(self), sel, NULL,
+	    DISPATCH_SUPER, argc, argv);
 }
 
 extern "C"
 VALUE
-rb_vm_call_with_cache2(void *cache, rb_vm_block_t *block, VALUE self,
-	VALUE klass, SEL sel, int argc, const VALUE *argv)
+rb_vm_call2(rb_vm_block_t *block, VALUE self, VALUE klass, SEL sel, int argc,
+	const VALUE *argv)
 {
-    return __rb_vm_dispatch(GET_VM(), (struct mcache *)cache, 0, self,
-	    (Class)klass, sel, block, DISPATCH_FCALL, argc, argv);
+    if (klass == 0) {
+	klass = CLASS_OF(self);
+    }
+    return vm_call(GET_VM(), 0, self, (Class)klass, sel, block,
+	    DISPATCH_FCALL, argc, argv);
 }
 
 static rb_vm_block_t *
@@ -1264,8 +1276,8 @@
 
     if (b->flags & VM_BLOCK_METHOD) {
 	rb_vm_method_t *m = (rb_vm_method_t *)b->imp;
-	return rb_vm_call_with_cache2(m->cache, NULL, m->recv, m->oclass,
-		m->sel, argc, argv);
+	return vm_call_with_cache(vm, (struct mcache *)m->cache, 0, m->recv,
+		(Class)m->oclass, m->sel, NULL, DISPATCH_FCALL, argc, argv);
     }
     return __rb_vm_bcall(self, sel, (VALUE)b->dvars, b, b->imp, b->arity,
 	    argc, argv);
@@ -1655,7 +1667,7 @@
 		args[n++] = Qtrue;
 	    }
 	}
-	return rb_vm_call(obj, selRespondTo, n, args, false) == Qtrue;
+	return rb_vm_call(obj, selRespondTo, n, args) == Qtrue;
     }
 }
 

Modified: MacRuby/trunk/enum.c
===================================================================
--- MacRuby/trunk/enum.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/enum.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -82,7 +82,7 @@
     arg[0] = pat;
     arg[1] = ary;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, rb_block_given_p() ? grep_iter_i : grep_i, (VALUE)arg);
+    rb_objc_block_call(obj, selEach, 0, 0, rb_block_given_p() ? grep_iter_i : grep_i, (VALUE)arg);
 
     return ary;
 }
@@ -165,7 +165,7 @@
     }
 
     memo[0] = 0;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, func, (VALUE)&memo);
+    rb_objc_block_call(obj, selEach, 0, 0, func, (VALUE)&memo);
     return INT2NUM(memo[0]);
 }
 
@@ -204,7 +204,7 @@
 
     rb_scan_args(argc, argv, "01", &if_none);
     RETURN_ENUMERATOR(obj, argc, argv);
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, find_i, (VALUE)&memo);
+    rb_objc_block_call(obj, selEach, 0, 0, find_i, (VALUE)&memo);
     if (memo != Qundef) {
 	return memo;
     }
@@ -278,7 +278,7 @@
 
     memo[0] = Qnil;
     memo[1] = 0;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, func, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, func, (VALUE)memo);
     return memo[0];
 }
 
@@ -314,7 +314,7 @@
     RETURN_ENUMERATOR(obj, 0, 0);
 
     ary = rb_ary_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, find_all_i, ary);
+    rb_objc_block_call(obj, selEach, 0, 0, find_all_i, ary);
 
     return ary;
 }
@@ -349,7 +349,7 @@
     RETURN_ENUMERATOR(obj, 0, 0);
 
     ary = rb_ary_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, reject_i, ary);
+    rb_objc_block_call(obj, selEach, 0, 0, reject_i, ary);
 
     return ary;
 }
@@ -391,7 +391,7 @@
     RETURN_ENUMERATOR(obj, 0, 0);
 
     ary = rb_ary_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, collect_i, ary);
+    rb_objc_block_call(obj, selEach, 0, 0, collect_i, ary);
 
     return ary;
 }
@@ -433,7 +433,7 @@
     RETURN_ENUMERATOR(obj, 0, 0);
 
     ary = rb_ary_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, flat_map_i, ary);
+    rb_objc_block_call(obj, selEach, 0, 0, flat_map_i, ary);
 
     return ary;
 }
@@ -453,7 +453,7 @@
 {
     VALUE ary = rb_ary_new();
 
-    rb_objc_block_call(obj, selEach, cacheEach, argc, argv, collect_all, ary);
+    rb_objc_block_call(obj, selEach, argc, argv, collect_all, ary);
 
     return ary;
 }
@@ -561,7 +561,7 @@
 	iter = inject_op_i;
 	break;
     }
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, iter, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, iter, (VALUE)memo);
     if (memo[0] == Qundef) {
 	return Qnil;
     }
@@ -603,7 +603,7 @@
 
     ary[0] = rb_ary_new();
     ary[1] = rb_ary_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, partition_i, (VALUE)ary);
+    rb_objc_block_call(obj, selEach, 0, 0, partition_i, (VALUE)ary);
 
     return rb_assoc_new(ary[0], ary[1]);
 }
@@ -648,7 +648,7 @@
     RETURN_ENUMERATOR(obj, 0, 0);
 
     hash = rb_hash_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, group_by_i, hash);
+    rb_objc_block_call(obj, selEach, 0, 0, group_by_i, hash);
 
     return hash;
 }
@@ -701,7 +701,7 @@
 	ary[0] = n;
 	ary[1] = rb_ary_new2(NUM2LONG(n));
     }
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, first_i, (VALUE)ary);
+    rb_objc_block_call(obj, selEach, 0, 0, first_i, (VALUE)ary);
 
     return ary[1];
 }
@@ -835,7 +835,7 @@
     else {
 	ary = rb_ary_new();
     }
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, sort_by_i, ary);
+    rb_objc_block_call(obj, selEach, 0, 0, sort_by_i, ary);
     if (RARRAY_LEN(ary) > 1) {
 	qsort_r((VALUE *)RARRAY_PTR(ary), RARRAY_LEN(ary), sizeof(VALUE), NULL,
 		sort_by_cmp);
@@ -893,7 +893,7 @@
 {
     VALUE result = Qtrue;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, rb_block_given_p() ? all_iter_i : all_i, (VALUE)&result);
+    rb_objc_block_call(obj, selEach, 0, 0, rb_block_given_p() ? all_iter_i : all_i, (VALUE)&result);
     return result;
 }
 
@@ -932,7 +932,7 @@
 {
     VALUE result = Qfalse;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, rb_block_given_p() ? any_iter_i : any_i, (VALUE)&result);
+    rb_objc_block_call(obj, selEach, 0, 0, rb_block_given_p() ? any_iter_i : any_i, (VALUE)&result);
     return result;
 }
 
@@ -976,7 +976,7 @@
 {
     VALUE result = Qundef;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, rb_block_given_p() ? one_iter_i : one_i, (VALUE)&result);
+    rb_objc_block_call(obj, selEach, 0, 0, rb_block_given_p() ? one_iter_i : one_i, (VALUE)&result);
     if (result == Qundef) return Qfalse;
     return result;
 }
@@ -1013,7 +1013,7 @@
 {
     VALUE result = Qtrue;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, rb_block_given_p() ? none_iter_i : none_i, (VALUE)&result);
+    rb_objc_block_call(obj, selEach, 0, 0, rb_block_given_p() ? none_iter_i : none_i, (VALUE)&result);
     return result;
 }
 
@@ -1081,10 +1081,10 @@
     result[0] = Qundef;
     if (rb_block_given_p()) {
 	result[1] = rb_ary_new3(2, Qnil, Qnil);
-	rb_objc_block_call(obj, selEach, cacheEach, 0, 0, min_ii, (VALUE)result);
+	rb_objc_block_call(obj, selEach, 0, 0, min_ii, (VALUE)result);
     }
     else {
-	rb_objc_block_call(obj, selEach, cacheEach, 0, 0, min_i, (VALUE)result);
+	rb_objc_block_call(obj, selEach, 0, 0, min_i, (VALUE)result);
     }
     if (result[0] == Qundef) return Qnil;
     return result[0];
@@ -1153,10 +1153,10 @@
     result[0] = Qundef;
     if (rb_block_given_p()) {
 	result[1] = rb_ary_new3(2, Qnil, Qnil);
-	rb_objc_block_call(obj, selEach, cacheEach, 0, 0, max_ii, (VALUE)result);
+	rb_objc_block_call(obj, selEach, 0, 0, max_ii, (VALUE)result);
     }
     else {
-	rb_objc_block_call(obj, selEach, cacheEach, 0, 0, max_i, (VALUE)result);
+	rb_objc_block_call(obj, selEach, 0, 0, max_i, (VALUE)result);
     }
     if (result[0] == Qundef) return Qnil;
     return result[0];
@@ -1240,10 +1240,10 @@
     result[0] = Qundef;
     if (rb_block_given_p()) {
 	result[2] = ary;
-	rb_objc_block_call(obj, selEach, cacheEach, 0, 0, minmax_ii, (VALUE)result);
+	rb_objc_block_call(obj, selEach, 0, 0, minmax_ii, (VALUE)result);
     }
     else {
-	rb_objc_block_call(obj, selEach, cacheEach, 0, 0, minmax_i, (VALUE)result);
+	rb_objc_block_call(obj, selEach, 0, 0, minmax_i, (VALUE)result);
     }
     if (result[0] != Qundef) {
 	rb_ary_store(ary, 0, result[0]);
@@ -1291,7 +1291,7 @@
 
     memo[0] = Qundef;
     memo[1] = Qnil;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, min_by_i, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, min_by_i, (VALUE)memo);
     return memo[1];
 }
 
@@ -1334,7 +1334,7 @@
 
     memo[0] = Qundef;
     memo[1] = Qnil;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, max_by_i, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, max_by_i, (VALUE)memo);
     return memo[1];
 }
 
@@ -1388,7 +1388,7 @@
     memo[1] = Qundef;
     memo[2] = Qnil;
     memo[3] = Qnil;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, minmax_by_i, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, minmax_by_i, (VALUE)memo);
     return rb_assoc_new(memo[2], memo[3]);
 }
 
@@ -1422,7 +1422,7 @@
 
     memo[0] = val;
     memo[1] = Qfalse;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, member_i, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, member_i, (VALUE)memo);
     return memo[1];
 }
 
@@ -1458,7 +1458,7 @@
     RETURN_ENUMERATOR(obj, argc, argv);
 
     memo = 0;
-    rb_objc_block_call(obj, selEach, cacheEach, argc, argv, each_with_index_i, (VALUE)&memo);
+    rb_objc_block_call(obj, selEach, argc, argv, each_with_index_i, (VALUE)&memo);
     return obj;
 }
 
@@ -1522,7 +1522,7 @@
 enum_each_entry(VALUE obj, SEL sel, int argc, VALUE *argv)
 {
     RETURN_ENUMERATOR(obj, argc, argv);
-    rb_objc_block_call(obj, selEach, cacheEach, argc, argv, each_val_i, 0);
+    rb_objc_block_call(obj, selEach, argc, argv, each_val_i, 0);
     return obj;
 }
 
@@ -1574,7 +1574,7 @@
     args[0] = rb_ary_new2(size);
     args[1] = (VALUE)size;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, each_slice_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, each_slice_i, (VALUE)args);
 
     ary = args[0];
     if (RARRAY_LEN(ary) > 0) {
@@ -1636,7 +1636,7 @@
     args[0] = rb_ary_new2(size);
     args[1] = (VALUE)size;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, each_cons_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, each_cons_i, (VALUE)args);
 
     return Qnil;
 }
@@ -1668,8 +1668,7 @@
 {
     RETURN_ENUMERATOR(obj, 1, &memo);
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0,
-	each_with_object_i, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, each_with_object_i, (VALUE)memo);
 
     return memo;
 }
@@ -1803,7 +1802,7 @@
 	result = rb_ary_new();
     }
     memo = rb_node_newnode(NODE_MEMO, result, args, 0);
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);
+    rb_objc_block_call(obj, selEach, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);
 
     return result;
 }
@@ -1844,7 +1843,7 @@
     }
     args[0] = rb_ary_new();
     args[1] = len;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, take_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, take_i, (VALUE)args);
     return args[0];
 }
 
@@ -1878,7 +1877,7 @@
 
     RETURN_ENUMERATOR(obj, 0, 0);
     ary = rb_ary_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, take_while_i, (VALUE)&ary);
+    rb_objc_block_call(obj, selEach, 0, 0, take_while_i, (VALUE)&ary);
     return ary;
 }
 
@@ -1918,7 +1917,7 @@
 
     args[1] = len;
     args[0] = rb_ary_new();
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, drop_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, drop_i, (VALUE)args);
     return args[0];
 }
 
@@ -1958,7 +1957,7 @@
     RETURN_ENUMERATOR(obj, 0, 0);
     args[0] = rb_ary_new();
     args[1] = Qfalse;
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, drop_while_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, drop_while_i, (VALUE)args);
     return args[0];
 }
 
@@ -2012,7 +2011,7 @@
 #if !WITH_OBJC
     RBASIC(ary)->klass = 0;
 #endif
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, cycle_i, ary);
+    rb_objc_block_call(obj, selEach, 0, 0, cycle_i, ary);
     len = RARRAY_LEN(ary);
     if (len == 0) return Qnil;
     while (n < 0 || 0 < --n) {

Modified: MacRuby/trunk/enumerator.c
===================================================================
--- MacRuby/trunk/enumerator.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/enumerator.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -141,7 +141,7 @@
     args[0] = rb_ary_new2(size);
     args[1] = (VALUE)size;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, each_slice_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, each_slice_i, (VALUE)args);
 
     ary = args[0];
     if (RARRAY_LEN(ary) > 0) rb_yield(ary);
@@ -198,7 +198,7 @@
     args[0] = rb_ary_new2(size);
     args[1] = (VALUE)size;
 
-    rb_objc_block_call(obj, selEach, cacheEach, 0, 0, each_cons_i, (VALUE)args);
+    rb_objc_block_call(obj, selEach, 0, 0, each_cons_i, (VALUE)args);
 
     return Qnil;
 }
@@ -312,7 +312,7 @@
 	argc = RARRAY_LEN(e->args);
 	argv = RARRAY_PTR(e->args);
     }
-    return rb_objc_block_call(e->obj, e->sel, NULL, argc, (VALUE *)argv,
+    return rb_objc_block_call(e->obj, e->sel, argc, (VALUE *)argv,
 	    func, arg);
 }
 

Modified: MacRuby/trunk/error.c
===================================================================
--- MacRuby/trunk/error.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/error.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -595,8 +595,7 @@
  * Create a new +SystemExit+ exception with the given status.
  */
 
-/* XXX not a static/local symbol because of the super call that calls dladdr */
-VALUE
+static VALUE
 exit_initialize(VALUE exc, SEL sel, int argc, VALUE *argv)
 {
     VALUE status = INT2FIX(EXIT_SUCCESS);
@@ -604,11 +603,10 @@
 	status = *argv++;
 	--argc;
     }
-    //rb_call_super(argc, argv);
     if (sel == 0) {
 	sel = argc == 0 ? selInitialize : selInitialize2;
     }
-    rb_vm_call(exc, sel, argc, argv, true);
+    rb_vm_call_super(exc, sel, argc, argv);
     rb_iv_set(exc, "status", status);
     return exc;
 }
@@ -670,18 +668,16 @@
  * method.
  */
 
-/* XXX not a static/local symbol because of the super call that calls dladdr */
-VALUE
+static VALUE
 name_err_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
 {
     VALUE name;
 
     name = (argc > 1) ? argv[--argc] : Qnil;
-    //rb_call_super(argc, argv);
     if (sel == 0) {
 	sel = argc == 0 ? selInitialize : selInitialize2;
     }
-    rb_vm_call(self, sel, argc, argv, true);
+    rb_vm_call_super(self, sel, argc, argv);
     rb_iv_set(self, "name", name);
     return self;
 }
@@ -733,8 +729,7 @@
  * arguments using the <code>#args</code> method.
  */
 
-/* XXX not a static/local symbol because of the super call that calls dladdr */
-VALUE
+static VALUE
 nometh_err_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
 {
     VALUE args = (argc > 2) ? argv[--argc] : Qnil;
@@ -742,7 +737,7 @@
     if (sel == 0) {
 	sel = argc == 0 ? selInitialize : selInitialize2;
     }
-    rb_vm_call(self, sel, argc, argv, true);
+    rb_vm_call_super(self, sel, argc, argv);
     rb_iv_set(self, "args", args);
     return self;
 }
@@ -933,8 +928,7 @@
  * method.
  */
 
-/* XXX not a static/local symbol because of the super call that calls dladdr */
-VALUE
+static VALUE
 syserr_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
 {
 #if !defined(_WIN32) && !defined(__VMS)
@@ -973,8 +967,7 @@
     else {
 	mesg = rb_str_new2(err);
     }
-    //rb_call_super(1, &mesg);
-    rb_vm_call(self, selInitialize2, 1, &mesg, true);
+    rb_vm_call_super(self, selInitialize2, 1, &mesg);
     rb_iv_set(self, "errno", error);
     return self;
 }
@@ -1224,10 +1217,8 @@
 VALUE
 rb_format_exception_message(VALUE exc)
 {
-    VALUE message = rb_vm_call(exc, sel_registerName("message"), 0, NULL,
-	    false);
-    VALUE bt = rb_vm_call(exc, sel_registerName("backtrace"), 0, NULL,
-	    false);
+    VALUE message = rb_vm_call(exc, sel_registerName("message"), 0, NULL);
+    VALUE bt = rb_vm_call(exc, sel_registerName("backtrace"), 0, NULL);
 
     CFMutableStringRef result = CFStringCreateMutable(NULL, 0);
 

Modified: MacRuby/trunk/exported_symbols_list
===================================================================
--- MacRuby/trunk/exported_symbols_list	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/exported_symbols_list	2010-06-01 09:27:08 UTC (rev 4181)
@@ -8,7 +8,7 @@
 
 # used by the kernel:
 _rary_reserve
-_rhash_call_default
+_rhash_aref
 _rhash_aset
 _rstr_concat
 _selPLUS

Modified: MacRuby/trunk/ext/libyaml/rubyext.c
===================================================================
--- MacRuby/trunk/ext/libyaml/rubyext.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/ext/libyaml/rubyext.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -63,10 +63,6 @@
 
 static VALUE rb_oDefaultResolver;
 
-static struct mcache *to_yaml_cache = NULL;
-static struct mcache *call_cache = NULL;
-static struct mcache *yaml_new_cache = NULL;
-
 static const int DEFAULT_STACK_SIZE = 8;
 
 static VALUE
@@ -278,12 +274,10 @@
 	return result;
     }
     if (rb_vm_respond_to(handler, sel_call, 0)) {
-	return rb_vm_call_with_cache(call_cache, handler, sel_call, 1,
-		&result);
+	return rb_vm_call(handler, sel_call, 1, &result);
     }
     else if (rb_vm_respond_to(handler, sel_yaml_new, 0)) {
-	return rb_vm_call_with_cache(yaml_new_cache, handler, sel_yaml_new,
-		1, &result);
+	return rb_vm_call(handler, sel_yaml_new, 1, &result);
     }
     return result;
 }
@@ -957,9 +951,9 @@
 {
     VALUE first = Qnil, second = Qnil;
     rb_scan_args(argc, argv, "11", &first, &second);
-    rb_vm_call_with_cache(to_yaml_cache, first, sel_to_yaml, 1, &self);
+    rb_vm_call(first, sel_to_yaml, 1, &self);
     if (argc == 2) {
-	rb_vm_call_with_cache(to_yaml_cache, second, sel_to_yaml, 1, &self);
+	rb_vm_call(second, sel_to_yaml, 1, &self);
     }
     return self;
 }
@@ -1019,10 +1013,6 @@
     sel_call = sel_registerName("call:");
     sel_yaml_new = sel_registerName("yaml_new:");
 
-    to_yaml_cache = rb_vm_get_call_cache(sel_to_yaml);
-    call_cache = rb_vm_get_call_cache(sel_call);
-    yaml_new_cache = rb_vm_get_call_cache(sel_yaml_new);
-
     rb_mYAML = rb_define_module("YAML");
 
     rb_mLibYAML = rb_define_module_under(rb_mYAML, "LibYAML");
@@ -1057,7 +1047,7 @@
     //rb_objc_define_method(rb_cResolver, "add_ruby_type", rb_yaml_resolver_add_ruby_type, 1);
     //rb_objc_define_method(rb_cResolver, "add_builtin_type", rb_yaml_resolver_add_builtin_type, 1);
     //rb_objc_define_method(rb_cResolver, "add_private_type", rb_yaml_resolver_add_private_type, 1);
-    rb_oDefaultResolver = rb_vm_call(rb_cResolver, sel_registerName("new"), 0, NULL, false);
+    rb_oDefaultResolver = rb_vm_call(rb_cResolver, sel_registerName("new"), 0, NULL);
     rb_define_const(rb_mLibYAML, "DEFAULT_RESOLVER", rb_oDefaultResolver);
 
     rb_cEmitter = rb_define_class_under(rb_mLibYAML, "Emitter", rb_cObject);

Modified: MacRuby/trunk/ext/openssl/ossl_ssl.c
===================================================================
--- MacRuby/trunk/ext/openssl/ossl_ssl.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/ext/openssl/ossl_ssl.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -964,8 +964,7 @@
     ossl_ssl_set_sync_close(self, Qfalse);
     ossl_sslctx_setup(ctx);
 
-    //rb_call_super(0, 0);
-    rb_vm_call(self, sel, 0, NULL, true);
+    rb_vm_call_super(self, sel, 0, NULL);
 
     return self;
 }

Modified: MacRuby/trunk/file.c
===================================================================
--- MacRuby/trunk/file.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/file.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -106,7 +106,7 @@
     }
 
     if (rb_vm_respond_to(obj, selToPath, true)) {
-	tmp = rb_vm_call(obj, selToPath, 0, NULL, false);
+	tmp = rb_vm_call(obj, selToPath, 0, NULL);
     }
     else {
 	tmp = rb_check_string_type(obj);

Modified: MacRuby/trunk/hash.c
===================================================================
--- MacRuby/trunk/hash.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/hash.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -32,8 +32,6 @@
 
 static ID id_yield;
 
-static void *defaultCache = NULL;
-static void *hashCache = NULL;
 static SEL selFlattenBang = 0;
 static SEL selDefault = 0;
 static SEL selHash = 0;
@@ -41,7 +39,7 @@
 VALUE
 rb_hash(VALUE obj)
 {
-    VALUE v = rb_vm_call_with_cache(hashCache, obj, selHash, 0, NULL);
+    VALUE v = rb_vm_call(obj, selHash, 0, NULL);
 retry:
     switch (TYPE(v)) {
 	case T_FIXNUM:
@@ -428,10 +426,10 @@
  *
  */
 
-VALUE
+static inline VALUE
 rhash_call_default(VALUE hash, VALUE key)
 {
-    return rb_vm_call_with_cache(defaultCache, hash, selDefault, 1, &key);
+    return rb_vm_call(hash, selDefault, 1, &key);
 }
 
 VALUE
@@ -1617,7 +1615,7 @@
 	tmp = INT2FIX(1);
 	argv = &tmp;
     }
-    rb_vm_call(ary, selFlattenBang, argc, argv, false);
+    rb_vm_call(ary, selFlattenBang, argc, argv);
     return ary;
 }
 
@@ -1773,8 +1771,6 @@
     selFlattenBang = sel_registerName("flatten!:");
     selDefault = sel_registerName("default:");
     selHash = sel_registerName("hash");
-    defaultCache = rb_vm_get_call_cache(selDefault);
-    hashCache = rb_vm_get_call_cache(selHash);
 
     id_yield = rb_intern("yield");
 

Modified: MacRuby/trunk/hash.h
===================================================================
--- MacRuby/trunk/hash.h	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/hash.h	2010-06-01 09:27:08 UTC (rev 4181)
@@ -101,7 +101,6 @@
 VALUE rhash_aset(VALUE hash, SEL sel, VALUE key, VALUE val);
 VALUE rhash_keys(VALUE hash, SEL sel);
 VALUE rhash_has_key(VALUE hash, SEL sel, VALUE key);
-VALUE rhash_call_default(VALUE hash, VALUE key);
 VALUE rhash_set_default(VALUE hash, SEL sel, VALUE ifnone);
 
 #if defined(__cplusplus)

Modified: MacRuby/trunk/id.c
===================================================================
--- MacRuby/trunk/id.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/id.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -106,8 +106,6 @@
     selLambda = sel_registerName("lambda");
     selObjectForKey = sel_registerName("objectForKey:");
     selSetObjectForKey = sel_registerName("setObject:forKey:");
-
-    cacheEach = rb_vm_get_call_cache(selEach);
 #endif
 
     idAREF = rb_intern("[]");

Modified: MacRuby/trunk/id.h
===================================================================
--- MacRuby/trunk/id.h	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/id.h	2010-06-01 09:27:08 UTC (rev 4181)
@@ -119,6 +119,5 @@
 extern ID idIncludedModules;
 extern ID idIncludedInClasses;
 extern ID idAncestors;
-extern void *cacheEach;
 #endif
 #endif /* RUBY_ID_H */

Modified: MacRuby/trunk/include/ruby/ruby.h
===================================================================
--- MacRuby/trunk/include/ruby/ruby.h	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/include/ruby/ruby.h	2010-06-01 09:27:08 UTC (rev 4181)
@@ -802,8 +802,8 @@
 VALUE rb_funcall2(VALUE, ID, int, const VALUE*);
 VALUE rb_funcall3(VALUE, ID, int, const VALUE*);
 int rb_scan_args(int, const VALUE*, const char*, ...);
-VALUE rb_call_super(int, const VALUE*);
-VALUE rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *args, bool super);
+VALUE rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *args);
+VALUE rb_vm_call_super(VALUE self, SEL sel, int argc, const VALUE *args);
 
 VALUE rb_gv_set(const char*, VALUE);
 VALUE rb_gv_get(const char*);
@@ -868,7 +868,7 @@
 void rb_need_block(void);
 VALUE rb_iterate(VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE);
 VALUE rb_block_call(VALUE,ID,int,VALUE*,VALUE(*)(ANYARGS),VALUE);
-VALUE rb_objc_block_call(VALUE obj, SEL sel, void *cache, int argc,
+VALUE rb_objc_block_call(VALUE obj, SEL sel, int argc,
 	VALUE *argv, VALUE (*bl_proc) (ANYARGS), VALUE data2);
 VALUE rb_rescue(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE);
 VALUE rb_rescue2(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...);

Modified: MacRuby/trunk/io.c
===================================================================
--- MacRuby/trunk/io.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/io.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -415,7 +415,7 @@
     VALUE tmp = rb_io_check_io(io);
     if (NIL_P(tmp)) {
 	// receiver is not IO, dispatch the write method on it
-	return rb_vm_call(io, selWrite, 1, &data, false);
+	return rb_vm_call(io, selWrite, 1, &data);
     }
     io = tmp;
     

Modified: MacRuby/trunk/kernel.c
===================================================================
--- MacRuby/trunk/kernel.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/kernel.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -166,8 +166,8 @@
     rb_const_set(outer, id, obj);
 }
 
-VALUE rb_vm_dispatch(void *cache, VALUE top, VALUE self, void *sel,
-	void *block, unsigned char opt, int argc, ...);
+VALUE rb_vm_dispatch(VALUE top, VALUE self, void *sel, void *block,
+	unsigned char opt, int argc, ...);
 
 // Only numeric immediates have their lsb at 1.
 #define NUMERIC_IMM_P(x) ((x & 0x1) == 0x1)
@@ -175,7 +175,7 @@
 #define IMM2DBL(x) (FIXFLOAT_P(x) ? FIXFLOAT2DBL(x) : FIX2LONG(x))
 
 inline VALUE
-vm_fast_plus(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_plus(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -189,11 +189,11 @@
 	    return DBL2FIXFLOAT(res);
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selPLUS, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selPLUS, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_minus(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_minus(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -207,11 +207,11 @@
 	    return DBL2FIXFLOAT(res);
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selMINUS, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selMINUS, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_mult(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_mult(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -225,11 +225,11 @@
 	    return DBL2FIXFLOAT(res);
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selMULT, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selMULT, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_div(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_div(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -251,11 +251,11 @@
 	    return DBL2FIXFLOAT(res);
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selDIV, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selDIV, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_lt(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_lt(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -265,11 +265,11 @@
 	    return IMM2DBL(left) < IMM2DBL(right) ? Qtrue : Qfalse;
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selLT, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selLT, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_le(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_le(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -279,11 +279,11 @@
 	    return IMM2DBL(left) <= IMM2DBL(right) ? Qtrue : Qfalse;
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selLE, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selLE, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_gt(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_gt(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -293,11 +293,11 @@
 	    return IMM2DBL(left) > IMM2DBL(right) ? Qtrue : Qfalse;
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selGT, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selGT, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_ge(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_ge(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
 	if (FIXNUM_P(left) && FIXNUM_P(right)) {
@@ -307,11 +307,11 @@
 	    return IMM2DBL(left) >= IMM2DBL(right) ? Qtrue : Qfalse;
 	}
     }
-    return rb_vm_dispatch(cache, 0, left, selGE, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selGE, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_eq(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_eq(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0) {
 	if (NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
@@ -327,11 +327,11 @@
 	}
 	// TODO: opt for non-immediate types
     }
-    return rb_vm_dispatch(cache, 0, left, selEq, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selEq, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_eqq(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_eqq(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0) {
 	if (NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
@@ -347,11 +347,11 @@
 	}
 	// TODO: opt for non-immediate types
     }
-    return rb_vm_dispatch(cache, 0, left, selEqq, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selEqq, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_neq(void *cache, VALUE left, VALUE right, unsigned char overriden)
+vm_fast_neq(VALUE left, VALUE right, unsigned char overriden)
 {
     if (overriden == 0) {
 	if (NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
@@ -367,11 +367,11 @@
 	}
 	// TODO: opt for non-immediate types
     }
-    return rb_vm_dispatch(cache, 0, left, selNeq, NULL, 0, 1, right);
+    return rb_vm_dispatch(0, left, selNeq, NULL, 0, 1, right);
 }
 
 inline VALUE
-vm_fast_aref(VALUE obj, VALUE other, void *cache, unsigned char overriden)
+vm_fast_aref(VALUE obj, VALUE other, unsigned char overriden)
 {
     if (overriden == 0 && !SPECIAL_CONST_P(obj)) {
 	VALUE klass = *(VALUE *)obj;
@@ -381,22 +381,14 @@
 	    }
 	}
 	else if (klass == rb_cRubyHash) {
-	    VALUE val = rhash_lookup(obj, other);
-	    if (val == Qundef) {
-		if (RHASH(obj)->ifnone == Qnil) {
-		    return Qnil;
-		}
-		return rhash_call_default(obj, other);
-	    }
-	    return val;
+	    return rhash_aref(obj, 0, other);
 	}
     }
-    return rb_vm_dispatch(cache, 0, obj, selAREF, NULL, 0, 1, other);
+    return rb_vm_dispatch(0, obj, selAREF, NULL, 0, 1, other);
 }
 
 inline VALUE
-vm_fast_aset(VALUE obj, VALUE other1, VALUE other2, void *cache,
-	unsigned char overriden)
+vm_fast_aset(VALUE obj, VALUE other1, VALUE other2, unsigned char overriden)
 {
     if (overriden == 0 && !SPECIAL_CONST_P(obj)) {
 	VALUE klass = *(VALUE *)obj;
@@ -410,11 +402,11 @@
 	    return rhash_aset(obj, 0, other1, other2);
 	}
     }
-    return rb_vm_dispatch(cache, 0, obj, selASET, NULL, 0, 2, other1, other2);
+    return rb_vm_dispatch(0, obj, selASET, NULL, 0, 2, other1, other2);
 }
 
 inline VALUE
-vm_fast_shift(VALUE obj, VALUE other, void *cache, unsigned char overriden)
+vm_fast_shift(VALUE obj, VALUE other, unsigned char overriden)
 {
     if (overriden == 0 && !SPECIAL_CONST_P(obj)) {
 	VALUE klass = *(VALUE *)obj;
@@ -427,12 +419,11 @@
 	    return rstr_concat(obj, 0, other);
 	}
     }
-    return rb_vm_dispatch(cache, 0, obj, selLTLT, NULL, 0, 1, other);
+    return rb_vm_dispatch(0, obj, selLTLT, NULL, 0, 1, other);
 }
 
 inline VALUE
-vm_when_splat(void *cache, unsigned char overriden,
-	VALUE comparedTo, VALUE splat)
+vm_when_splat(unsigned char overriden, VALUE comparedTo, VALUE splat)
 {
     VALUE ary = rb_check_convert_type(splat, T_ARRAY, "Array", "to_a");
     if (NIL_P(ary)) {
@@ -441,7 +432,7 @@
     long i, count = RARRAY_LEN(ary);
     for (i = 0; i < count; i++) {
 	VALUE o = RARRAY_AT(ary, i);
-	if (RTEST(vm_fast_eqq(cache, o, comparedTo, overriden))) {
+	if (RTEST(vm_fast_eqq(o, comparedTo, overriden))) {
 	    return Qtrue;
 	}
     }

Modified: MacRuby/trunk/numeric.c
===================================================================
--- MacRuby/trunk/numeric.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/numeric.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -142,7 +142,7 @@
 static VALUE
 coerce_body(VALUE *x)
 {
-    return rb_vm_call(x[1], sel_coerce, 1, &x[0], false);
+    return rb_vm_call(x[1], sel_coerce, 1, &x[0]);
 }
 
 static VALUE
@@ -190,7 +190,7 @@
 rb_objc_num_coerce_bin(VALUE x, VALUE y, SEL sel)
 {
     do_coerce(&x, &y, Qtrue);
-    return rb_vm_call(x, sel, 1, &y, false);
+    return rb_vm_call(x, sel, 1, &y);
 }
 
 VALUE
@@ -206,7 +206,7 @@
 rb_objc_num_coerce_cmp(VALUE x, VALUE y, SEL sel)
 {
     if (do_coerce(&x, &y, Qfalse)) {
-	return rb_vm_call(x, sel, 1, &y, false);
+	return rb_vm_call(x, sel, 1, &y);
     }
     return Qnil;
 }
@@ -217,7 +217,7 @@
     VALUE c, x0 = x, y0 = y;
 
     if (!do_coerce(&x, &y, Qfalse) ||
-	NIL_P(c = rb_vm_call(x, sel, 1, &y, false))) {
+	NIL_P(c = rb_vm_call(x, sel, 1, &y))) {
 	rb_cmperr(x0, y0);
 	return Qnil;		/* not reached */
     }
@@ -292,7 +292,7 @@
     zero = INT2FIX(0);
     do_coerce(&zero, &num, Qtrue);
 
-    return rb_vm_call(zero, selMINUS, 1, &num, false);
+    return rb_vm_call(zero, selMINUS, 1, &num);
 }
 
 /*
@@ -305,7 +305,7 @@
 static VALUE
 num_quo(VALUE x, SEL sel, VALUE y)
 {
-    return rb_vm_call(rb_rational_raw1(x), selDIV, 1, &y, false);
+    return rb_vm_call(rb_rational_raw1(x), selDIV, 1, &y);
 }
 
 
@@ -319,7 +319,7 @@
 static VALUE
 num_fdiv(VALUE x, SEL sel, VALUE y)
 {
-    return rb_vm_call(rb_Float(x), selDIV, 1, &y, false);
+    return rb_vm_call(rb_Float(x), selDIV, 1, &y);
 }
 
 
@@ -340,7 +340,7 @@
     if (rb_equal(INT2FIX(0), y)) {
 	rb_num_zerodiv();
     }
-    return num_floor(rb_vm_call(x, selDIV, 1, &y, false), 0);
+    return num_floor(rb_vm_call(x, selDIV, 1, &y), 0);
 }
 
 
@@ -388,7 +388,7 @@
 static VALUE
 num_divmod(VALUE x, SEL sel, VALUE y)
 {
-    return rb_assoc_new(num_div(x, 0, y), rb_vm_call(x, selMOD, 1, &y, false));
+    return rb_assoc_new(num_div(x, 0, y), rb_vm_call(x, selMOD, 1, &y));
 }
 
 /*
@@ -402,9 +402,9 @@
 static VALUE
 num_modulo(VALUE x, SEL sel, VALUE y)
 {
-    VALUE tmp1 = rb_vm_call(x, selDiv, 1, &y, false);
-    VALUE tmp2 = rb_vm_call(y, selMULT, 1, &tmp1, false);
-    return rb_vm_call(x, selMINUS, 1, &tmp2, false);
+    VALUE tmp1 = rb_vm_call(x, selDiv, 1, &y);
+    VALUE tmp2 = rb_vm_call(y, selMULT, 1, &tmp1);
+    return rb_vm_call(x, selMINUS, 1, &tmp2);
 }
 
 /*
@@ -422,15 +422,15 @@
 static VALUE
 num_remainder(VALUE x, SEL sel, VALUE y)
 {
-    VALUE z = rb_vm_call(x, selMOD, 1, &y, false);
+    VALUE z = rb_vm_call(x, selMOD, 1, &y);
 
     VALUE zero = INT2FIX(0);
     if ((!rb_equal(z, INT2FIX(0))) &&
-	((RTEST(rb_vm_call(x, selLT, 1, &zero, false)) &&
-	  RTEST(rb_vm_call(y, selGT, 1, &zero, false))) ||
-	 (RTEST(rb_vm_call(x, selGT, 1, &zero, false)) &&
-	  RTEST(rb_vm_call(y, selLT, 1, &zero, false))))) {
-	return rb_vm_call(z, selMINUS, 1, &y, false);
+	((RTEST(rb_vm_call(x, selLT, 1, &zero)) &&
+	  RTEST(rb_vm_call(y, selGT, 1, &zero))) ||
+	 (RTEST(rb_vm_call(x, selGT, 1, &zero)) &&
+	  RTEST(rb_vm_call(y, selLT, 1, &zero))))) {
+	return rb_vm_call(z, selMINUS, 1, &y);
     }
     return z;
 }
@@ -492,7 +492,7 @@
 num_abs(VALUE num, SEL sel)
 {
     VALUE zero = INT2FIX(0);
-    if (RTEST(rb_vm_call(num, selLT, 1, &zero, false))) {
+    if (RTEST(rb_vm_call(num, selLT, 1, &zero))) {
 	return rb_funcall(num, rb_intern("-@"), 0);
     }
     return num;
@@ -752,7 +752,7 @@
 static VALUE
 flo_quo(VALUE x, SEL sel, VALUE y)
 {
-    return rb_vm_call(x, selDIV, 1, &y, false);
+    return rb_vm_call(x, selDIV, 1, &y);
 }
 
 static void
@@ -1608,19 +1608,19 @@
 	SEL cmp;
 
 	VALUE zero = INT2FIX(0);
-	if (RTEST(rb_vm_call(step, selGT, 1, &zero, false))) {
+	if (RTEST(rb_vm_call(step, selGT, 1, &zero))) {
 	    cmp = selGT;
 	}
 	else {
 	    cmp = selLT;
 	}
 	for (;;) {
-	    if (RTEST(rb_vm_call(i, cmp, 1, &to, false))) {
+	    if (RTEST(rb_vm_call(i, cmp, 1, &to))) {
 		break;
 	    }
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
-	    i = rb_vm_call(i, selPLUS, 1, &step, false);
+	    i = rb_vm_call(i, selPLUS, 1, &step);
 	}
     }
     return from;
@@ -1718,7 +1718,7 @@
 {
     unsigned long num = rb_num2ulong(val);
 
-    if (RTEST(rb_vm_call(INT2FIX(0), selLT, 1, &val, false))) {
+    if (RTEST(rb_vm_call(INT2FIX(0), selLT, 1, &val))) {
 	check_uint(num);
     }
     return num;
@@ -1884,7 +1884,7 @@
 int_odd_p(VALUE num, SEL sel)
 {
     VALUE two = INT2FIX(2);
-    if (rb_vm_call(num, selMOD, 1, &two, false) != INT2FIX(0)) {
+    if (rb_vm_call(num, selMOD, 1, &two) != INT2FIX(0)) {
 	return Qtrue;
     }
     return Qfalse;
@@ -1940,7 +1940,7 @@
 	return LONG2NUM(i);
     }
     VALUE one = INT2FIX(1);
-    return rb_vm_call(num, selPLUS, 1, &one, false);
+    return rb_vm_call(num, selPLUS, 1, &one);
 }
 
 /*
@@ -1961,7 +1961,7 @@
 	return LONG2NUM(i);
     }
     VALUE one = INT2FIX(1);
-    return rb_vm_call(num, selMINUS, 1, &one, false);
+    return rb_vm_call(num, selMINUS, 1, &one);
 }
 
 /*
@@ -2640,7 +2640,7 @@
 	long b = FIX2LONG(y);
 
 	if (b < 0) {
-	  return rb_vm_call(rb_rational_raw1(x), selExp, 1, &y, false);
+	  return rb_vm_call(rb_rational_raw1(x), selExp, 1, &y);
 	}
 
 	if (b == 0) {
@@ -2671,8 +2671,8 @@
     VALUE zerov = INT2FIX(0);
     switch (TYPE(y)) {
       case T_BIGNUM:
-	  if (rb_vm_call(y, selLT, 1, &zerov, false)) {
-	      return rb_vm_call(rb_rational_raw1(x), selExp, 1, &y, false);
+	  if (rb_vm_call(y, selLT, 1, &zerov)) {
+	      return rb_vm_call(rb_rational_raw1(x), selExp, 1, &y);
 	  }
 	  if (a == 0) {
 	      return INT2FIX(0);
@@ -3144,11 +3144,11 @@
     else {
 	VALUE i = from, c;
 
-	while (!(c = rb_vm_call(i, selGT, 1, &to, false))) {
+	while (!(c = rb_vm_call(i, selGT, 1, &to))) {
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
 	    VALUE one = INT2FIX(1);
-	    i = rb_vm_call(i, selPLUS, 1, &one, false);
+	    i = rb_vm_call(i, selPLUS, 1, &one);
 	}
 	if (NIL_P(c)) rb_cmperr(i, to);
     }
@@ -3186,11 +3186,11 @@
     else {
 	VALUE i = from, c;
 
-	while (!(c = rb_vm_call(i, selLT, 1, &to, false))) {
+	while (!(c = rb_vm_call(i, selLT, 1, &to))) {
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
 	    VALUE one = INT2FIX(1);
-	    i = rb_vm_call(i, selMINUS, 1, &one, false);
+	    i = rb_vm_call(i, selMINUS, 1, &one);
 	}
 	if (NIL_P(c)) rb_cmperr(i, to);
     }
@@ -3231,13 +3231,13 @@
 	VALUE i = INT2FIX(0);
 
 	for (;;) {
-	    if (!RTEST(rb_vm_call(i, selLT, 1, &num, false))) {
+	    if (!RTEST(rb_vm_call(i, selLT, 1, &num))) {
 		break;
 	    }
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
 	    VALUE one = INT2FIX(1);
-	    i = rb_vm_call(i, selPLUS, 1, &one, false);
+	    i = rb_vm_call(i, selPLUS, 1, &one);
 	}
     }
     return num;
@@ -3272,11 +3272,11 @@
 	return LONG2NUM(x);
     }
     VALUE two = INT2FIX(2);
-    h = rb_vm_call(f, selDIV, 1, &two, false);
-    r = rb_vm_call(num, selMOD, 1, &f, false);
-    n = rb_vm_call(num, selMINUS, 1, &r, false);
-    if (!RTEST(rb_vm_call(r, selLT, 1, &h, false))) {
-	n = rb_vm_call(n, selPLUS, 1, &f, false);
+    h = rb_vm_call(f, selDIV, 1, &two);
+    r = rb_vm_call(num, selMOD, 1, &f);
+    n = rb_vm_call(num, selMINUS, 1, &r);
+    if (!RTEST(rb_vm_call(r, selLT, 1, &h))) {
+	n = rb_vm_call(n, selPLUS, 1, &f);
     }
     return n;
 }

Modified: MacRuby/trunk/object.c
===================================================================
--- MacRuby/trunk/object.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/object.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -42,18 +42,11 @@
 static ID id_eq, id_match, id_inspect, id_init_copy;
 
 static SEL eqlSel = 0;
-static void *eqlCache = NULL;
 
-static void *allocCache = NULL;
-static void *initializeCache = NULL;
-static void *initialize2Cache = NULL;
-static void *eqCache = NULL;
-static void *dupCache = NULL;
-
-inline VALUE
+VALUE
 rb_send_dup(VALUE obj)
 {
-    return rb_vm_call_with_cache(dupCache, obj, selDup, 0, NULL);
+    return rb_vm_call(obj, selDup, 0, NULL);
 }
 
 /*
@@ -71,7 +64,7 @@
     if (obj1 == obj2) {
 	return Qtrue;
     }
-    VALUE result = rb_vm_call_with_cache(eqCache, obj1, selEq, 1, &obj2);
+    VALUE result = rb_vm_call(obj1, selEq, 1, &obj2);
     if (RTEST(result)) {
 	return Qtrue;
     }
@@ -87,7 +80,7 @@
 int
 rb_eql(VALUE obj1, VALUE obj2)
 {
-    return RTEST(rb_vm_call_with_cache(eqlCache, obj1, eqlSel, 1, &obj2));
+    return RTEST(rb_vm_call(obj1, eqlSel, 1, &obj2));
 }
 
 /*
@@ -154,7 +147,7 @@
 static VALUE
 rb_obj_not_equal(VALUE obj1, SEL sel, VALUE obj2)
 {
-    VALUE result = rb_vm_call_with_cache(eqCache, obj1, selEq, 1, &obj2);
+    VALUE result = rb_vm_call(obj1, selEq, 1, &obj2);
     return RTEST(result) ? Qfalse : Qtrue;
 }
 
@@ -232,7 +225,7 @@
         break;
     }
 call_init_copy:
-    rb_vm_call(dest, selInitializeCopy, 1, &obj, false);
+    rb_vm_call(dest, selInitializeCopy, 1, &obj);
 }
 
 /*
@@ -1896,7 +1889,7 @@
 	// Fast path!
 	return rb_vm_new_rb_object(klass);
     }
-    return rb_vm_call_with_cache(allocCache, klass, selAlloc, 0, NULL);
+    return rb_vm_call(klass, selAlloc, 0, NULL);
 }
 
 VALUE
@@ -1937,12 +1930,10 @@
 
     rb_vm_block_t *block = rb_vm_current_block();
     if (argc == 0) {
-	rb_vm_call_with_cache2(initializeCache, block, obj, CLASS_OF(obj),
-		selInitialize, argc, argv);
+	rb_vm_call2(block, obj, CLASS_OF(obj), selInitialize, argc, argv);
     }
     else {
-	rb_vm_call_with_cache2(initialize2Cache, block, obj, CLASS_OF(obj),
-		selInitialize2, argc, argv);
+	rb_vm_call2(block, obj, CLASS_OF(obj), selInitialize2, argc, argv);
     }
 
     return obj;
@@ -2427,8 +2418,7 @@
 	    return Qnil;
 	}
     }
-    //return rb_funcall(val, m, 0);
-    return rb_vm_call(val, sel, 0, NULL, false);
+    return rb_vm_call(val, sel, 0, NULL);
 }
 
 VALUE
@@ -2949,13 +2939,7 @@
     RCLASS_SET_VERSION_FLAG(rb_cRubyObject, RCLASS_IS_OBJECT_SUBCLASS);
     rb_define_object_special_methods(rb_cRubyObject);
 
-    allocCache = rb_vm_get_call_cache(selAlloc);
-    initializeCache = rb_vm_get_call_cache(selInitialize);
-    initialize2Cache = rb_vm_get_call_cache(selInitialize2);
-    eqCache = rb_vm_get_call_cache(selEq);
-    dupCache = rb_vm_get_call_cache(selDup);
     eqlSel = sel_registerName("eql?:");
-    eqlCache = rb_vm_get_call_cache(eqlSel);
 
     rb_objc_define_method(*(VALUE *)rb_cModule, "alloc", rb_module_s_alloc, 0);
     rb_objc_define_method(*(VALUE *)rb_cClass, "alloc", rb_class_s_alloc, 0);

Modified: MacRuby/trunk/proc.c
===================================================================
--- MacRuby/trunk/proc.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/proc.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -1059,8 +1059,7 @@
 	}
     }
 
-    VALUE result = rb_vm_call_with_cache2(data->cache, NULL, data->recv,
-	    data->oclass, data->sel, argc, argv);
+    VALUE result = rb_vm_call2(NULL, data->recv, data->oclass, data->sel, argc, argv);
 
     if (safe >= 0) {
 	rb_set_safe_level_force(safe);

Modified: MacRuby/trunk/process.c
===================================================================
--- MacRuby/trunk/process.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/process.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -1819,8 +1819,7 @@
         VALUE env = rb_const_get(rb_cObject, rb_intern("ENV"));
         if (RTEST(env)) {
             VALUE ary = hide_obj(rb_ary_new());
-            rb_objc_block_call(env, selEach, cacheEach, 0, 0, save_env_i,
-                          (VALUE)ary);
+            rb_objc_block_call(env, selEach, 0, 0, save_env_i, (VALUE)ary);
             rb_ary_store(save, EXEC_OPTION_ENV, ary);
         }
         rb_ary_store(save, EXEC_OPTION_UNSETENV_OTHERS, Qtrue);

Modified: MacRuby/trunk/random.c
===================================================================
--- MacRuby/trunk/random.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/random.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -583,7 +583,7 @@
     if (!rb_vm_respond_to(end, selMINUS, false)) {
 	return Qfalse;
     }
-    VALUE r = rb_vm_call(end, selMINUS, 1, begp, false);
+    VALUE r = rb_vm_call(end, selMINUS, 1, begp);
     if (NIL_P(r)) {
 	return Qfalse;
     }
@@ -758,7 +758,7 @@
 		return DOUBLE2NUM(d);
 	    }
 	default:
-	    return rb_vm_call(v, selPLUS, 1, &beg, false);
+	    return rb_vm_call(v, selPLUS, 1, &beg);
     }
 }
 

Modified: MacRuby/trunk/range.c
===================================================================
--- MacRuby/trunk/range.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/range.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -18,7 +18,6 @@
 
 VALUE rb_cRange;
 static SEL selUpto, selBeg, selEnd, selExcludeEnd, selInclude; 
-static void *cacheUpto = NULL;
 
 #define RANGE_BEG(r) (RSTRUCT(r)->as.ary[0])
 #define RANGE_END(r) (RSTRUCT(r)->as.ary[1])
@@ -258,7 +257,7 @@
     if (EXCL(range)) {
 	while (r_lt(v, e)) {
 	    (*func) (v, arg);
-	    v = rb_vm_call(v, selSucc, 0, NULL, false);
+	    v = rb_vm_call(v, selSucc, 0, NULL);
 	}
     }
     else {
@@ -266,7 +265,7 @@
 	    (*func) (v, arg);
 	    if (c == INT2FIX(0))
 		break;
-	    v = rb_vm_call(v, selSucc, 0, NULL, false);
+	    v = rb_vm_call(v, selSucc, 0, NULL);
 	}
     }
 }
@@ -281,7 +280,7 @@
     }
     else {
 	VALUE one = INT2FIX(1);
-	iter[0] = rb_vm_call(iter[0], selMINUS, 1, &one, false);
+	iter[0] = rb_vm_call(iter[0], selMINUS, 1, &one);
     }
     if (iter[0] == INT2FIX(0)) {
 	rb_yield(i);
@@ -300,7 +299,7 @@
     }
     else {
 	VALUE one = INT2FIX(1);
-	iter[0] = rb_vm_call(iter[0], selMINUS,1, &one, false);
+	iter[0] = rb_vm_call(iter[0], selMINUS,1, &one);
     }
     if (iter[0] == INT2FIX(0)) {
 	rb_yield(ID2SYM(rb_intern_str(i)));
@@ -355,10 +354,10 @@
 	    step = rb_to_int(step);
 	}
 	VALUE zero = INT2FIX(0);
-	if (rb_vm_call(step, selLT, 1, &zero, false)) {
+	if (rb_vm_call(step, selLT, 1, &zero)) {
 	    rb_raise(rb_eArgError, "step can't be negative");
 	}
-	else if (!rb_vm_call(step, selGT, 1, &zero, false)) {
+	else if (!rb_vm_call(step, selGT, 1, &zero)) {
 	    rb_raise(rb_eArgError, "step can't be 0");
 	}
     }
@@ -386,17 +385,17 @@
 	args[1] = EXCL(range) ? Qtrue : Qfalse;
 	iter[0] = INT2FIX(1);
 	iter[1] = step;
-	rb_objc_block_call(rb_sym_to_s(b), selUpto, cacheUpto, 2, args, sym_step_i, (VALUE)iter);
+	rb_objc_block_call(rb_sym_to_s(b), selUpto, 2, args, sym_step_i, (VALUE)iter);
     }
     else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
 	     !NIL_P(rb_check_to_integer(b, "to_int")) ||
 	     !NIL_P(rb_check_to_integer(e, "to_int"))) {
 	SEL op = EXCL(range) ? selLT : selLE;
 
-	while (RTEST(rb_vm_call(b, op, 1, &e, false))) {
+	while (RTEST(rb_vm_call(b, op, 1, &e))) {
 	    rb_yield(b);
 	    RETURN_IF_BROKEN();
-	    b = rb_vm_call(b, selPLUS, 1, &step, false);
+	    b = rb_vm_call(b, selPLUS, 1, &step);
 	}
     }
     else {
@@ -410,7 +409,7 @@
 	    args[1] = EXCL(range) ? Qtrue : Qfalse;
 	    iter[0] = INT2FIX(1);
 	    iter[1] = step;
-	    rb_objc_block_call(b, selUpto, cacheUpto, 2, args, step_i, (VALUE)iter);
+	    rb_objc_block_call(b, selUpto, 2, args, step_i, (VALUE)iter);
 	}
 	else {
 	    VALUE args[2];
@@ -489,14 +488,14 @@
 
 	args[0] = rb_sym_to_s(end);
 	args[1] = EXCL(range) ? Qtrue : Qfalse;
-	rb_objc_block_call(rb_sym_to_s(beg), selUpto, cacheUpto, 2, args, sym_each_i, 0);
+	rb_objc_block_call(rb_sym_to_s(beg), selUpto, 2, args, sym_each_i, 0);
     }
     else if (TYPE(beg) == T_STRING) {
 	VALUE args[2];
 
 	args[0] = end;
 	args[1] = EXCL(range) ? Qtrue : Qfalse;
-	rb_objc_block_call(beg, selUpto, cacheUpto, 2, args, rb_yield, 0);
+	rb_objc_block_call(beg, selUpto, 2, args, rb_yield, 0);
     }
     else {
 	range_each_func(range, each_i, NULL);
@@ -568,7 +567,7 @@
     rb_scan_args(argc, argv, "1", &n);
     ary[0] = n;
     ary[1] = rb_ary_new2(NUM2LONG(n));
-    rb_objc_block_call(range, selEach, cacheEach, 0, 0, first_i, (VALUE)ary);
+    rb_objc_block_call(range, selEach, 0, 0, first_i, (VALUE)ary);
 
     return ary[1];
 }
@@ -608,11 +607,10 @@
 range_min(VALUE range, SEL sel)
 {
     if (rb_block_given_p()) {
-	//return rb_call_super(0, 0);
 	if (sel == NULL) {
 	    sel = sel_registerName("min");
 	}
-	return rb_vm_call(range, sel, 0, NULL, true);
+	return rb_vm_call_super(range, sel, 0, NULL);
     }
     else {
 	VALUE b = RANGE_BEG(range);
@@ -644,11 +642,10 @@
     int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);
 
     if (rb_block_given_p() || (EXCL(range) && !nm)) {
-	//return rb_call_super(0, 0);
 	if (sel == NULL) {
 	    sel = sel_registerName("max");
 	}
-	return rb_vm_call(range, sel, 0, NULL, true);
+	return rb_vm_call_super(range, sel, 0, NULL);
     }
     else {
 	VALUE b = RANGE_BEG(range);
@@ -667,7 +664,7 @@
 		return LONG2NUM(FIX2LONG(e) - 1);
 	    }
 	    VALUE one = INT2FIX(1);
-	    return rb_vm_call(e, selMINUS, 1, &one, false);
+	    return rb_vm_call(e, selMINUS, 1, &one);
 	}
 	return e;
     }
@@ -700,9 +697,9 @@
 	if (!rb_vm_respond_to(range, selEnd, false)) {
 	    return Qfalse;
 	}
-	b = rb_vm_call(range, selBeg, 0, NULL, false);
-	e = rb_vm_call(range, selEnd, 0, NULL, false);
-	excl = RTEST(rb_vm_call(range, selExcludeEnd, 0, NULL, false));
+	b = rb_vm_call(range, selBeg, 0, NULL);
+	e = rb_vm_call(range, selEnd, 0, NULL);
+	excl = RTEST(rb_vm_call(range, selExcludeEnd, 0, NULL));
     }
     *begp = b;
     *endp = e;
@@ -728,9 +725,9 @@
 	if (!rb_vm_respond_to(range, selEnd, false)) {
 	    return Qfalse;
 	}
-	b = rb_vm_call(range, selBeg, 0, NULL, false);
-	e = rb_vm_call(range, selEnd, 0, NULL, false);
-	excl = RTEST(rb_vm_call(range, selExcludeEnd, 0, NULL, false));
+	b = rb_vm_call(range, selBeg, 0, NULL);
+	e = rb_vm_call(range, selEnd, 0, NULL);
+	excl = RTEST(rb_vm_call(range, selExcludeEnd, 0, NULL));
     }
     beg = NUM2LONG(b);
     end = NUM2LONG(e);
@@ -836,7 +833,7 @@
 static VALUE
 range_eqq(VALUE range, SEL sel, VALUE val)
 {
-    return rb_vm_call(range, selInclude, 1, &val, false);
+    return rb_vm_call(range, selInclude, 1, &val);
 }
 
 /*
@@ -895,12 +892,10 @@
 	    }
 	}
     }
-    /* TODO: ruby_frame->this_func = rb_intern("include?"); */
-    //return rb_call_super(1, &val);
     if (sel == NULL) {
 	sel = sel_registerName("include?:");
     }
-    return rb_vm_call(range, sel, 1, &val, true);
+    return rb_vm_call_super(range, sel, 1, &val);
 }
 
 
@@ -1058,7 +1053,6 @@
     rb_objc_define_method(rb_cRange, "cover?", range_cover, 1);
 
     selUpto = sel_registerName("upto:");
-    cacheUpto = rb_vm_get_call_cache(selUpto);
     selBeg = sel_registerName("begin");
     selEnd = sel_registerName("end");
     selExcludeEnd = sel_registerName("exclude_end?");

Modified: MacRuby/trunk/rational.c
===================================================================
--- MacRuby/trunk/rational.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/rational.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -1753,11 +1753,10 @@
 float_numerator(VALUE self, SEL sel)
 {
     double d = RFLOAT_VALUE(self);
-    if (isinf(d) || isnan(d))
+    if (isinf(d) || isnan(d)) {
 	return self;
-    return rb_vm_call(self, sel, 0, 0, true);
-//    return ZERO;
-//    return rb_call_super(0, 0);
+    }
+    return rb_vm_call_super(self, sel, 0, 0);
 }
 
 /*
@@ -1773,9 +1772,10 @@
 float_denominator(VALUE self, SEL sel)
 {
     double d = RFLOAT_VALUE(self);
-    if (isinf(d) || isnan(d))
+    if (isinf(d) || isnan(d)) {
 	return INT2FIX(1);
-    return rb_vm_call(self, sel, 0, 0, true);
+    }
+    return rb_vm_call_super(self, sel, 0, 0);
 //    return ZERO;
 //    return rb_call_super(0, 0);
 }

Modified: MacRuby/trunk/signal.c
===================================================================
--- MacRuby/trunk/signal.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/signal.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -161,8 +161,7 @@
 	}
 	sig = rb_sprintf("SIG%s", signm);
     }
-    //rb_call_super(1, &sig);
-    rb_vm_call(self, selInitialize2, 1, &sig, true);
+    rb_vm_call_super(self, selInitialize2, 1, &sig);
     rb_iv_set(self, "signo", INT2NUM(signo));
 
     return self;
@@ -188,7 +187,7 @@
 
     args[0] = INT2FIX(SIGINT);
     rb_scan_args(argc, argv, "01", &args[1]);
-    return rb_vm_call(self, selInitialize2, 2, args, true);
+    return rb_vm_call_super(self, selInitialize2, 2, args);
 }
 
 void

Modified: MacRuby/trunk/spec/macruby/core/constant_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/constant_spec.rb	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/spec/macruby/core/constant_spec.rb	2010-06-01 09:27:08 UTC (rev 4181)
@@ -81,3 +81,11 @@
     ConstantNSRect.should == NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4))
   end
 end
+
+describe "NSNotFound" do
+  it "is properly mapped as -1" do
+    range = 'foo'.rangeOfString('bar')
+    range.location.should == NSNotFound
+    range.length.should == 0
+  end
+end

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/string.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -2691,12 +2691,12 @@
 	    return Qnil;
 	}
 	else {
-	    VALUE tmp = rb_vm_call(other, selCmp, 1, &self, false);
+	    VALUE tmp = rb_vm_call(other, selCmp, 1, &self);
 	    if (NIL_P(tmp)) {
 		return Qnil;
 	    }
 	    if (!FIXNUM_P(tmp)) {
-		return rb_vm_call(LONG2FIX(0), selMINUS, 1, &tmp, false);
+		return rb_vm_call(LONG2FIX(0), selMINUS, 1, &tmp);
 	    }
 	    result = -FIX2LONG(tmp);
 	}
@@ -3103,7 +3103,7 @@
 	    return regexp_match(other, 0, self);
 
 	default:
-	    return rb_vm_call(other, selEqTilde, 1, &self, false);
+	    return rb_vm_call(other, selEqTilde, 1, &self);
     }
 }
 
@@ -5022,7 +5022,7 @@
     SEL succ_sel = sel_registerName("succ");
 
     VALUE current = beg;
-    VALUE after_end = rb_vm_call(end, succ_sel, 0, NULL, false);
+    VALUE after_end = rb_vm_call(end, succ_sel, 0, NULL);
     StringValue(after_end);
     while (!rb_str_equal(current, after_end)) {
 	rb_yield(current);
@@ -5030,7 +5030,7 @@
 	if (!excl && rb_str_equal(current, end)) {
 	    break;
 	}
-	current = rb_vm_call(current, succ_sel, 0, NULL, false);
+	current = rb_vm_call(current, succ_sel, 0, NULL);
 	StringValue(current);
 	if (excl && rb_str_equal(current, end)) {
 	    break;
@@ -6361,7 +6361,7 @@
     if (TYPE(obj) == T_STRING || TYPE(obj) == T_SYMBOL) {
 	return obj;
     }
-    VALUE str = rb_vm_call(obj, selToS, 0, NULL, false);
+    VALUE str = rb_vm_call(obj, selToS, 0, NULL);
     if (TYPE(str) != T_STRING) {
 	return rb_any_to_s(obj);
     }

Modified: MacRuby/trunk/variable.c
===================================================================
--- MacRuby/trunk/variable.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/variable.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -1410,11 +1410,6 @@
     if (!load || !(file = load->nd_lit)) {
 	return Qfalse;
     }
-    if (false) {
-	// XXX Apparently RubySpec does not want us to do that...
-	return rb_vm_call(*(VALUE *)rb_mKernel, selRequire, 1, &file,
-		false);
-    }
     return rb_require_safe(file, load->nd_nth);
 }
 

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/vm.cpp	2010-06-01 09:27:08 UTC (rev 4181)
@@ -398,6 +398,9 @@
     return_from_block = -1;
     current_super_class = NULL;
     current_super_sel = 0;
+
+    mcache = (struct mcache *)calloc(VM_MCACHE_SIZE, sizeof(struct mcache));
+    assert(mcache != NULL);
 }
 
 static inline void *
@@ -459,6 +462,10 @@
     throw_exc = NULL;
     current_super_class = NULL;
     current_super_sel = 0;
+
+    mcache = (struct mcache *)calloc(VM_MCACHE_SIZE, sizeof(struct mcache));
+    assert(mcache != NULL);
+    memcpy(mcache, vm.mcache, sizeof(struct mcache) * VM_MCACHE_SIZE);
 }
 
 RoxorVM::~RoxorVM(void)
@@ -474,6 +481,9 @@
     GC_RELEASE(broken_with);
     GC_RELEASE(last_status);
     GC_RELEASE(errinfo);
+
+    free(mcache);
+    mcache = NULL;
 }
 
 static void
@@ -743,33 +753,6 @@
     return GET_CORE()->constant_cache_get(rb_intern(name));
 }
 
-struct mcache *
-RoxorCore::method_cache_get(SEL sel, bool super)
-{
-    if (super) {
-	struct mcache *cache = (struct mcache *)malloc(sizeof(struct mcache));
-	cache->flag = 0;
-	// TODO store the cache somewhere and invalidate it appropriately.
-	return cache;
-    }
-    std::map<SEL, struct mcache *>::iterator iter = mcache.find(sel);
-    if (iter == mcache.end()) {
-	struct mcache *cache = (struct mcache *)malloc(sizeof(struct mcache));
-	cache->flag = 0;
-	mcache[sel] = cache;
-	return cache;
-    }
-    return iter->second;
-}
-
-extern "C"
-void *
-rb_vm_get_method_cache(SEL sel)
-{
-    const bool super = strncmp(sel_getName(sel), "__super__:", 10) == 0;
-    return GET_CORE()->method_cache_get(sel, super); 
-}
-
 rb_vm_method_node_t *
 RoxorCore::method_node_get(IMP imp, bool create)
 {
@@ -929,10 +912,10 @@
 	    VALUE sym = ID2SYM(mid);
 	    if (RCLASS_SINGLETON(klass)) {
 		VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
-		rb_vm_call(sk, selSingletonMethodAdded, 1, &sym, false);
+		rb_vm_call(sk, selSingletonMethodAdded, 1, &sym);
 	    }
 	    else {
-		rb_vm_call((VALUE)klass, selMethodAdded, 1, &sym, false);
+		rb_vm_call((VALUE)klass, selMethodAdded, 1, &sym);
 	    }
 	}
     }
@@ -941,9 +924,12 @@
 void
 RoxorCore::invalidate_method_cache(SEL sel)
 {
-    std::map<SEL, struct mcache *>::iterator iter = mcache.find(sel);
-    if (iter != mcache.end()) {
-	iter->second->flag = 0;
+    struct mcache *cache = GET_VM()->get_mcache();
+    for (int i = 0; i < VM_MCACHE_SIZE; i++) {
+	struct mcache *e = &cache[i];
+	if (e->sel == sel) {
+	    e->flag = 0;
+	}
     }
 }
 
@@ -1749,7 +1735,7 @@
     // Re-generate ObjC stub. 
     Function *objc_func = RoxorCompiler::shared->compile_objc_stub(NULL,
 	    node->ruby_imp, node->arity, new_types);
-    node->objc_imp = compile(objc_func);
+    node->objc_imp = compile(objc_func, false);
     // TODO: free LLVM machine code from old objc IMP
     objc_to_ruby_stubs[node->ruby_imp] = node->objc_imp;
 
@@ -2526,10 +2512,10 @@
 	VALUE sym = ID2SYM(mid);
 	if (RCLASS_SINGLETON(klass)) {
 	    VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
-	    rb_vm_call(sk, selSingletonMethodUndefined, 1, &sym, false);
+	    rb_vm_call(sk, selSingletonMethodUndefined, 1, &sym);
 	}
 	else {
-	    rb_vm_call((VALUE)klass, selMethodUndefined, 1, &sym, false);
+	    rb_vm_call((VALUE)klass, selMethodUndefined, 1, &sym);
 	}
     }
 }
@@ -2583,10 +2569,10 @@
 	VALUE sym = ID2SYM(mid);
 	if (RCLASS_SINGLETON(klass)) {
 	    VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
-	    rb_vm_call(sk, selSingletonMethodRemoved, 1, &sym, false);
+	    rb_vm_call(sk, selSingletonMethodRemoved, 1, &sym);
 	}
 	else {
-	    rb_vm_call((VALUE)klass, selMethodRemoved, 1, &sym, false);
+	    rb_vm_call((VALUE)klass, selMethodRemoved, 1, &sym);
 	}
     }
 }
@@ -2664,7 +2650,7 @@
     int n = 0;
     VALUE args[3];
     VALUE not_args[3] = {rb_str_new2(format), obj, meth};
-    args[n++] = rb_vm_call(rb_cNameErrorMesg, selNot2, 3, not_args, false);
+    args[n++] = rb_vm_call(rb_cNameErrorMesg, selNot2, 3, not_args);
     args[n++] = meth;
     if (exc == rb_eNoMethodError) {
 	args[n++] = rb_ary_new4(argc - 1, argv + 1);
@@ -3005,20 +2991,6 @@
     GET_VM()->pop_current_binding(false);
 }
 
-extern "C"
-void *
-rb_vm_get_call_cache(SEL sel)
-{
-    return GET_CORE()->method_cache_get(sel, false);
-}
-
-extern "C"
-void *
-rb_vm_get_call_cache2(SEL sel, unsigned char super)
-{
-    return GET_CORE()->method_cache_get(sel, super);
-}
-
 // Should be used inside a method implementation.
 extern "C"
 int
@@ -3092,7 +3064,7 @@
 	rb_raise(rb_eArgError, "no receiver given");
     }
     SEL msel = argc - 1 == 0 ? (SEL)dvars[0] : (SEL)dvars[1];
-    return rb_vm_call(argv[0], msel, argc - 1, &argv[1], false);
+    return rb_vm_call(argv[0], msel, argc - 1, &argv[1]);
 }
 
 extern "C"
@@ -4128,7 +4100,7 @@
     for (int i = 0, count = RARRAY_LEN(finalizer->finalizers); i < count; i++) {
 	VALUE b = RARRAY_AT(finalizer->finalizers, i);
 	try {
-	    rb_vm_call(b, selCall, 1, &finalizer->objid, false);
+	    rb_vm_call(b, selCall, 1, &finalizer->objid);
 	}
 	catch (...) {
 	    // Do nothing.

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/vm.h	2010-06-01 09:27:08 UTC (rev 4181)
@@ -317,12 +317,10 @@
 void rb_vm_alias(VALUE klass, ID name, ID def);
 bool rb_vm_copy_method(Class klass, Method method);
 void rb_vm_copy_methods(Class from_class, Class to_class);
-VALUE rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *args, bool super);
-VALUE rb_vm_call_with_cache(void *cache, VALUE self, SEL sel, int argc,
-	const VALUE *argv);
-VALUE rb_vm_call_with_cache2(void *cache, rb_vm_block_t *block, VALUE self,
-	VALUE klass, SEL sel, int argc, const VALUE *argv);
-void *rb_vm_get_call_cache(SEL sel);
+VALUE rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *args);
+VALUE rb_vm_call2(rb_vm_block_t *block, VALUE self, VALUE klass, SEL sel,
+	int argc, const VALUE *argv);
+VALUE rb_vm_call_super(VALUE self, SEL sel, int argc, const VALUE *args);
 VALUE rb_vm_yield(int argc, const VALUE *argv);
 VALUE rb_vm_yield_under(VALUE klass, VALUE self, int argc, const VALUE *argv);
 bool rb_vm_respond_to(VALUE obj, SEL sel, bool priv);
@@ -524,36 +522,25 @@
     VALUE val;
 };
 
-#if defined(__cplusplus)
-}
-
-#include "bridgesupport.h"
-
-typedef struct {
-    Function *func;
-    rb_vm_arity_t arity;
-    int flags;
-} rb_vm_method_source_t;
-
 typedef VALUE rb_vm_objc_stub_t(IMP imp, id self, SEL sel, int argc,
 	const VALUE *argv);
 typedef VALUE rb_vm_c_stub_t(IMP imp, int argc, const VALUE *argv);
-#define rb_vm_long_arity_stub_t rb_vm_objc_stub_t
-typedef VALUE rb_vm_long_arity_bstub_t(IMP imp, id self, SEL sel,
-	VALUE dvars, rb_vm_block_t *b, int argc, const VALUE *argv);
 
+#include "bridgesupport.h"
+
 struct mcache {
 #define MCACHE_RCALL 0x1 // Ruby call
 #define MCACHE_OCALL 0x2 // Objective-C call
 #define MCACHE_FCALL 0x4 // C call
+#define MCACHE_SUPER 0x8 // Super call (only applied with RCALL or OCALL)
     uint8_t flag;
+    SEL sel;
+    Class klass;
     union {
 	struct {
-	    Class klass;
 	    rb_vm_method_node_t *node;
 	} rcall;
 	struct {
-	    Class klass;
 	    IMP imp;
 	    bs_element_method_t *bs_method;	
 	    rb_vm_objc_stub_t *stub;
@@ -564,11 +551,23 @@
 	    rb_vm_c_stub_t *stub;
 	} fcall;
     } as;
-#define rcache cache->as.rcall
-#define ocache cache->as.ocall
-#define fcache cache->as.fcall
 };
 
+#define VM_MCACHE_SIZE	0x1000
+
+#if defined(__cplusplus)
+}
+
+typedef struct {
+    Function *func;
+    rb_vm_arity_t arity;
+    int flags;
+} rb_vm_method_source_t;
+
+#define rb_vm_long_arity_stub_t rb_vm_objc_stub_t
+typedef VALUE rb_vm_long_arity_bstub_t(IMP imp, id self, SEL sel,
+	VALUE dvars, rb_vm_block_t *b, int argc, const VALUE *argv);
+
 // For rb_vm_define_class()
 #define DEFINE_MODULE		0x1
 #define DEFINE_OUTER 		0x2
@@ -630,8 +629,7 @@
 	std::map<IMP, rb_vm_method_node_t *> ruby_imps;
 	std::map<Method, rb_vm_method_node_t *> ruby_methods;
 
-	// Method and constant caches.
-	std::map<SEL, struct mcache *> mcache;
+	// Constants cache.
 	std::map<ID, struct ccache *> ccache;
 
 	// Optimized selectors redefinition cache.
@@ -762,7 +760,6 @@
 		char *path, size_t path_len, unsigned long *ln,
 		char *name, size_t name_len);
 
-	struct mcache *method_cache_get(SEL sel, bool super);
 	void invalidate_method_cache(SEL sel);
 	rb_vm_method_node_t *method_node_get(IMP imp, bool create=false);
 	rb_vm_method_node_t *method_node_get(Method m, bool create=false);
@@ -882,6 +879,9 @@
 	std::map<VALUE, int *> catch_nesting;
 	std::vector<VALUE> recursive_objects;
 
+	// Method cache.
+	struct mcache *mcache;
+
 	VALUE thread;
 	Class current_class;
 	VALUE current_top_object;
@@ -922,6 +922,7 @@
 	ACCESSOR(throw_exc, RoxorCatchThrowException *);
 	ACCESSOR(current_super_class, Class);
 	ACCESSOR(current_super_sel, SEL);
+	READER(mcache, struct mcache *);
 
 	std::string debug_blocks(void);
 

Modified: MacRuby/trunk/vm_eval.c
===================================================================
--- MacRuby/trunk/vm_eval.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/vm_eval.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -41,10 +41,8 @@
 	}
     }
 
-    void *cache = rb_vm_get_call_cache(sel);
     rb_vm_block_t *block = pass_current_block ? rb_vm_current_block() : NULL;
-    return rb_vm_call_with_cache2(cache, block, recv, CLASS_OF(recv),
-	    sel, argc, argv);
+    return rb_vm_call2(block, recv, CLASS_OF(recv), sel, argc, argv);
 }
 
 /*
@@ -260,19 +258,16 @@
 }
 
 VALUE
-rb_objc_block_call(VALUE obj, SEL sel, void *cache, int argc, VALUE *argv, 
-		   VALUE (*bl_proc) (ANYARGS), VALUE data2)
+rb_objc_block_call(VALUE obj, SEL sel, int argc, VALUE *argv,
+	VALUE (*bl_proc) (ANYARGS), VALUE data2)
 {
     rb_vm_block_t *b = rb_vm_create_block((IMP)bl_proc, obj, data2);
-    if (cache == NULL) {
-	cache = rb_vm_get_call_cache(sel);
-    }
-    return rb_vm_call_with_cache2(cache, b, obj, 0, sel, argc, argv);
+    return rb_vm_call2(b, obj, 0, sel, argc, argv);
 }
 
 VALUE
 rb_block_call(VALUE obj, ID mid, int argc, VALUE *argv,
-	      VALUE (*bl_proc) (ANYARGS), VALUE data2)
+	VALUE (*bl_proc) (ANYARGS), VALUE data2)
 {
     SEL sel;
     if (argc == 0) {
@@ -283,7 +278,7 @@
 	snprintf(buf, sizeof buf, "%s:", rb_id2name(mid));
 	sel = sel_registerName(buf);
     }
-    return rb_objc_block_call(obj, sel, NULL, argc, argv, bl_proc, data2);
+    return rb_objc_block_call(obj, sel, argc, argv, bl_proc, data2);
 }
 
 VALUE

Modified: MacRuby/trunk/vm_method.c
===================================================================
--- MacRuby/trunk/vm_method.c	2010-06-01 09:11:36 UTC (rev 4180)
+++ MacRuby/trunk/vm_method.c	2010-06-01 09:27:08 UTC (rev 4181)
@@ -255,7 +255,7 @@
 	    VALUE args[2];
 	    args[0] = ID2SYM(id);
 	    args[1] = priv ? Qtrue : Qfalse;
-	    return RTEST(rb_vm_call(obj, selRespondToDefault, 2, args, false));
+	    return RTEST(rb_vm_call(obj, selRespondToDefault, 2, args));
 	}
     }
     return true;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100601/cf978e67/attachment-0001.html>


More information about the macruby-changes mailing list