Revision: 4181 http://trac.macosforge.org/projects/ruby/changeset/4181 Author: lsansonetti@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 *> ¶ms) { 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;