[#108552] [Ruby master Bug#18782] Race conditions in autoload when loading the same feature with multiple threads. — "ioquatix (Samuel Williams)" <noreply@...>
Issue #18782 has been reported by ioquatix (Samuel Williams).
11 messages
2022/05/14
[ruby-core:108701] [Ruby master Bug#18801] Dead YARV instructions produced when `branchif` is used
From:
"dylants (Dylan Thacker-Smith)" <noreply@...>
Date:
2022-05-25 18:07:42 UTC
List:
ruby-core #108701
Issue #18801 has been updated by dylants (Dylan Thacker-Smith).
Both of those instructions serve a purpose, but they could also be optimized away.
`next_catch_label` is referenced from the catch table. That catch table may be optimized away, which is why you are seeing the label being omitted from the disassembly when `next` is removed. Similarly, the `pop` that follows that label could also be optimized away when the catch table is optimized away, otherwise, it is needed to pop off the value added by the `throw` instruction for a non-local `next` usage (e.g. that test was using it within a class definition block rather than locally within the method).
The `putnil` instruction that precedes `next_catch_label` seems to only be used to adjust the stack depth for that label, to account for the value thrown by `next`. The instruction isn't needed for execution, so it could be replaced by an iseq element that adds an element to the stack without being compiled to an instruction.
Note that `adjust_label` is an example of how the stack depth at a label gets used, where it gets used by the the ADD_ADJUST_RESTORE macro to create an ISEQ_ELEMENT_ADJUST. The ISEQ_ELEMENT_ADJUST also doesn't end up generating any instructions, since the compiler calculates the necessary adjustment to be 0. I don't think the label would ever end up in the disassembly, since it doesn't look like it is used as a jump target.
----------------------------------------
Bug #18801: Dead YARV instructions produced when `branchif` is used
https://bugs.ruby-lang.org/issues/18801#change-97745
* Author: wildmaples (Maple Ong)
* Status: Open
* Priority: Normal
* ruby -v: 3.1.0
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
# Description
It seems there are unused YARV instructions produced when the snippet contains a `branchif` instruction.
In the following example, the instructions numbers 0002 to 0004 won't ever be executed:
```
irb(main):003:0> puts RubyVM::InstructionSequence.compile("while 2+3; puts 'hi'; end").disasm
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,25)> (catch: FALSE)
0000 jump 12 ( 1)[Li]
0002 putnil
0003 pop
0004 jump 12
0006 putself
0007 putstring "hi"
0009 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0011 pop
0012 putobject 2
0014 putobject 3
0016 opt_plus <calldata!mid:+, argc:1, ARGS_SIMPLE>[CcCr]
0018 branchif 6
0020 putnil
0021 leave
```
Similarly in this example, 0006-0008 won't be executed.
```
irb(main):003:0> puts RubyVM::InstructionSequence.compile("x = 9; while x; puts 'hi'; end").disasm
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,30)> (catch: FALSE)
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0
0000 putobject 9 ( 1)[Li]
0002 setlocal_WC_0 x@0
0004 jump 16
0006 putnil
0007 pop
0008 jump 16
0010 putself
0011 putstring "hi"
0013 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0015 pop
0016 getlocal_WC_0 x@0
0018 branchif 10
0020 putnil
0021 leave
```
Initially we thought those instructions (i.e. putnil, pop, jump) were used when the return value of the while-loop is needed.
```
irb(main):012:0> puts RubyVM::InstructionSequence.compile("x = while foo; 9; end").disasm
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,21)> (catch: FALSE)
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0
0000 jump 4 ( 1)[Li]
0002 putnil
0003 pop
0004 putself
0005 opt_send_without_block <calldata!mid:foo, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0007 branchif 4
0009 putnil
0010 dup
0011 setlocal_WC_0 x@0
0013 leave
```
But it seems like some dead instructions (0002, 0003) in the example above still remains.
Are those instructions meant to be used for something else or is it a "bug" that it sticks around?
Perhaps it can be optimized away?
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>