summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2021-01-26 15:49:21 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2021-02-16 14:00:36 -0800
commit938e027cdf019ff2cb6ee8a7229e6d9a4d8fc953 (patch)
treef4d9b768659b56f12118fbfefc7cff9f958170f9 /compile.c
parent296a2cab07ce530809ee74dee61180fbb3ca6f91 (diff)
downloadruby-938e027cdf019ff2cb6ee8a7229e6d9a4d8fc953.tar.gz
Eliminate useless catch tables and nops from lambdas
Before this commit: ``` $ ruby --dump=insn -e '1.times { |x| puts x }' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,22)> (catch: FALSE) == catch table | catch type: break st: 0000 ed: 0004 sp: 0000 cont: 0004 | == disasm: #<ISeq:block in <main>@-e:1 (1,8)-(1,22)> (catch: FALSE) | == catch table | | catch type: redo st: 0001 ed: 0006 sp: 0000 cont: 0001 | | catch type: next st: 0001 ed: 0006 sp: 0000 cont: 0006 | |------------------------------------------------------------------------ | local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) | [ 1] x@0<Arg> | 0000 nop ( 1)[Bc] | 0001 putself [Li] | 0002 getlocal_WC_0 x@0 | 0004 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE> | 0006 leave [Br] |------------------------------------------------------------------------ 0000 putobject_INT2FIX_1_ ( 1)[Li] 0001 send <calldata!mid:times, argc:0>, block in <main> 0004 leave ``` After this commit: ``` > ruby --dump=insn -e '1.times { |x| puts x }' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,22)> (catch: FALSE) 0000 putobject_INT2FIX_1_ ( 1)[Li] 0001 send <calldata!mid:times, argc:0>, block in <main> 0004 leave == disasm: #<ISeq:block in <main>@-e:1 (1,8)-(1,22)> (catch: FALSE) local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] x@0<Arg> 0000 putself ( 1)[LiBc] 0001 getlocal_WC_0 x@0 0003 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE> 0005 leave ``` Fixes [ruby-core:102418] [Feature #17613] Co-Authored-By: Alan Wu <XrXr@users.noreply.github.com>
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 81ed8fd284..ee6897e9e7 100644
--- a/compile.c
+++ b/compile.c
@@ -1497,6 +1497,12 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
debugs("[compile step 6 (update_catch_except_flags)] \n");
update_catch_except_flags(iseq->body);
+ debugs("[compile step 6.1 (remove unused catch tables)] \n");
+ if (!iseq->body->catch_except_p && iseq->body->catch_table) {
+ xfree(iseq->body->catch_table);
+ iseq->body->catch_table = NULL;
+ }
+
#if VM_INSN_INFO_TABLE_IMPL == 2
if (iseq->body->insns_info.succ_index_table == NULL) {
debugs("[compile step 7 (rb_iseq_insns_info_encode_positions)] \n");
@@ -3525,6 +3531,12 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
list = FIRST_ELEMENT(anchor);
+ int do_block_optimization = 0;
+
+ if (iseq->body->type == ISEQ_TYPE_BLOCK && !iseq->body->catch_except_p) {
+ do_block_optimization = 1;
+ }
+
while (list) {
if (IS_INSN(list)) {
if (do_peepholeopt) {
@@ -3536,6 +3548,13 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
if (do_ou) {
insn_operands_unification((INSN *)list);
}
+
+ if (do_block_optimization) {
+ INSN * item = (INSN *)list;
+ if (IS_INSN_ID(item, jump)) {
+ do_block_optimization = 0;
+ }
+ }
}
if (IS_LABEL(list)) {
switch (((LABEL *)list)->rescued) {
@@ -3550,6 +3569,13 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
}
list = list->next;
}
+
+ if (do_block_optimization) {
+ LINK_ELEMENT * le = FIRST_ELEMENT(anchor)->next;
+ if (IS_INSN(le) && IS_INSN_ID((INSN *)le, nop)) {
+ ELEM_REMOVE(le);
+ }
+ }
return COMPILE_OK;
}