[前][次][番号順一覧][スレッド一覧]

ruby-changes:1751

From: ko1@a...
Date: 23 Aug 2007 20:32:30 +0900
Subject: [ruby-changes:1751] ko1 - Ruby:r13242 (trunk): * compile.c: optimize simple massign.

ko1	2007-08-23 20:32:21 +0900 (Thu, 23 Aug 2007)

  New Revision: 13242

  Modified files:
    trunk/ChangeLog
    trunk/compile.c

  Log:
    * compile.c: optimize simple massign.
    


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/compile.c?r1=13242&r2=13241
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13242&r2=13241

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 13241)
+++ ChangeLog	(revision 13242)
@@ -1,3 +1,7 @@
+Thu Aug 23 20:31:31 2007  Koichi Sasada  <ko1@a...>
+
+	* compile.c: optimize simple massign.
+
 Thu Aug 23 20:02:25 2007  Masaki Suketa  <masaki.suketa@n...>
 
 	* ext/win32ole/win32ole.c (reg_get_value): use RegQueryValueEx instead
Index: compile.c
===================================================================
--- compile.c	(revision 13241)
+++ compile.c	(revision 13242)
@@ -190,7 +190,6 @@
 	  case ISEQ_TYPE_BLOCK:
 	  case ISEQ_TYPE_EVAL:
 	  case ISEQ_TYPE_TOP:
-	    dpn(node);
 	    rb_compile_error(ERROR_ARGS "compile/should not be reached: %s:%d",
 			     __FILE__, __LINE__);
 	    break;
@@ -1979,18 +1978,92 @@
 	DECL_ANCHOR(anchor);
 	INIT_ANCHOR(anchor);
 	COMPILE_POPED(anchor, "masgn lhs", node);
-	/* dump_disasm_list(FIRST_ELEMENT(anchor)); */
 	REMOVE_ELEM(FIRST_ELEMENT(anchor));
-	/* dump_disasm_list(FIRST_ELEMENT(anchor)); */
 	ADD_SEQ(ret, anchor);
-	/* ADD_ELEM(ret, LAST_ELEMENT(anchor)); */
       }
     }
 
     return COMPILE_OK;
 }
 
+static void
+compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *lhsn)
+{
+    if (lhsn) {
+	compile_massign_opt_lhs(iseq, ret, lhsn->nd_next);
+	compile_massign_lhs(iseq, ret, lhsn->nd_head);
+    }
+}
+
 static int
+compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *ret,
+		    NODE *rhsn, NODE *orig_lhsn)
+{
+    int memsize = 64;
+    int memindex = 0;
+    VALUE *mem = ALLOCA_N(VALUE, memsize);
+    int llen = 0, rlen = 0;
+    int i;
+    NODE *lhsn = orig_lhsn;
+
+#define MEMORY(v) { \
+    int i; \
+    if (memindex == memsize) return 0; \
+    for (i=0; i<memindex; i++) { \
+	if (mem[i] == (v)) return 0; \
+    } \
+    mem[memindex++] = (v); \
+}
+
+    if (rhsn == 0 || nd_type(rhsn) != NODE_ARRAY) {
+	return 0;
+    }
+
+    while (lhsn) {
+	NODE *ln = lhsn->nd_head;
+	switch (nd_type(ln)) {
+	  case NODE_LASGN:
+	    MEMORY(ln->nd_vid);
+	    break;
+	  case NODE_DASGN:
+	  case NODE_DASGN_CURR:
+	  case NODE_IASGN:
+	  case NODE_IASGN2:
+	  case NODE_CVASGN:
+	    MEMORY(ln->nd_vid);
+	    break;
+	  case NODE_GASGN:
+	    MEMORY((VALUE)ln->nd_entry);
+	    break;
+	  default:
+	    return 0;
+	}
+	lhsn = lhsn->nd_next;
+	llen++;
+    }
+
+    while (rhsn) {
+	if (llen <= rlen) {
+	    COMPILE_POPED(ret, "masgn val (poped)", rhsn->nd_head);
+	}
+	else {
+	    COMPILE(ret, "masgn val", rhsn->nd_head);
+	}
+	rhsn = rhsn->nd_next;
+	rlen++;
+    }
+
+    if (llen > rlen) {
+	for (i=0; i<llen-rlen; i++) {
+	    ADD_INSN(ret, nd_line(orig_lhsn), putnil);
+	}
+    }
+
+    compile_massign_opt_lhs(iseq, ret, orig_lhsn);
+    return 1;
+}
+
+static int
 compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped)
 {
     NODE *rhsn = node->nd_value;
@@ -1998,13 +2071,10 @@
     NODE *lhsn = node->nd_head;
     int lhs_splat = (splatn && (VALUE)splatn != (VALUE)-1) ? 1 : 0;
 
-    if (!poped && 0) {
-	/* optimized one */
-	/*compile_massign_opt(iseq, ret, rhsn, splatn, lhsn, llen);*/
-    }
-    else {
+    if (!poped || splatn || !compile_massign_opt(iseq, ret, rhsn, lhsn)) {
+	int llen = 0;
 	DECL_ANCHOR(lhsseq);
-	int llen = 0;
+
 	INIT_ANCHOR(lhsseq);
 
 	while (lhsn) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]