[macruby-changes] [3633] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Feb 26 03:11:55 PST 2010
Revision: 3633
http://trac.macosforge.org/projects/ruby/changeset/3633
Author: martinlagardette at apple.com
Date: 2010-02-26 03:11:53 -0800 (Fri, 26 Feb 2010)
Log Message:
-----------
Allow methods/blocks with 12+ arguments
Methods/Blocks with 0 to 11 arguments are hardcoded for faster response time. Starting 12 arguments, LLVM is used to compile a stub receiving as much arguments as needed, and the stub is then cached for later faster retrieval.
Modified Paths:
--------------
MacRuby/trunk/compiler.cpp
MacRuby/trunk/compiler.h
MacRuby/trunk/dispatcher.cpp
MacRuby/trunk/vm.cpp
MacRuby/trunk/vm.h
Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp 2010-02-26 05:24:06 UTC (rev 3632)
+++ MacRuby/trunk/compiler.cpp 2010-02-26 11:11:53 UTC (rev 3633)
@@ -7023,6 +7023,100 @@
return f;
}
+Function *
+RoxorCompiler::compile_long_arity_stub(int argc, bool is_block)
+{
+ Function *f;
+
+ if (is_block) {
+ // VALUE stubX(IMP imp, VALUE self, SEL sel,
+ // VALUE dvars, rb_vm_block_t *b, int argc, VALUE *argv)
+ // {
+ // return (*imp)(self, sel, dvars, b, argv[0], ..., argv[X - 1]);
+ // }
+ f = cast<Function>(module->getOrInsertFunction("",
+ RubyObjTy,
+ PtrTy, RubyObjTy, PtrTy,
+ RubyObjTy, PtrTy, Int32Ty, RubyObjPtrTy, NULL));
+ }
+ else {
+ // VALUE stubX(IMP imp, VALUE self, SEL sel, int argc, VALUE *argv)
+ // {
+ // return (*imp)(self, sel, argv[0], argv[1], ..., argv[X - 1]);
+ // }
+ f = cast<Function>(module->getOrInsertFunction("",
+ RubyObjTy,
+ PtrTy, RubyObjTy, PtrTy, Int32Ty, RubyObjPtrTy, NULL));
+ }
+
+ bb = BasicBlock::Create(context, "EntryBlock", f);
+
+ Function::arg_iterator arg = f->arg_begin();
+
+ Value *imp_arg = arg++;
+ Value *self_arg = arg++;
+ Value *sel_arg = arg++;
+ Value *dvars_arg;
+ Value *block_arg;
+ if (is_block) {
+ dvars_arg = arg++;
+ block_arg = arg++;
+ }
+ /*Value *argc_arg = */arg++;
+ Value *argv_arg = arg++;
+
+ std::vector<const Type *> f_types;
+ std::vector<Value *> params;
+
+ // Return type
+ const Type *ret_type = RubyObjTy;
+
+ // self
+ f_types.push_back(RubyObjTy);
+ params.push_back(self_arg);
+
+ // sel
+ f_types.push_back(PtrTy);
+ params.push_back(sel_arg);
+
+ if (is_block) {
+ // dvars
+ f_types.push_back(RubyObjTy);
+ params.push_back(dvars_arg);
+
+ // block
+ f_types.push_back(PtrTy);
+ params.push_back(block_arg);
+ }
+
+ for (int i = 0; i < argc; i++) {
+ f_types.push_back(RubyObjTy);
+
+ // Get an int
+ Value *index = ConstantInt::get(Int32Ty, i);
+ // Get the slot (aka argv[index])
+ Value *slot = GetElementPtrInst::Create(argv_arg, index, "", bb);
+ // Load the slot into memory and add it as an argument
+ Value *arg_val = new LoadInst(slot, "", bb);
+ params.push_back(arg_val);
+ }
+
+ // Get the function type, aka: VALUE (*)(VALUE, SEL, ...)
+ FunctionType *ft = FunctionType::get(ret_type, f_types, false);
+ // Cast imp as the function type
+ Value *imp = new BitCastInst(imp_arg, PointerType::getUnqual(ft), "", bb);
+
+ // Compile call to the function
+ CallInst *imp_call = CallInst::Create(imp, params.begin(), params.end(),
+ "", bb);
+
+ // Compile return value
+ Value *retval = imp_call;
+ ReturnInst::Create(context, retval, bb);
+
+ return f;
+}
+
bool
RoxorCompiler::compile_lvars(ID *tbl)
{
Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h 2010-02-26 05:24:06 UTC (rev 3632)
+++ MacRuby/trunk/compiler.h 2010-02-26 11:11:53 UTC (rev 3633)
@@ -48,6 +48,7 @@
Function *compile_write_attr(ID name);
Function *compile_stub(const char *types, bool variadic, int min_argc,
bool is_objc);
+ Function *compile_long_arity_stub(int argc, bool is_block);
Function *compile_bs_struct_new(rb_vm_bs_boxed_t *bs_boxed);
Function *compile_bs_struct_writer(rb_vm_bs_boxed_t *bs_boxed,
int field);
Modified: MacRuby/trunk/dispatcher.cpp
===================================================================
--- MacRuby/trunk/dispatcher.cpp 2010-02-26 05:24:06 UTC (rev 3632)
+++ MacRuby/trunk/dispatcher.cpp 2010-02-26 11:11:53 UTC (rev 3633)
@@ -107,9 +107,13 @@
return (*imp)(self, sel, dvars, b, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
case 9:
return (*imp)(self, sel, dvars, b, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
- }
- printf("invalid argc %d\n", argc);
- abort();
+ }
+
+ rb_vm_long_arity_bstub_t *stub;
+
+ stub = (rb_vm_long_arity_bstub_t *)GET_CORE()->gen_large_arity_stub(argc,
+ true);
+ return (*stub)(pimp, (id)self, sel, dvars, b, argc, argv);
}
static force_inline VALUE
@@ -152,9 +156,12 @@
return (*imp)(self, sel, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
case 11:
return (*imp)(self, sel, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
- }
- printf("invalid argc %d\n", argc);
- abort();
+ }
+
+ rb_vm_long_arity_stub_t *stub;
+
+ stub = (rb_vm_long_arity_stub_t *)GET_CORE()->gen_large_arity_stub(argc);
+ return (*stub)(pimp, (id)self, sel, argc, argv);
}
static void
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2010-02-26 05:24:06 UTC (rev 3632)
+++ MacRuby/trunk/vm.cpp 2010-02-26 11:11:53 UTC (rev 3633)
@@ -2861,6 +2861,28 @@
}
void *
+RoxorCore::gen_large_arity_stub(int argc, bool is_block)
+{
+ lock();
+ std::map<int, void *> &stubs =
+ is_block ? rb_large_arity_bstubs : rb_large_arity_rstubs;
+ std::map<int, void *>::iterator iter = stubs.find(argc);
+ void *stub;
+ if (iter == stubs.end()) {
+ Function *f = RoxorCompiler::shared->compile_long_arity_stub(argc,
+ is_block);
+ stub = (void *)compile(f);
+ stubs.insert(std::make_pair(argc, stub));
+ }
+ else {
+ stub = iter->second;
+ }
+ unlock();
+
+ return stub;
+}
+
+void *
RoxorCore::gen_stub(std::string types, bool variadic, int min_argc,
bool is_objc)
{
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2010-02-26 05:24:06 UTC (rev 3632)
+++ MacRuby/trunk/vm.h 2010-02-26 11:11:53 UTC (rev 3633)
@@ -526,8 +526,11 @@
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);
struct mcache {
#define MCACHE_RCALL 0x1 // Ruby call
@@ -640,6 +643,8 @@
std::map<std::string, void *> c_stubs, objc_stubs,
to_rval_convertors, to_ocval_convertors;
std::map<IMP, IMP> objc_to_ruby_stubs;
+ std::map<int, void *> rb_large_arity_rstubs; // Large arity Ruby calls
+ std::map<int, void *> rb_large_arity_bstubs; // Large arity block calls
// Caches for the lazy JIT.
std::map<SEL, std::map<Class, rb_vm_method_source_t *> *>
@@ -724,6 +729,7 @@
// This callback is public for the only reason it's called by C.
void bs_parse_cb(bs_element_type_t type, void *value, void *ctx);
+ void *gen_large_arity_stub(int argc, bool is_block=false);
void *gen_stub(std::string types, bool variadic, int min_argc,
bool is_objc);
void *gen_to_rval_convertor(std::string type);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100226/81d877bd/attachment.html>
More information about the macruby-changes
mailing list