[macruby-changes] [904] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Fri Mar 13 15:59:41 PDT 2009
Revision: 904
http://trac.macosforge.org/projects/ruby/changeset/904
Author: vincent.isambart at gmail.com
Date: 2009-03-13 15:59:41 -0700 (Fri, 13 Mar 2009)
Log Message:
-----------
Cleaned up case and made it faster in a few cases
Modified Paths:
--------------
MacRuby/branches/experimental/include/ruby/intern.h
MacRuby/branches/experimental/re.c
MacRuby/branches/experimental/roxor.cpp
Modified: MacRuby/branches/experimental/include/ruby/intern.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/intern.h 2009-03-13 05:56:06 UTC (rev 903)
+++ MacRuby/branches/experimental/include/ruby/intern.h 2009-03-13 22:59:41 UTC (rev 904)
@@ -507,6 +507,7 @@
VALUE rb_reg_new(const char *, long, int);
VALUE rb_reg_match(VALUE, VALUE);
int rb_reg_options(VALUE);
+VALUE rb_reg_eqq(VALUE, SEL, VALUE);
void rb_set_kcode(const char*);
const char* rb_get_kcode(void);
/* ruby.c */
Modified: MacRuby/branches/experimental/re.c
===================================================================
--- MacRuby/branches/experimental/re.c 2009-03-13 05:56:06 UTC (rev 903)
+++ MacRuby/branches/experimental/re.c 2009-03-13 22:59:41 UTC (rev 904)
@@ -2745,7 +2745,7 @@
* Upper case
*/
-static VALUE
+VALUE
rb_reg_eqq(VALUE re, SEL sel, VALUE str)
{
long start;
Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp 2009-03-13 05:56:06 UTC (rev 903)
+++ MacRuby/branches/experimental/roxor.cpp 2009-03-13 22:59:41 UTC (rev 904)
@@ -211,6 +211,7 @@
Value *current_loop_exit_val;
Function *dispatcherFunc;
+ Function *fastEqqFunc;
Function *whenSplatFunc;
Function *blockCreateFunc;
Function *getBlockFunc;
@@ -278,9 +279,10 @@
NODE *node);
void compile_boolean_test(Value *condVal, BasicBlock *ifTrueBB, BasicBlock *ifFalseBB);
void compile_when_arguments(NODE *args, Value *comparedToVal, BasicBlock *thenBB);
- void compile_one_when_argument(NODE *arg, Value *comparedToVal, BasicBlock *thenBB);
+ void compile_single_when_argument(NODE *arg, Value *comparedToVal, BasicBlock *thenBB);
Value *compile_dispatch_call(std::vector<Value *> ¶ms);
- Value *compile_when_splat_call(std::vector<Value *> ¶ms);
+ Value *compile_when_splat(Value *comparedToVal, Value *splatVal);
+ Value *compile_fast_eqq_call(Value *selfVal, Value *comparedToVal);
Value *compile_attribute_assign(NODE *node, Value *extra_val);
Value *compile_block_create(NODE *node=NULL);
Value *compile_optimized_dispatch_call(SEL sel, int argc, std::vector<Value *> ¶ms);
@@ -642,7 +644,7 @@
}
void
-RoxorCompiler::compile_one_when_argument(NODE *arg, Value *comparedToVal, BasicBlock *thenBB)
+RoxorCompiler::compile_single_when_argument(NODE *arg, Value *comparedToVal, BasicBlock *thenBB)
{
Value *subnodeVal = compile_node(arg);
Value *condVal;
@@ -691,23 +693,14 @@
switch (nd_type(args)) {
case NODE_ARRAY:
while (args != NULL) {
- compile_one_when_argument(args->nd_head, comparedToVal, thenBB);
+ compile_single_when_argument(args->nd_head, comparedToVal, thenBB);
args = args->nd_next;
}
break;
- case NODE_ARGSCAT:
- compile_when_arguments(args->nd_head, comparedToVal, thenBB);
- args = args->nd_body;
-
case NODE_SPLAT:
{
- void *eqq_cache = GET_VM()->method_cache_get(selEqq, false);
- std::vector<Value *> params;
- params.push_back(compile_const_pointer(eqq_cache));
- params.push_back(comparedToVal);
- params.push_back(compile_node(args->nd_head));
- Value *condVal = compile_when_splat_call(params);
+ Value *condVal = compile_when_splat(comparedToVal, compile_node(args->nd_head));
BasicBlock *nextTestBB = BasicBlock::Create("next_test", bb->getParent());
compile_boolean_test(condVal, thenBB, nextTestBB);
@@ -718,9 +711,14 @@
case NODE_ARGSPUSH:
compile_when_arguments(args->nd_head, comparedToVal, thenBB);
- compile_one_when_argument(args->nd_body, comparedToVal, thenBB);
+ compile_single_when_argument(args->nd_body, comparedToVal, thenBB);
break;
+ case NODE_ARGSCAT:
+ compile_when_arguments(args->nd_head, comparedToVal, thenBB);
+ compile_when_arguments(args->nd_body, comparedToVal, thenBB);
+ break;
+
default:
compile_node_error("unrecognized when arg node", args);
}
@@ -799,8 +797,28 @@
}
Value *
-RoxorCompiler::compile_when_splat_call(std::vector<Value *> ¶ms)
+RoxorCompiler::compile_fast_eqq_call(Value *selfVal, Value *comparedToVal)
{
+ if (fastEqqFunc == NULL) {
+ // VALUE rb_vm_fast_eqq(struct mcache *cache, VALUE left, VALUE right)
+ fastEqqFunc = cast<Function>
+ (module->getOrInsertFunction("rb_vm_fast_eqq",
+ RubyObjTy, PtrTy, RubyObjTy, RubyObjTy, NULL));
+ }
+
+ void *eqq_cache = GET_VM()->method_cache_get(selEqq, false);
+
+ std::vector<Value *> params;
+ params.push_back(compile_const_pointer(eqq_cache));
+ params.push_back(selfVal);
+ params.push_back(comparedToVal);
+
+ return compile_protected_call(fastEqqFunc, params);
+}
+
+Value *
+RoxorCompiler::compile_when_splat(Value *comparedToVal, Value *splatVal)
+{
if (whenSplatFunc == NULL) {
// VALUE rb_vm_when_splat(struct mcache *cache, VALUE comparedTo, VALUE splat)
whenSplatFunc = cast<Function>
@@ -808,6 +826,12 @@
RubyObjTy, PtrTy, RubyObjTy, RubyObjTy, NULL));
}
+ void *eqq_cache = GET_VM()->method_cache_get(selEqq, false);
+ std::vector<Value *> params;
+ params.push_back(compile_const_pointer(eqq_cache));
+ params.push_back(comparedToVal);
+ params.push_back(splatVal);
+
return compile_protected_call(whenSplatFunc, params);
}
@@ -1343,9 +1367,21 @@
else {
areFixnums = new ICmpInst(ICmpInst::ICMP_EQ, rightAndOp, oneVal, "", bb);
}
-
- BranchInst::Create(then2BB, elseBB, areFixnums, bb);
-
+
+ Value *fastEqqVal = NULL;
+ BasicBlock *fastEqqBB = NULL;
+ if (sel == selEqq) {
+ // compile_fast_eqq_call won't be called if #=== has been redefined
+ // fixnum optimizations are done separately
+ fastEqqBB = BasicBlock::Create("fast_eqq", f);
+ BranchInst::Create(then2BB, fastEqqBB, areFixnums, bb);
+ bb = fastEqqBB;
+ fastEqqVal = compile_fast_eqq_call(leftVal, rightVal);
+ BranchInst::Create(mergeBB, bb);
+ }
+ else {
+ BranchInst::Create(then2BB, elseBB, areFixnums, bb);
+ }
bb = then2BB;
Value *unboxedLeft;
@@ -1446,6 +1482,10 @@
pn->addIncoming(thenVal, then3BB);
pn->addIncoming(elseVal, elseBB);
+ if (sel == selEqq) {
+ pn->addIncoming(fastEqqVal, fastEqqBB);
+ }
+
return pn;
}
}
@@ -4469,10 +4509,31 @@
extern "C"
VALUE
-rb_vm_fast_eqq(struct mcache *cache, VALUE left, VALUE right)
+rb_vm_fast_eqq(struct mcache *cache, VALUE self, VALUE comparedTo)
{
- // TODO: manual dispatch for Fixnum, Regexp, Range if === not redefined
- return rb_vm_dispatch(cache, left, selEqq, NULL, 0, 1, right);
+ // This function does not check if === has been or not redefined
+ // so it should only been called by code generated by compile_optimized_dispatch_call.
+ // Fixnums are already tested in compile_optimized_dispatch_call
+ switch (TYPE(self)) {
+ // TODO: Range
+ case T_STRING:
+ if (self == comparedTo)
+ return Qtrue;
+ return rb_str_equal(self, comparedTo);
+
+ case T_REGEXP:
+ return rb_reg_eqq(self, selEqq, comparedTo);
+
+ case T_SYMBOL:
+ return (self == comparedTo ? Qtrue : Qfalse);
+
+ case T_MODULE:
+ case T_CLASS:
+ return rb_obj_is_kind_of(comparedTo, self);
+
+ default:
+ return rb_vm_dispatch(cache, self, selEqq, NULL, 0, 1, comparedTo);
+ }
}
extern "C"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090313/b7ac1622/attachment.html>
More information about the macruby-changes
mailing list