diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-23 07:10:56 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-23 07:10:56 +0000 |
commit | e39eb9dab50eaa681467e51145b37cdc11667830 (patch) | |
tree | b0b1e300f1105da8124013b71adab030b9182ee8 /compile.c | |
parent | ac41d2774982fcf6f297e71c3e1209a650e44ce7 (diff) | |
download | ruby-e39eb9dab50eaa681467e51145b37cdc11667830.tar.gz |
* compile.c, insns.def, parse.y: fix massign order. This change
causes performance problem. Try vm1_swap benchmark.
[ruby-dev:31522]
* insns.def, insnhelper.ci: move process body of expandarray insn to
vm_expandarray().
* bootstraptest/test_knownbug.rb, bootstraptest/test_massign.rb:
move a solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 161 |
1 files changed, 45 insertions, 116 deletions
@@ -1946,7 +1946,7 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, VALUE s } static int -make_masgn_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) +compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) { switch (nd_type(node)) { case NODE_ATTRASGN: { @@ -1968,7 +1968,11 @@ make_masgn_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) break; } case NODE_MASGN: { - COMPILE_POPED(ret, "nest masgn lhs", node); + DECL_ANCHOR(anchor); + INIT_ANCHOR(anchor); + COMPILE_POPED(anchor, "nest masgn lhs", node); + REMOVE_ELEM(FIRST_ELEMENT(anchor)); + ADD_SEQ(ret, anchor); break; } default: { @@ -1987,123 +1991,60 @@ make_masgn_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) } static int -compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, - NODE *rhsn, NODE *splatn, NODE *lhsn, int llen) +compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) { - if (lhsn != 0) { - compile_massign(iseq, ret, rhsn, splatn, lhsn->nd_next, llen + 1); - make_masgn_lhs(iseq, ret, lhsn->nd_head); + NODE *rhsn = node->nd_value; + NODE *splatn = node->nd_args; + 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 { - int lhs_splat = 0; - - if (splatn && (VALUE)splatn != -1) { - lhs_splat = 1; - } - - if (rhsn) { - switch (nd_type(rhsn)) { - case NODE_ARRAY:{ - int rlen = rhsn->nd_alen; - int max = rlen > llen ? rlen : llen; - int i, si = 0; - int rline = nd_line(rhsn); - - for (i = 0; i < max; i++) { - if (i < rlen && i < llen) { - /* a, b = c, d */ - COMPILE(ret, "masgn val1", rhsn->nd_head); - rline = nd_line(rhsn); - rhsn = rhsn->nd_next; - } - else if (i < rlen) { - if (lhs_splat) { - while (rhsn) { - /* a, *b = x, y, z */ - si++; - COMPILE(ret, "masgn rhs for lhs splat", - rhsn->nd_head); - rline = nd_line(rhsn); - rhsn = rhsn->nd_next; - } - break; - } - else { - /* a, b = c, d, e */ - COMPILE_POPED(ret, "masgn rhs (popped)", - rhsn->nd_head); - rhsn = rhsn->nd_next; - } - } - else if (i < llen) { - /* a, b, c = c, d */ - ADD_INSN(ret, rline, putnil); - } - } + DECL_ANCHOR(lhsseq); + int llen = 0; + INIT_ANCHOR(lhsseq); - if (lhs_splat) { - ADD_INSN1(ret, rline, newarray, INT2FIX(si)); - } - break; - } - case NODE_TO_ARY: - COMPILE(ret, "rhs to ary", rhsn->nd_head); - ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen), - INT2FIX(lhs_splat)); - break; - - case NODE_SPLAT: - COMPILE(ret, "rhs to ary (splat)", rhsn); - ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen), INT2FIX(lhs_splat)); - break; + while (lhsn) { + compile_massign_lhs(iseq, lhsseq, lhsn->nd_head); + llen += 1; + lhsn = lhsn->nd_next; + } - case NODE_ARGSCAT: - COMPILE(ret, "rhs to argscat", rhsn); - ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen), INT2FIX(lhs_splat)); - break; + COMPILE(ret, "normal masgn rhs", rhsn); - default: - COMPILE(ret, "rhs to ary (splat/default)", rhsn); - ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen), INT2FIX(lhs_splat)); - } - } - else { - /* nested massign */ - ADD_INSN2(ret, 0, expandarray, INT2FIX(llen), INT2FIX(lhs_splat)); + if (!poped) { + ADD_INSN(ret, nd_line(node), dup); } + ADD_INSN2(ret, nd_line(node), expandarray, + INT2FIX(llen), INT2FIX(lhs_splat)); + ADD_SEQ(ret, lhsseq); + if (lhs_splat) { if (nd_type(splatn) == NODE_POSTARG) { - NODE *n = splatn->nd_2nd; - int num = n->nd_alen; - - ADD_INSN (ret, nd_line(n), dup); - ADD_INSN2(ret, nd_line(n), expandarray, INT2FIX(num), INT2FIX(2)); + /*a, b, *r, p1, p2 */ + NODE *postn = splatn->nd_2nd; + NODE *restn = splatn->nd_1st; + int num = postn->nd_alen; + int flag = 0x02 | (((VALUE)restn == (VALUE)-1) ? 0x00 : 0x01); - while (n) { - DECL_ANCHOR(lhs); + ADD_INSN2(ret, nd_line(splatn), expandarray, + INT2FIX(num), INT2FIX(flag)); - INIT_ANCHOR(lhs); - COMPILE_POPED(lhs, "post", n->nd_head); - - if (nd_type(n->nd_head) != NODE_MASGN) { - REMOVE_ELEM(FIRST_ELEMENT(lhs)); - } - - ADD_SEQ(ret, lhs); - n = n->nd_next; + if ((VALUE)restn != (VALUE)-1) { + compile_massign_lhs(iseq, ret, restn); } - - if (splatn->nd_1st == (NODE*)(VALUE)-1) { - /* v1, *, v2 = expr */ - ADD_INSN(ret, nd_line(splatn), pop); - } - else { - make_masgn_lhs(iseq, ret, splatn->nd_1st); + while (postn) { + compile_massign_lhs(iseq, ret, postn->nd_head); + postn = postn->nd_next; } } else { - make_masgn_lhs(iseq, ret, splatn); + /* a, b, *r */ + compile_massign_lhs(iseq, ret, splatn); } } } @@ -3204,19 +3145,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) } case NODE_MASGN:{ - if (poped) { - compile_massign(iseq, ret, - node->nd_value, /* rhsn */ - node->nd_args, /* splat */ - node->nd_head, /* lhsn */ - 0); - } - else { - COMPILE(ret, "masgn/value", node->nd_value); - ADD_INSN(ret, nd_line(node), dup); - compile_massign(iseq, ret, 0, - node->nd_args, node->nd_head, 0); - } + compile_massign(iseq, ret, node, poped); break; } |