[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 *> &params);
-	Value *compile_when_splat_call(std::vector<Value *> &params);
+	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 *> &params);
@@ -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 *> &params)
+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