diff options
author | Peter Zhu <[email protected]> | 2023-02-24 09:20:14 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2023-02-24 14:10:09 -0500 |
commit | 3e098224077e8c43a1d8c2070b26ffdfda422780 (patch) | |
tree | ac701b8c89d90f3e6cd632ce22d0713d149ba945 /tool/ruby_vm/views | |
parent | d2631c427ee723f6136ac1e08dd3c9c5b04c6725 (diff) |
Fix incorrect line numbers in GC hook
If the previous instruction is not a leaf instruction, then the PC was
incremented before the instruction was ran (meaning the currently
executing instruction is actually the previous instruction), so we
should not increment the PC otherwise we will calculate the source
line for the next instruction.
This bug can be reproduced in the following script:
```
require "objspace"
ObjectSpace.trace_object_allocations_start
a =
1.0 / 0.0
p [ObjectSpace.allocation_sourceline(a), ObjectSpace.allocation_sourcefile(a)]
```
Which outputs: [4, "test.rb"]
This is incorrect because the object was allocated on line 10 and not
line 4. The behaviour is correct when we use a leaf instruction (e.g.
if we replaced `1.0 / 0.0` with `"hello"`), then the output is:
[10, "test.rb"].
[Bug #19456]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7357
Diffstat (limited to 'tool/ruby_vm/views')
-rw-r--r-- | tool/ruby_vm/views/_leaf_helpers.erb | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/tool/ruby_vm/views/_leaf_helpers.erb b/tool/ruby_vm/views/_leaf_helpers.erb index 1735db2196..ed2b5dec49 100644 --- a/tool/ruby_vm/views/_leaf_helpers.erb +++ b/tool/ruby_vm/views/_leaf_helpers.erb @@ -10,6 +10,31 @@ #include "iseq.h" +extern const bool rb_vm_insn_leaf_p[]; + +#ifdef RUBY_VM_INSNS_INFO +const bool rb_vm_insn_leaf_p[] = { +% RubyVM::Instructions.each_slice(20) do |insns| + <%= insns.map do |insn| + if insn.is_a?(RubyVM::BareInstructions) + insn.always_leaf? ? '1' : '0' + else + '0' + end + end.join(', ') + %>, +% end +}; +#endif + +CONSTFUNC(MAYBE_UNUSED(static bool insn_leaf_p(VALUE insn))); + +bool +insn_leaf_p(VALUE insn) +{ + return rb_vm_insn_leaf_p[insn]; +} + // This is used to tell MJIT that this insn would be leaf if CHECK_INTS didn't exist. // It should be used only when RUBY_VM_CHECK_INTS is directly written in insns.def. static bool leafness_of_check_ints = false; |