[macruby-changes] [3927] MacRuby/branches/vm-mcache
source_changes at macosforge.org
source_changes at macosforge.org
Tue Apr 13 20:07:31 PDT 2010
Revision: 3927
http://trac.macosforge.org/projects/ruby/changeset/3927
Author: lsansonetti at apple.com
Date: 2010-04-13 20:07:29 -0700 (Tue, 13 Apr 2010)
Log Message:
-----------
experimental per-VM method cache
Modified Paths:
--------------
MacRuby/branches/vm-mcache/array.c
MacRuby/branches/vm-mcache/compar.c
MacRuby/branches/vm-mcache/compiler.cpp
MacRuby/branches/vm-mcache/compiler.h
MacRuby/branches/vm-mcache/dispatcher.cpp
MacRuby/branches/vm-mcache/enum.c
MacRuby/branches/vm-mcache/enumerator.c
MacRuby/branches/vm-mcache/hash.c
MacRuby/branches/vm-mcache/id.c
MacRuby/branches/vm-mcache/id.h
MacRuby/branches/vm-mcache/include/ruby/ruby.h
MacRuby/branches/vm-mcache/object.c
MacRuby/branches/vm-mcache/proc.c
MacRuby/branches/vm-mcache/process.c
MacRuby/branches/vm-mcache/range.c
MacRuby/branches/vm-mcache/vm.cpp
MacRuby/branches/vm-mcache/vm.h
MacRuby/branches/vm-mcache/vm_eval.c
Modified: MacRuby/branches/vm-mcache/array.c
===================================================================
--- MacRuby/branches/vm-mcache/array.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/array.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -1889,8 +1889,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/branches/vm-mcache/compar.c
===================================================================
--- MacRuby/branches/vm-mcache/compar.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/compar.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -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,14 +36,14 @@
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, false);
}
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], false);
if (NIL_P(c)) {
return Qfalse;
@@ -93,7 +92,7 @@
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);
+ VALUE c = rb_vm_call(x, cmp, 1, &y, false);
if (rb_cmpint(c, x, y) > 0) return Qtrue;
return Qfalse;
@@ -111,7 +110,7 @@
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);
+ VALUE c = rb_vm_call(x, cmp, 1, &y, false);
if (rb_cmpint(c, x, y) >= 0) return Qtrue;
return Qfalse;
@@ -129,7 +128,7 @@
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);
+ VALUE c = rb_vm_call(x, cmp, 1, &y, false);
if (rb_cmpint(c, x, y) < 0) return Qtrue;
return Qfalse;
@@ -147,7 +146,7 @@
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);
+ VALUE c = rb_vm_call(x, cmp, 1, &y, false);
if (rb_cmpint(c, x, y) <= 0) return Qtrue;
return Qfalse;
@@ -225,5 +224,4 @@
rb_objc_define_method(rb_mComparable, "between?", cmp_between, 2);
cmp = sel_registerName("<=>:");
- cmp_cache = rb_vm_get_call_cache(cmp);
}
Modified: MacRuby/branches/vm-mcache/compiler.cpp
===================================================================
--- MacRuby/branches/vm-mcache/compiler.cpp 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/compiler.cpp 2010-04-14 03:07:29 UTC (rev 3927)
@@ -268,7 +268,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));
@@ -425,12 +424,12 @@
{
Function *func = NULL;
- // VALUE rb_vm_fast_op(struct mcache *cache, VALUE left, VALUE right);
+ // VALUE rb_vm_fast_op(VALUE left, VALUE right);
#define fast_op(storage, name) \
do { \
if (storage == NULL) { \
storage = cast<Function>(module->getOrInsertFunction(name, \
- RubyObjTy, PtrTy, RubyObjTy, RubyObjTy, NULL)); \
+ RubyObjTy, RubyObjTy, RubyObjTy, NULL)); \
} \
func = storage; \
} \
@@ -474,7 +473,6 @@
}
std::vector<Value *> params;
- params.push_back(compile_mcache(sel, false));
params.push_back(selfVal);
params.push_back(otherVal);
@@ -485,17 +483,15 @@
RoxorCompiler::compile_when_splat(Value *comparedToVal, Value *splatVal)
{
if (whenSplatFunc == NULL) {
- // VALUE rb_vm_when_splat(struct mcache *cache,
- // unsigned char overriden,
- // VALUE comparedTo, VALUE splat)
+ // VALUE rb_vm_when_splat(unsigned char overriden,
+ // VALUE comparedTo, VALUE splat)
whenSplatFunc = cast<Function>
(module->getOrInsertFunction("rb_vm_when_splat",
- RubyObjTy, PtrTy, Int1Ty,
- RubyObjTy, RubyObjTy, NULL));
+ RubyObjTy, Int1Ty, RubyObjTy,
+ RubyObjTy, NULL));
}
std::vector<Value *> params;
- params.push_back(compile_mcache(selEqq, false));
GlobalVariable *is_redefined = GET_CORE()->redefined_op_gvar(selEqq, true);
params.push_back(new LoadInst(is_redefined, "", bb));
params.push_back(comparedToVal);
@@ -571,55 +567,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));
- }
-
- std::vector<Value *> params;
- params.push_back(sel);
- params.push_back(ConstantInt::get(Int8Ty, super ? 1 : 0));
-
- return CallInst::Create(getCacheFunc, params.begin(), params.end(), "", 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);
@@ -757,10 +704,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);
@@ -805,7 +751,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));
@@ -2203,7 +2148,7 @@
return NULL;
}
- Value *val = params[2]; // self
+ Value *val = params[1]; // self
Function *f = bb->getParent();
@@ -2236,7 +2181,7 @@
GlobalVariable *is_redefined = GET_CORE()->redefined_op_gvar(sel, true);
- Value *leftVal = params[2]; // self
+ Value *leftVal = params[1]; // self
Value *rightVal = params.back();
VALUE leftRVal = Qundef, rightRVal = Qundef;
@@ -2552,7 +2497,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;
@@ -2561,31 +2506,34 @@
Function *opt_func = NULL;
if (sel == selLTLT) {
- opt_func = cast<Function>(module->getOrInsertFunction("rb_vm_fast_shift",
- RubyObjTy, RubyObjTy, RubyObjTy, PtrTy, Int1Ty, NULL));
+ opt_func = cast<Function>(module->getOrInsertFunction(
+ "rb_vm_fast_shift",
+ RubyObjTy, RubyObjTy, RubyObjTy, Int1Ty, NULL));
}
else if (sel == selAREF) {
- opt_func = cast<Function>(module->getOrInsertFunction("rb_vm_fast_aref",
- RubyObjTy, RubyObjTy, RubyObjTy, PtrTy, Int1Ty, NULL));
+ opt_func = cast<Function>(module->getOrInsertFunction(
+ "rb_vm_fast_aref",
+ RubyObjTy, RubyObjTy, RubyObjTy, Int1Ty, NULL));
}
else if (sel == selASET) {
- opt_func = cast<Function>(module->getOrInsertFunction("rb_vm_fast_aset",
- RubyObjTy, RubyObjTy, RubyObjTy, RubyObjTy, PtrTy,
- Int1Ty, NULL));
+ opt_func = cast<Function>(module->getOrInsertFunction(
+ "rb_vm_fast_aset",
+ RubyObjTy, RubyObjTy, RubyObjTy, RubyObjTy, Int1Ty,
+ NULL));
}
else {
abort();
}
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.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));
@@ -2624,16 +2572,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;
@@ -2651,118 +2598,6 @@
return pn;
}
-#if 0
- // XXX this optimization is disabled because it's buggy and not really
- // interesting
- // #eval
- else if (sel == selEval) {
-
- if (current_block_func != NULL || argc != 1) {
- return NULL;
- }
- Value *strVal = params.back();
- if (!ConstantInt::classof(strVal)) {
- return NULL;
- }
- VALUE str = cast<ConstantInt>(strVal)->getZExtValue();
- if (TYPE(str) != T_STRING) {
- return NULL;
- }
- // FIXME:
- // - pass the real file/line arguments
- // - catch potential parsing exceptions
- NODE *new_node = rb_compile_string("", str, 0);
- if (new_node == NULL) {
- return NULL;
- }
- if (nd_type(new_node) != NODE_SCOPE || new_node->nd_body == NULL) {
- return NULL;
- }
-
- GlobalVariable *is_redefined = GET_VM()->redefined_op_gvar(sel, true);
-
- Value *is_redefined_val = new LoadInst(is_redefined, "", bb);
- Value *isOpRedefined = new ICmpInst(ICmpInst::ICMP_EQ,
- is_redefined_val, ConstantInt::getFalse(), "", bb);
-
- Function *f = bb->getParent();
-
- BasicBlock *thenBB = BasicBlock::Create("op_not_redefined", f);
- BasicBlock *elseBB = BasicBlock::Create("op_dispatch", f);
- BasicBlock *mergeBB = BasicBlock::Create("op_merge", f);
-
- BranchInst::Create(thenBB, elseBB, isOpRedefined, bb);
-
- bb = thenBB;
- Value *thenVal = compile_node(new_node->nd_body);
- thenBB = bb;
- BranchInst::Create(mergeBB, thenBB);
-
- bb = elseBB;
- Value *elseVal = compile_dispatch_call(params);
- BranchInst::Create(mergeBB, elseBB);
-
- bb = mergeBB;
- PHINode *pn = PHINode::Create(RubyObjTy, "op_tmp", mergeBB);
- pn->addIncoming(thenVal, thenBB);
- pn->addIncoming(elseVal, elseBB);
-
- return pn;
-
- }
-#endif
-#if 0
- // TODO: block inlining optimization
- else if (current_block_func != NULL) {
- static SEL selTimes = 0;
- if (selTimes == 0) {
- selTimes = rb_intern("times");
- }
-
- if (sel == selTimes && argc == 0) {
- Value *val = params[1]; // self
-
- long valLong;
- if (unbox_fixnum_constant(val, &valLong)) {
- GlobalVariable *is_redefined = redefined_op_gvar(sel, true);
-
- Value *is_redefined_val = new LoadInst(is_redefined, "", bb);
- Value *isOpRedefined = new ICmpInst(ICmpInst::ICMP_EQ, is_redefined_val, ConstantInt::getFalse(), "", bb);
-
- Function *f = bb->getParent();
-
- BasicBlock *thenBB = BasicBlock::Create("op_not_redefined", f);
- BasicBlock *elseBB = BasicBlock::Create("op_dispatch", f);
- BasicBlock *mergeBB = BasicBlock::Create("op_merge", f);
-
- BranchInst::Create(thenBB, elseBB, isOpRedefined, bb);
- bb = thenBB;
-
-
-
-// Val *mem = new AllocaInst(RubyObjTy, "", bb);
-// new StoreInst(zeroVal, mem, "", bb);
-// Val *i = LoadInst(mem, "", bb);
-
-
-
- Value *thenVal = val;
- BranchInst::Create(mergeBB, thenBB);
-
- Value *elseVal = dispatchCall;
- elseBB->getInstList().push_back(dispatchCall);
- BranchInst::Create(mergeBB, elseBB);
-
- PHINode *pn = PHINode::Create(Type::Int32Ty, "op_tmp", mergeBB);
- pn->addIncoming(thenVal, thenBB);
- pn->addIncoming(elseVal, elseBB);
- bb = mergeBB;
-
- return pn;
- }
- }
- }
-#endif
return NULL;
}
@@ -3631,7 +3466,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));
@@ -3691,7 +3525,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));
@@ -3716,7 +3549,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));
@@ -3768,7 +3600,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));
@@ -4215,7 +4046,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) {
@@ -4241,18 +4072,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);
}
@@ -4364,7 +4190,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.
@@ -4641,7 +4467,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));
@@ -5236,7 +5061,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) {
@@ -5252,9 +5076,11 @@
params.push_back(current_self);
}
- params.push_back(compile_sel((is_lambda ? selLambda : selEach)));
+ params.push_back(compile_sel(is_lambda
+ ? selLambda : selEach));
params.push_back(compile_block_create());
- params.push_back(ConstantInt::get(Int8Ty, (is_lambda ? DISPATCH_FCALL : 0)));
+ params.push_back(ConstantInt::get(Int8Ty, is_lambda
+ ? DISPATCH_FCALL : 0));
params.push_back(ConstantInt::get(Int32Ty, 0));
caller = compile_dispatch_call(params);
@@ -5454,7 +5280,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));
@@ -5544,36 +5369,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;
-
- std::vector<Value *> params;
- Value *load = compile_sel(sel, false);
- params.push_back(load);
-
- Instruction *call = CallInst::Create(getMethodCacheFunc,
- params.begin(), params.end(), "");
-
- 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(
Modified: MacRuby/branches/vm-mcache/compiler.h
===================================================================
--- MacRuby/branches/vm-mcache/compiler.h 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/compiler.h 2010-04-14 03:07:29 UTC (rev 3927)
@@ -305,8 +305,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);
@@ -386,7 +384,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;
@@ -398,7 +395,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/branches/vm-mcache/dispatcher.cpp
===================================================================
--- MacRuby/branches/vm-mcache/dispatcher.cpp 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/dispatcher.cpp 2010-04-14 03:07:29 UTC (rev 3927)
@@ -23,6 +23,7 @@
#include <dlfcn.h>
#define ROXOR_VM_DEBUG 0
+#define ROXOR_MCACHE_DEBUG 1
#define MAX_DISPATCH_ARGS 100
static force_inline void
@@ -347,10 +348,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, NULL, selMethodMissing, argc + 1,
+ new_argv);
}
}
@@ -551,16 +550,37 @@
return x_imp == y_imp;
}
+static inline int
+mcache_hash(Class klass, SEL sel)
+{
+ return (((unsigned long)klass >> 3) ^ (unsigned long)sel)
+ & (MCACHE_SIZE - 1);
+}
+
+#if ROXOR_MCACHE_DEBUG
+static long cached_count = 0;
+static long collision_count = 0;
+#endif
+
+extern "C"
+void
+rb_vm_dispatch_finalize(void)
+{
+#if ROXOR_MCACHE_DEBUG
+ printf("cached count %ld, collision count %ld\n", cached_count,
+ collision_count);
+#endif
+}
+
static force_inline VALUE
-__rb_vm_dispatch(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)
+__rb_vm_dispatch(RoxorVM *vm, 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) {
+ if (sel == 0) {
+ if (opt == DISPATCH_SUPER) {
rb_raise(rb_eNoMethodError, "super called outside of method");
}
- abort();
+ abort();
}
if (klass == NULL) {
@@ -570,18 +590,44 @@
#if ROXOR_VM_DEBUG
bool cached = true;
#endif
+ int cache_hash = 0;
bool cache_method = true;
+ struct mcache *cache;
+ if (opt == DISPATCH_SUPER) {
+ cache_hash = mcache_hash(klass, sel) + 1;
+ cache = &vm->mcache[cache_hash];
+ if (!(cache->flag & MCACHE_SUPER) || cache->sel != sel) {
+ cache->flag = 0; // recache
+#if ROXOR_MCACHE_DEBUG
+ collision_count++;
+#endif
+ }
+#if ROXOR_MCACHE_DEBUG
+ else {
+ cached_count++;
+ }
+#endif
+ }
+ else {
+ cache_hash = mcache_hash(klass, sel);
+ cache = &vm->mcache[cache_hash];
+ if (cache->sel != sel) {
+ cache->flag = 0; // recache
+#if ROXOR_MCACHE_DEBUG
+ collision_count++;
+#endif
+ }
+#if ROXOR_MCACHE_DEBUG
+ else {
+ cached_count++;
+ }
+#endif
+ }
+
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) {
recache:
#if ROXOR_VM_DEBUG
@@ -620,6 +666,11 @@
// objc call
fill_ocache(cache, self, klass, imp, sel, method, argc);
}
+
+ if (opt == DISPATCH_SUPER) {
+ cache->flag |= MCACHE_SUPER;
+ }
+ cache->sel = sel;
}
else {
// Method is not found...
@@ -732,7 +783,7 @@
}
dispatch:
- if (cache->flag == MCACHE_RCALL) {
+ if (cache->flag & MCACHE_RCALL) {
if (rcache.klass != klass) {
goto recache;
}
@@ -741,7 +792,7 @@
}
#if ROXOR_VM_DEBUG
- printf("ruby dispatch %c[<%s %p> %s] (imp %p block %p argc %d opt %d cache %p cached %s)\n",
+ printf("ruby dispatch %c[<%s %p> %s] (imp %p block %p argc %d opt %d cache hash %d cached %s)\n",
class_isMetaClass(klass) ? '+' : '-',
class_getName(klass),
(void *)self,
@@ -750,7 +801,7 @@
block,
argc,
opt,
- cache,
+ cache_hash,
cached ? "true" : "false");
#endif
@@ -820,7 +871,7 @@
return v;
}
- else if (cache->flag == MCACHE_OCALL) {
+ else if (cache->flag & MCACHE_OCALL) {
if (ocache.klass != klass) {
goto recache;
}
@@ -856,13 +907,14 @@
}
#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 argc %d cache hash %d cached %s\n",
class_isMetaClass(klass) ? '+' : '-',
class_getName(klass),
(void *)self,
sel_getName(sel),
ocache.imp,
argc,
+ cache_hash,
cached ? "true" : "false");
#endif
@@ -912,7 +964,7 @@
return __rb_vm_objc_dispatch(ocache.stub, ocache.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,
@@ -1032,8 +1084,8 @@
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, ...)
{
VALUE base_argv[MAX_DISPATCH_ARGS];
VALUE *argv = base_argv;
@@ -1066,49 +1118,26 @@
~Finally() { vm->pop_current_binding(); }
} finalizer(vm);
- VALUE retval = __rb_vm_dispatch(vm, cache, top, self, NULL, sel, block,
- opt, argc, argv);
-
- return retval;
+ return __rb_vm_dispatch(vm, top, self, NULL, sel, block, opt, argc, argv);
}
extern "C"
VALUE
rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *argv, bool super)
{
- 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 __rb_vm_dispatch(GET_VM(), 0, self, NULL, sel, NULL,
+ super ? DISPATCH_SUPER : DISPATCH_FCALL, argc, argv);
}
extern "C"
VALUE
-rb_vm_call_with_cache(void *cache, VALUE self, SEL sel, int argc,
+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, NULL,
- sel, NULL, DISPATCH_FCALL, argc, argv);
+ return __rb_vm_dispatch(GET_VM(), 0, self, (Class)klass, sel, block,
+ DISPATCH_FCALL, 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)
-{
- return __rb_vm_dispatch(GET_VM(), (struct mcache *)cache, 0, self,
- (Class)klass, sel, block, DISPATCH_FCALL, argc, argv);
-}
-
// The rb_vm_fast_* functions don't check if the selector has been redefined or
// not, because this is already handled by the compiler.
// Also, fixnums and floats are already handled.
@@ -1130,122 +1159,134 @@
extern "C"
VALUE
-rb_vm_fast_plus(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_plus(VALUE self, VALUE other)
{
switch (TYPE(self)) {
// TODO: Array, String
case T_BIGNUM:
return rb_big_plus(self, other);
+
case T_FIXNUM:
return rb_fix_plus(self, other);
+
case T_FLOAT:
return rb_flo_plus(self, other);
+
case T_COMPLEX:
return rb_nu_plus(self, other);
}
- return rb_vm_dispatch(cache, 0, self, selPLUS, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selPLUS, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_minus(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_minus(VALUE self, VALUE other)
{
switch (TYPE(self)) {
// TODO: Array, String
case T_BIGNUM:
return rb_big_minus(self, other);
+
case T_FIXNUM:
return rb_fix_minus(self, other);
+
case T_FLOAT:
return rb_flo_minus(self, other);
+
case T_COMPLEX:
return rb_nu_minus(self, other);
}
- return rb_vm_dispatch(cache, 0, self, selMINUS, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selMINUS, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_div(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_div(VALUE self, VALUE other)
{
switch (TYPE(self)) {
case T_BIGNUM:
return rb_big_div(self, other);
+
case T_FIXNUM:
return rb_fix_div(self, other);
+
case T_FLOAT:
return rb_flo_div(self, other);
+
case T_COMPLEX:
return rb_nu_div(self, other);
}
- return rb_vm_dispatch(cache, 0, self, selDIV, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selDIV, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_mult(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_mult(VALUE self, VALUE other)
{
switch (TYPE(self)) {
// TODO: Array, String
case T_BIGNUM:
return rb_big_mul(self, other);
+
case T_FIXNUM:
return rb_fix_mul(self, other);
+
case T_FLOAT:
return rb_flo_mul(self, other);
+
case T_COMPLEX:
return rb_nu_mul(self, other);
}
- return rb_vm_dispatch(cache, 0, self, selMULT, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selMULT, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_lt(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_lt(VALUE self, VALUE other)
{
switch (TYPE(self)) {
case T_BIGNUM:
return FIX2INT(rb_big_cmp(self, other)) < 0 ? Qtrue : Qfalse;
}
- return rb_vm_dispatch(cache, 0, self, selLT, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selLT, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_le(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_le(VALUE self, VALUE other)
{
switch (TYPE(self)) {
case T_BIGNUM:
return FIX2INT(rb_big_cmp(self, other)) <= 0 ? Qtrue : Qfalse;
}
- return rb_vm_dispatch(cache, 0, self, selLE, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selLE, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_gt(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_gt(VALUE self, VALUE other)
{
switch (TYPE(self)) {
case T_BIGNUM:
return FIX2INT(rb_big_cmp(self, other)) > 0 ? Qtrue : Qfalse;
}
- return rb_vm_dispatch(cache, 0, self, selGT, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selGT, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_ge(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_ge(VALUE self, VALUE other)
{
switch (TYPE(self)) {
case T_BIGNUM:
return FIX2INT(rb_big_cmp(self, other)) >= 0 ? Qtrue : Qfalse;
}
- return rb_vm_dispatch(cache, 0, self, selGE, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selGE, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_eq(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_eq(VALUE self, VALUE other)
{
const int self_type = TYPE(self);
switch (self_type) {
@@ -1282,20 +1323,20 @@
case T_BIGNUM:
return rb_big_eq(self, other);
}
- return rb_vm_dispatch(cache, 0, self, selEq, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selEq, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_neq(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_neq(VALUE self, VALUE other)
{
// TODO
- return rb_vm_dispatch(cache, 0, self, selNeq, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selNeq, NULL, 0, 1, other);
}
extern "C"
VALUE
-rb_vm_fast_eqq(struct mcache *cache, VALUE self, VALUE other)
+rb_vm_fast_eqq(VALUE self, VALUE other)
{
switch (TYPE(self)) {
// TODO: Range
@@ -1316,14 +1357,13 @@
return rb_obj_is_kind_of(other, self);
default:
- return rb_vm_dispatch(cache, 0, self, selEqq, NULL, 0, 1, other);
+ return rb_vm_dispatch(0, self, selEqq, NULL, 0, 1, other);
}
}
extern "C"
VALUE
-rb_vm_when_splat(struct mcache *cache, unsigned char overriden,
- VALUE comparedTo, VALUE splat)
+rb_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)) {
@@ -1333,7 +1373,7 @@
if (overriden == 0) {
for (int i = 0; i < count; ++i) {
VALUE o = RARRAY_AT(ary, i);
- if (RTEST(rb_vm_fast_eqq(cache, o, comparedTo))) {
+ if (RTEST(rb_vm_fast_eqq(o, comparedTo))) {
return Qtrue;
}
}
@@ -1341,8 +1381,7 @@
else {
for (int i = 0; i < count; ++i) {
VALUE o = RARRAY_AT(ary, i);
- if (RTEST(rb_vm_dispatch(cache, 0, o, selEqq, NULL, 0, 1,
- comparedTo))) {
+ if (RTEST(rb_vm_dispatch(0, o, selEqq, NULL, 0, 1, comparedTo))) {
return Qtrue;
}
}
@@ -1352,8 +1391,7 @@
extern "C"
VALUE
-rb_vm_fast_shift(VALUE obj, VALUE other, struct mcache *cache,
- unsigned char overriden)
+rb_vm_fast_shift(VALUE obj, VALUE other, unsigned char overriden)
{
if (overriden == 0) {
switch (TYPE(obj)) {
@@ -1373,14 +1411,13 @@
#endif
}
}
- return __rb_vm_dispatch(GET_VM(), cache, 0, obj, NULL, selLTLT, NULL, 0, 1,
+ return __rb_vm_dispatch(GET_VM(), 0, obj, NULL, selLTLT, NULL, 0, 1,
&other);
}
extern "C"
VALUE
-rb_vm_fast_aref(VALUE obj, VALUE other, struct mcache *cache,
- unsigned char overriden)
+rb_vm_fast_aref(VALUE obj, VALUE other, unsigned char overriden)
{
if (overriden == 0)
switch (TYPE(obj)) {
@@ -1396,14 +1433,13 @@
}
break;
}
- return __rb_vm_dispatch(GET_VM(), cache, 0, obj, NULL, selAREF, NULL, 0, 1,
+ return __rb_vm_dispatch(GET_VM(), 0, obj, NULL, selAREF, NULL, 0, 1,
&other);
}
extern "C"
VALUE
-rb_vm_fast_aset(VALUE obj, VALUE other1, VALUE other2, struct mcache *cache,
- unsigned char overriden)
+rb_vm_fast_aset(VALUE obj, VALUE other1, VALUE other2, unsigned char overriden)
{
if (overriden == 0) {
switch (TYPE(obj)) {
@@ -1424,7 +1460,7 @@
}
}
VALUE args[2] = { other1, other2 };
- return __rb_vm_dispatch(GET_VM(), cache, 0, obj, NULL, selASET, NULL, 0, 2,
+ return __rb_vm_dispatch(GET_VM(), 0, obj, NULL, selASET, NULL, 0, 2,
args);
}
@@ -1579,9 +1615,13 @@
} finalizer(vm, b, old_current_class);
if (b->flags & VM_BLOCK_METHOD) {
+#if 0
+ // TODO
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);
+#endif
+ return Qnil;
}
return __rb_vm_bcall(self, sel, (VALUE)b->dvars, b, b->imp, b->arity,
argc, argv);
Modified: MacRuby/branches/vm-mcache/enum.c
===================================================================
--- MacRuby/branches/vm-mcache/enum.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/enum.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -81,7 +81,8 @@
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;
}
@@ -164,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]);
}
@@ -203,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;
}
@@ -277,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];
}
@@ -313,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;
}
@@ -348,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;
}
@@ -390,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;
}
@@ -410,7 +411,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;
}
@@ -518,7 +519,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;
}
@@ -560,7 +561,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]);
}
@@ -605,7 +606,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;
}
@@ -658,7 +659,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];
}
@@ -792,7 +793,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);
@@ -850,7 +851,8 @@
{
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;
}
@@ -889,7 +891,8 @@
{
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;
}
@@ -933,8 +936,11 @@
{
VALUE result = Qundef;
- rb_objc_block_call(obj, selEach, cacheEach, 0, 0, rb_block_given_p() ? one_iter_i : one_i, (VALUE)&result);
- if (result == Qundef) return Qfalse;
+ 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;
}
@@ -970,7 +976,8 @@
{
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;
}
@@ -1038,12 +1045,14 @@
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;
+ if (result[0] == Qundef) {
+ return Qnil;
+ }
return result[0];
}
@@ -1110,12 +1119,14 @@
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;
+ if (result[0] == Qundef) {
+ return Qnil;
+ }
return result[0];
}
@@ -1197,10 +1208,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]);
@@ -1248,7 +1259,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];
}
@@ -1291,7 +1302,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];
}
@@ -1345,7 +1356,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]);
}
@@ -1379,7 +1390,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];
}
@@ -1415,7 +1426,8 @@
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;
}
@@ -1571,7 +1583,8 @@
result = rb_ary_new();
}
memo = rb_node_newnode(NODE_MEMO, result, rb_ary_new4(argc, argv), 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;
}
@@ -1607,7 +1620,7 @@
args[1] = len;
args[0] = rb_ary_new();
- 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];
}
@@ -1639,7 +1652,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;
}
@@ -1679,7 +1692,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];
}
@@ -1719,7 +1732,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];
}
@@ -1773,7 +1786,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/branches/vm-mcache/enumerator.c
===================================================================
--- MacRuby/branches/vm-mcache/enumerator.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/enumerator.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -14,6 +14,8 @@
#include "ruby/ruby.h"
#include "id.h"
+#include "ruby/node.h"
+#include "vm.h"
/*
* Document-class: Enumerable::Enumerator
@@ -141,7 +143,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 +200,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;
}
@@ -321,7 +323,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,
enumerator_each_i, (VALUE)e);
}
@@ -356,7 +358,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,
enumerator_with_index_i, (VALUE)&memo);
}
Modified: MacRuby/branches/vm-mcache/hash.c
===================================================================
--- MacRuby/branches/vm-mcache/hash.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/hash.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -31,8 +31,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;
@@ -40,7 +38,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, false);
retry:
switch (TYPE(v)) {
case T_FIXNUM:
@@ -437,8 +435,7 @@
&& RHASH(hash)->ifnone == Qnil) {
return Qnil;
}
- return rb_vm_call_with_cache(defaultCache, hash, selDefault,
- 1, &key);
+ return rb_vm_call(hash, selDefault, 1, &key, false);
}
return val;
}
@@ -1768,8 +1765,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/branches/vm-mcache/id.c
===================================================================
--- MacRuby/branches/vm-mcache/id.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/id.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -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/branches/vm-mcache/id.h
===================================================================
--- MacRuby/branches/vm-mcache/id.h 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/id.h 2010-04-14 03:07:29 UTC (rev 3927)
@@ -119,6 +119,5 @@
extern ID idIncludedModules;
extern ID idIncludedInClasses;
extern ID idAncestors;
-extern void *cacheEach;
#endif
#endif /* RUBY_ID_H */
Modified: MacRuby/branches/vm-mcache/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/vm-mcache/include/ruby/ruby.h 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/include/ruby/ruby.h 2010-04-14 03:07:29 UTC (rev 3927)
@@ -967,8 +967,6 @@
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 *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,...);
VALUE rb_ensure(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE);
Modified: MacRuby/branches/vm-mcache/object.c
===================================================================
--- MacRuby/branches/vm-mcache/object.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/object.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -41,18 +41,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
rb_send_dup(VALUE obj)
{
- return rb_vm_call_with_cache(dupCache, obj, selDup, 0, NULL);
+ return rb_vm_call(obj, selDup, 0, NULL, false);
}
/*
@@ -70,7 +63,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, false);
if (RTEST(result)) {
return Qtrue;
}
@@ -86,7 +79,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, false));
}
/*
@@ -147,7 +140,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, false);
return RTEST(result) ? Qfalse : Qtrue;
}
@@ -1932,7 +1925,7 @@
// Fast path!
return rb_robject_allocate_instance(klass);
}
- return rb_vm_call_with_cache(allocCache, klass, selAlloc, 0, NULL);
+ return rb_vm_call(klass, selAlloc, 0, NULL, false);
}
VALUE
@@ -1973,12 +1966,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;
@@ -2987,13 +2978,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/branches/vm-mcache/proc.c
===================================================================
--- MacRuby/branches/vm-mcache/proc.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/proc.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -1063,8 +1063,12 @@
}
}
+ VALUE result = Qnil;
+#if 0
+ // TODO
VALUE result = rb_vm_call_with_cache2(data->cache, NULL, data->recv,
data->oclass, data->sel, argc, argv);
+#endif
if (safe >= 0) {
rb_set_safe_level_force(safe);
Modified: MacRuby/branches/vm-mcache/process.c
===================================================================
--- MacRuby/branches/vm-mcache/process.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/process.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -16,6 +16,8 @@
#include "ruby/io.h"
#include "ruby/util.h"
#include "id.h"
+#include "ruby/node.h"
+#include "vm.h"
#include <stdio.h>
#include <errno.h>
@@ -1819,8 +1821,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/branches/vm-mcache/range.c
===================================================================
--- MacRuby/branches/vm-mcache/range.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/range.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -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])
@@ -371,7 +370,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];
@@ -443,7 +442,7 @@
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);
@@ -515,7 +514,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];
}
@@ -1000,7 +999,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/branches/vm-mcache/vm.cpp
===================================================================
--- MacRuby/branches/vm-mcache/vm.cpp 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/vm.cpp 2010-04-14 03:07:29 UTC (rev 3927)
@@ -345,6 +345,10 @@
return_from_block = -1;
current_super_class = NULL;
current_super_sel = 0;
+
+ mcache = (struct mcache *)malloc(sizeof(struct mcache) * MCACHE_SIZE);
+ assert(mcache != NULL);
+ memset(mcache, 0, sizeof(struct mcache) * MCACHE_SIZE);
}
static inline void *
@@ -406,6 +410,10 @@
throw_exc = NULL;
current_super_class = NULL;
current_super_sel = 0;
+
+ mcache = (struct mcache *)malloc(sizeof(struct mcache) * MCACHE_SIZE);
+ assert(mcache != NULL);
+ memcpy(mcache, vm.mcache, sizeof(struct mcache) * MCACHE_SIZE);
}
RoxorVM::~RoxorVM(void)
@@ -421,6 +429,8 @@
GC_RELEASE(broken_with);
GC_RELEASE(last_status);
GC_RELEASE(errinfo);
+
+ free(mcache);
}
static void
@@ -677,33 +687,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)
{
@@ -875,10 +858,13 @@
void
RoxorCore::invalidate_method_cache(SEL sel)
{
+#if 0 // TODO
std::map<SEL, struct mcache *>::iterator iter = mcache.find(sel);
if (iter != mcache.end()) {
iter->second->flag = 0;
}
+#endif
+ memset(GET_VM()->mcache, 0, sizeof(struct mcache) * MCACHE_SIZE);
}
rb_vm_method_node_t *
@@ -3216,20 +3202,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
@@ -5144,6 +5116,8 @@
rb_define_const(rb_cThGroup, "Default", group);
}
+extern "C" void rb_vm_dispatch_finalize(void);
+
extern "C"
void
rb_vm_finalize(void)
@@ -5158,6 +5132,7 @@
GET_CORE()->get_functions_compiled());
#endif
+ rb_vm_dispatch_finalize();
// XXX: deleting the core is not safe at this point because there might be
// threads still running and trying to unregister.
Modified: MacRuby/branches/vm-mcache/vm.h
===================================================================
--- MacRuby/branches/vm-mcache/vm.h 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/vm.h 2010-04-14 03:07:29 UTC (rev 3927)
@@ -307,11 +307,8 @@
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_call2(rb_vm_block_t *block, VALUE self, VALUE klass, SEL sel,
+ int argc, const VALUE *argv);
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);
@@ -326,6 +323,10 @@
VALUE rb_vm_catch(VALUE tag);
VALUE rb_vm_throw(VALUE tag, VALUE value);
+// TODO defined in vm_eval.c, should be renamed as rb_vm_block_call
+VALUE rb_objc_block_call(VALUE obj, SEL sel, int argc, VALUE *argv,
+ VALUE (*bl_proc) (ANYARGS), VALUE data2);
+
static inline void
rb_vm_regrow_robject_slots(struct RObject *obj, unsigned int new_num_slot)
{
@@ -545,10 +546,12 @@
int argc, const VALUE *argv);
struct mcache {
-#define MCACHE_RCALL 0x1 // Ruby call
-#define MCACHE_OCALL 0x2 // Objective-C call
-#define MCACHE_FCALL 0x4 // C call
+#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;
union {
struct {
Class klass;
@@ -638,8 +641,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;
+ // Constant cache.
std::map<ID, struct ccache *> ccache;
// Instance variable slots cache.
@@ -780,7 +782,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);
@@ -910,6 +911,9 @@
return RoxorVM::main;
}
+#define MCACHE_SIZE 0x1000
+ struct mcache *mcache;
+
private:
// Cache to avoid allocating the same block twice.
std::map<void *, rb_vm_block_t *> blocks;
Modified: MacRuby/branches/vm-mcache/vm_eval.c
===================================================================
--- MacRuby/branches/vm-mcache/vm_eval.c 2010-04-14 03:01:30 UTC (rev 3926)
+++ MacRuby/branches/vm-mcache/vm_eval.c 2010-04-14 03:07:29 UTC (rev 3927)
@@ -40,10 +40,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);
}
/*
@@ -259,14 +257,11 @@
}
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
@@ -282,7 +277,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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100413/c1545416/attachment-0001.html>
More information about the macruby-changes
mailing list