Skip to content

Always treat non-full IC as not having protocol#6288

Merged
headius merged 1 commit intojruby:jruby-9.2from
headius:more_atomic_full_build
Jun 18, 2020
Merged

Always treat non-full IC as not having protocol#6288
headius merged 1 commit intojruby:jruby-9.2from
headius:more_atomic_full_build

Conversation

@headius
Copy link
Member

@headius headius commented Jun 18, 2020

The logic here used to go to interpreterContext to check for the
call protocol logic. The hasExplicitCallProtocol method returns a
cached value acquired from the encapsulated scope, via its flags.
However the enum of flags in IRScope may be mutated concurrently,
leading to a situation where we have seen the scope flip to having
call protocols installed, but the InterpreterContext in hand is
still the one without protocol instructions. As a result, we may
start interpreting using an unoptimized IR along the "direct" path
which does not push any scope state. This lead to the AIOOB
reported later in #6282.

The NPE reported in #6282 has not reproduced for me on the
jruby-9.2 branch, and may have been fixed through other means, but
this modified logic should also help any such cases that remain.
Instead of overwriting the two InterpreterContext fields, the non-
full version will always remain the non-full version, and the full
version will only be set into that field. Once set, neither are
ever cleared or re-set to a new value, avoiding a transient null
in the instructionContext field.

I ran the new reproduction from #6282 for a few hours and saw no
errors. Adding a test that guarantees this is fixed may be
difficult, but I believe we've got it here.

This logic will be overhauled for 9.3, so we'll go with this
workaround for now and call it fixed.

Fixes #6282.

@headius headius added this to the JRuby 9.2.12.0 milestone Jun 18, 2020
@headius headius requested a review from enebo June 18, 2020 07:51
The logic here used to go to interpreterContext to check for the
call protocol logic. The hasExplicitCallProtocol method returns a
cached value acquired from the encapsulated scope, via its flags.
However the enum of flags in IRScope may be mutated concurrently,
leading to a situation where we have seen the scope flip to having
call protocols installed, but the InterpreterContext in hand is
still the one without protocol instructions. As a result, we may
start interpreting using an unoptimized IR along the "direct" path
which does not push any scope state. This lead to the AIOOB
reported later in jruby#6282.

The NPE reported in jruby#6282 has not reproduced for me on the
jruby-9.2 branch, and may have been fixed through other means, but
this modified logic should also help any such cases that remain.
Instead of overwriting the two InterpreterContext fields, the non-
full version will always remain the non-full version, and the full
version will only be set into that field. Once set, neither are
ever cleared or re-set to a new value, avoiding a transient null
in the instructionContext field.

I ran the new reproduction from jruby#6282 for a few hours and saw no
errors. Adding a test that guarantees this is fixed may be
difficult, but I believe we've got it here.

This logic will be overhauled for 9.3, so we'll go with this
workaround for now and call it fixed.

Fixes jruby#6282.
@headius headius force-pushed the more_atomic_full_build branch from 3e760d4 to b0a3990 Compare June 18, 2020 20:34
@headius headius merged commit 9ea38be into jruby:jruby-9.2 Jun 18, 2020
@headius headius deleted the more_atomic_full_build branch June 18, 2020 22:10
@headius headius linked an issue Jun 18, 2020 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NPE in ruby block called concurrently from Java

2 participants