Bug #16139
closedsetinstancevariable on MJIT may not check frozen flag
Description
class A
def a
@a = 1
end
end
a = A.new
a.a
a.a
a.a
a.freeze
a.a
without JIT¶
$ ruby --disable-gems a.rb
Traceback (most recent call last):
1: from a.rb:12:in `<main>'
a.rb:3:in `a': can't modify frozen A: #<A:0x00005601af0b0430 @a=1> (FrozenError)
with JIT¶
$ ruby --disable-gems --jit-min-calls=3 --jit-wait a.rb
(no error)
Updated by k0kubun (Takashi Kokubun) over 5 years ago
- Status changed from Open to Closed
Applied in changeset git|c14b67b2a8cf60b37cfb221d8b97c6eb91833522.
Check frozen flag on MJIT setinstancevariable
It does not seem to have a significant performance impact, hopefully?
$ benchmark-driver -v benchmark.yml --rbenv 'before --jit;after --jit' --repeat-count=24 --output=all
before --jit: ruby 2.7.0dev (2019-09-03T21:02:24Z master 77596fb7a9) +JIT [x86_64-linux]
after --jit: ruby 2.7.0dev (2019-09-04T01:54:44Z master 7363e22d79) +JIT [x86_64-linux]
Calculating -------------------------------------
before --jit after --jit
Optcarrot Lan_Master.nes 48.44054595799523 71.67010255902900 fps
71.32797692837639 71.97846863769546
72.51921961607691 78.87360980544105
73.54082925611047 79.80408132389941
74.03503843709451 79.85739528572826
74.04863857926493 79.89850834901381
75.30266276129467 80.34607233076015
75.69063990896244 80.88474397425360
75.70458132587405 81.09234267781642
77.39842764662852 82.13766823612643
77.76922944068329 82.20398304840373
81.17984044023393 82.26722630628272
82.85235776076533 82.71375902781254
83.04906099135320 82.75893420702198
83.10214168136230 82.79668965325972
83.71456007558125 82.85131667916379
84.06658306760725 82.95676565411722
84.25690684305728 83.19972846225775
84.27938663923503 83.28510503845854
84.45467716218090 83.41003730434703
84.51563186125925 83.67773614721280
84.56139892968321 84.02082201151110
84.69819452180658 84.10495346787033
84.78125989622576 84.47867803506055
Note for backporter:
test_jit's success_count
would be 1 in Ruby 2.6, since 2.7 introduced
"MJIT recompile" on JIT-ed code cancel.
[Bug #16139]
Updated by nagachika (Tomoyuki Chikanaga) almost 5 years ago
I'd like to backport c14b67b2a8cf60b37cfb221d8b97c6eb91833522 into ruby_2_6 branch, but I got the following test failure with the changeset.
1) Failure:
TestJIT#test_inlined_setivar_frozen [/Users/nagachika/opt/ruby-2.6/src/ruby_2_6/test/ruby/test_jit.rb:701]:
Expected 2 times of JIT success, but succeeded 1 times.
script:
class A
def a
@a = 1
end
end
a = A.new
a.a
a.a
a.a
a.freeze
begin
a.a
rescue FrozenError => e
p e.class
end
stderr:
JIT success (179.3ms): a@-e:3 -> /var/folders/r1/f0zrvz7j1g13ctyj83wh_dcw0000gn/T//_ruby_mjit_p27759u0.c
Successful MJIT finish
.
<2> expected but was
<1>.
But the issue seems be fixed with reproduction script shown in description.
$ ./ruby -v --disable-gems --jit-min-calls=3 --jit-wait a.rb
ruby 2.6.6p134 (2020-03-18 revision 67845) +JIT [x86_64-darwin18]
Traceback (most recent call last):
1: from a.rb:12:in `<main>'
a.rb:3:in `a': can't modify frozen A (FrozenError)
Should I just change the parameter for assert_eval_with_jit with succesess_count: 1
instead of 2?
kokubun-san could you take a look into it?
Updated by k0kubun (Takashi Kokubun) almost 5 years ago
As my previous comment https://bugs.ruby-lang.org/issues/16139#note-1 says:
Note for backporter:
test_jit's success_count would be 1 in Ruby 2.6, since 2.7 introduced
"MJIT recompile" on JIT-ed code cancel.
Changing it to successes_count: 1
seems fine.
Updated by nagachika (Tomoyuki Chikanaga) almost 5 years ago
As my previous comment https://bugs.ruby-lang.org/issues/16139#note-1 says:
Ah! I overlooked it.
Thank you!
Updated by nagachika (Tomoyuki Chikanaga) almost 5 years ago
- Backport changed from 2.5: DONTNEED, 2.6: REQUIRED to 2.5: DONTNEED, 2.6: DONE
ruby_2_6 r67846 merged revision(s) c14b67b2a8cf60b37cfb221d8b97c6eb91833522.