From cbdf5a1842cda89347a2c840d23c35f041aead68 Mon Sep 17 00:00:00 2001 From: tenderlove Date: Fri, 30 Nov 2018 23:58:13 +0000 Subject: Collapse putobject, putobject, newarray This collapses: ``` == disasm: # (catch: FALSE) 0000 putobject "a" ( 4)[LiCa] 0002 putobject "b" 0004 putobject "c" 0006 putobject "d" 0008 putobject "e" 0010 putobject "f" 0012 putobject "g" 0014 putobject "h" 0016 putobject "i" 0018 putobject "j" 0020 putobject "k" 0022 newarray 11 0024 leave ( 5)[Re] ``` In to this: ``` == disasm: # (catch: FALSE) 0000 duparray ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]( 4)[LiCa] 0002 leave ( 5)[Re] ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66106 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- compile.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'compile.c') diff --git a/compile.c b/compile.c index 32606e955b..bd38573039 100644 --- a/compile.c +++ b/compile.c @@ -2823,6 +2823,53 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal } } + /* + * putobject "foo" + * putobject "bar" + * newarray 2 + * + * ==> + * + * duparray ["foo", "bar"] + */ + if (IS_INSN_ID(iobj, newarray)) { + int len; + + len = NUM2INT(OPERAND_AT(iobj, 0)); + + if (len > 0) { + INSN *link; + INSN *cur; + int i; + + link = iobj; + i = len; + while(i > 0) { + link = (INSN *)get_prev_insn(link); + if (!IS_INSN_ID(link, putobject)) + break; + + i--; + } + + /* All previous instructions were `putobject` */ + if (i == 0) { + VALUE list = rb_ary_new_capa(len); + iseq_add_mark_object_compile_time(iseq, list); + + while(i < len) { + cur = link; + rb_ary_push(list, OPERAND_AT(cur, 0)); + link = (INSN *)get_next_insn(link); + ELEM_REMOVE(&cur->link); + i++; + } + iobj->insn_id = BIN(duparray); + OPERAND_AT(iobj, 0) = list; + } + } + } + if (IS_INSN_ID(iobj, leave)) { remove_unreachable_chunk(iseq, iobj->link.next); } -- cgit v1.2.3