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