RFR[13]: 8227260: Can't deal with SharedRuntime::handle_wrong_method triggering more than once for interpreter calls
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Fri Jul 5 11:14:11 UTC 2019
Thanks for diagnosing the issue, Erik!
Can you elaborate, please, on relation to clinit barrier in c2i?
I don't see how it is possible to hit clinit barrier during i2c2i
transition. Template interpreter has clinit barrier as part of
invokestatic handler [1], so by the time c2i is reached, proper checks
should be already performed and all the conditions to pass the barrier
should be met.
If SR::handle_wrong_method is called from clinit barrier in c2i during
i2c2i, it signals about a bug in the new clinit logic: somehow clinit
barrier is bypassed in interpreter.
Are you sure it is not related to upcalls from native code
(caller_frame.is_entry_frame() [1])?
Also, SR::handle_wrong_method() calls coming from clinit barriers
shouldn't hit the fast path w/ callee_target(), because it bypasses the
actual initialization check happening during call site re-resolution.
Best regards,
Vladimir Ivanov
PS: regarding clearing JavaThread::_callee_target in
JavaThread::oops_do(), I'd prefer to keep it and limit the exposure of a
stale Method*. But it's just a matter of preference and I don't have a
strong opinion here.
[1]
src/hotspot/share/runtime/sharedRuntime.cpp:
JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method(JavaThread*
thread))
...
if (caller_frame.is_interpreted_frame() ||
caller_frame.is_entry_frame()) {
On 04/07/2019 18:02, Erik Österlund wrote:
> Hi,
>
> The i2c adapter sets a thread-local "callee_target" Method*, which is
> caught (and cleared) by SharedRuntime::handle_wrong_method if the i2c
> call is "bad" (e.g. not_entrant). This error handler forwards execution
> to the callee c2i entry. If the SharedRuntime::handle_wrong_method
> method is called again due to the i2c2i call being still bad, then we
> will crash the VM in the following guarantee in
> SharedRuntime::handle_wrong_method:
>
> Method* callee = thread->callee_target();
> guarantee(callee != NULL && callee->is_method(), "bad handshake");
>
> Unfortunately, the c2i entry can indeed fail again if it, e.g., hits the
> new class initialization entry barrier of the c2i adapter.
> The solution is to simply not clear the thread-local "callee_target"
> after handling the first failure, as we can't really know there won't be
> another one. There is no reason to clear this value as nobody else reads
> it than the SharedRuntime::handle_wrong_method handler (and we really do
> want it to be able to read the value as many times as it takes until the
> call goes through). I found some confused clearing of this callee_target
> in JavaThread::oops_do(), with a comment saying this is a methodOop that
> we need to clear to make GC happy or something. Seems like old traces of
> perm gen. So I deleted that too.
>
> I caught this in ZGC where the timing window for hitting this issue
> seems to be wider due to concurrent code cache unloading. But it is
> equally problematic for all GCs.
>
> Bug:
> https://bugs.openjdk.java.net/browse/JDK-8227260
>
> Webrev:
> http://cr.openjdk.java.net/~eosterlund/8227260/webrev.00/
>
> Thanks,
> /Erik
More information about the hotspot-dev
mailing list