-
-
Notifications
You must be signed in to change notification settings - Fork 925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Code behavior changes after being JITted at runtime #4425
Comments
I have tried with some other JRuby releases, and the problem seems to have been introduced in version 9.1.0.0. |
You could help confirm it's the JIT by running with Your guess that it happens after the 52nd row is not far off; the JIT normally fires at 50 invocations, but it does so on a background thread. So it's reasonable to assume that it wasn't until the 53rd row that the jitted code is actually installed. |
Condensed version: BIG_ARRAY = (0...1).to_a
def foo
col = 0
lamb = ->(a, b) do
col += 1
p col
end
BIG_ARRAY.each_with_index do |a, i|
col = 0
lamb[a, i]
col += 1
puts "HERE"
lamb[a, i]
end
end
foo This does not occur after 50 times because we will compile the entire main script file by default. col reads look like they read from inner col and writes go to outer col (whereas lambda access to col I think is fine). Pretty weird. IR Dump time. |
ok OptDynScopePass is busted: Before that pass:
After:
So you can see the variables a and i end up become temps and col reduce its depth by one. It eliminated the scope. However, for this to be broken we must still be pushing a scope... |
Ok my debugging output is lying to me. I still have not quite figured this out but we are seeing full build output and if you look at this line in both:
You can see col(0:0) = 0 is propagating the 0 to this call and it definitely cannot do that because col might be modified by the lambda :) |
@subbuss I reverted your commit from June!!! Amazing we have not seen this reported before. Basic issue I think is that dataflow barrier was not considering localvariables properly since they can be changed in any call (we were prop'ing 0 from a captured lvar but a closure was modifying that lvar between the init and where it got propd to). I will leave it to you do reapply a better fix (or talk to me about how you think we should fix this). |
I can confirm that it works well now when using master. Thanks for looking into this and fixing it so quickly! |
Hi, I'm having a strange issue while upgrading an old Rails application to JRuby 9.1.6.0 (latest released version, installed using rvm).
I have a long-running excel-export that used to work without issues under 1.7 (it uses apache POI to write an Excel file).
Using 9.1.6.0, part of the code seems to be JIT-compiled after writing 52 rows to the excel file (at least, that's what I suspect). As of row 53, the code behavior changes causing some columns not to be exported any longer. If I run the export a second time, the problem occurs from the start (i.e. as of row 1).
When I disable the JIT compiler (using
JRUBY_OPTS= -J-Djruby.compile.mode=OFF
in.ruby-env
) the problem disappears entirely, and the export works correctly for all rows and it keeps working when running it again.Environment
jruby -v
:jruby 9.1.6.0 (2.3.1) 2016-11-09 0150a76 OpenJDK 64-Bit Server VM 24.121-b00 on 1.7.0_121-b00 [linux-x86_64]
-J-Djruby.compile.mode=OFF
makes the problem disappear)uname -a
:Linux xps 3.13.0-35-generic #62~precise1-Ubuntu SMP Mon Aug 18 14:52:04 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
The application is a Rails app (being upgraded to Rails 4.2, the problem occurred under 4.2.7.1).
Problem code
To give an idea of what the code is doing, here's a shortened version (not runnable):
Explanation:
set_cell
is a lambda that writes a value (possibly shortened to respect constraints) to the cell with coordinates [row, col] (bothrow
andcol
are created beforeset_cell
and are hence available), after which it incrementscol
. A successive call toset_cell
then writes its value to the next column.When looping over the data, for each row
col
is initialized to zero, and then incremented insideset_cell
. Some columns have to remain empty, so then we just incrementcol
ourselves.This works only for a limited number of rows when the JIT compiler is enabled. What seems to happen after JIT compilation is the following:
col
is initialized to zeroset_cell
lambda works, correctly incrementingcol
(which also starts at zero), but the link betweencol
inside the lambda andcol
inside the loop (which should be the same variable) seems to be lost. Successive calls toset_cell
still increment their own version ofcol
, but this doesn't affect the value ofcol
outside the lambda (i.e. the value ofcol
as seen in the loop doesn't change).col += 1
inside the main loop for the first time,col
takes the value of 1 (since this version ofcol
wasn't changed by the lamba, although it should have been). For some reason, this restores the link between bothcol
versions, and as of that moment incrementingcol
inside the lambda (by calls toset_cell
is correctly reflected incol
as available in the loop).set_cell
, the link between both versions ofcol
is lost and then recovered again.So far, I haven't been able to reproduce this issue outside the context of this application.
The text was updated successfully, but these errors were encountered: