<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">Hi Dean,<br>
<br>
Thank you a lot for looking at this!<br>
Just a couple of points from me (it is up to Alex to provide a
full answer).<br>
<br>
<br>
I think, Alex in this RFR missed to tell that we knew about this
issue that an incorrect frame will be popped.<br>
But after some discussion we decided to file a separate issue on
this.<br>
Alex wanted to create a good stand-alone test case demonstrating
this problem before filing it.<br>
<br>
Now, as I can see, the <a
href="https://bugs.openjdk.java.net/browse/JDK-8195635"
title="[Graal] nsk/jvmti/unit/ForceEarlyReturn/earlyretbase
crashes with assertion "compilation level out of
bounds"" class="issue-link" data-issue-key="JDK-8195635">JDK-8195635</a>
looks very close to a bug that we wanted to file.
<br>
The only difference is that our scenario includes the
SharedRuntime::resolve_static_call_C instead of the
JavaCallWrapper::JavaCallWrapper as a helper for Java method
invocation.
<br>
If I understand corrctly (Alex will fix me if needed), the jtreg
test we used to chase this issue did not catch a problem with the
HotSpotJVMCIRuntime.adjustCompilationLevel.
<br>
<br>
<br>
The suggested fix was to fix the mismatch in the
TieredThresholdPolicy::even with the comment in the interpreter
code:
<br>
nmethod*
InterpreterRuntime::frequency_counter_overflow(JavaThread* thread,
address branch_bcp) {
<br>
. . .
<br>
if (nm != NULL && thread->is_interp_only_mode()) {
<br>
// Normally we never get an nm if is_interp_only_mode() is
true, because
<br>
// policy()->event has a check for this and won't compile
the method when
<br>
// true. However, it's possible for is_interp_only_mode() to
become true
<br>
// during the compilation. We don't want to return the nm in
that case
<br>
// because we want to continue to execute interpreted.
<br>
nm = NULL;
<br>
} <br>
<br>
> So I think the fix needs to be in code like
SharedRuntime::resolve_static_call_C(),
<br>
> where it returns get_c2i_entry() if is_interp_only_mode() is
true.
<br>
<br>
I'm not sure, the adding this condition and returning the
get_c2i_entry() is always correct.
<br>
We need some help from the Compiler team to make it right.
<br>
<br>
BTW, the interp_only_mode has been enabled only when some
interp_only events are enabled.
<br>
It is not set by either PopFrame or ForceEarlyReturn.
<br>
But the popframe009 test enables single stepping, so we wanted to
make this part right.<br>
<br>
Thanks,<br>
Serguei<br>
<br>
<br>
On 11/26/18 16:05, <a class="moz-txt-link-abbreviated" href="mailto:***@oracle.com">***@oracle.com</a> wrote:<br>
</div>
<blockquote type="cite"
cite="mid:5897ce86-dda6-dd44-ee53-***@oracle.com">How
does this solve the problem of
HotSpotJVMCIRuntime.adjustCompilationLevel being called?
<br>
<br>
I don't think this fix is the right approach. Doesn't
is_interp_only_mode() only apply to the current thread? I don't
think it's safe to assume no compiles will happen in other
threads, or that a method call target is not already compiled,
because as far as I can tell, JVMTI only deoptimizes the active
frames. The bug report describes a case where the caller has been
deoptimized while resolving a call. I don't see how this fix
prevents the target from being a previously compiled method. But
we do need to make sure not to call into compiled code, so I think
the fix needs to be in code like
SharedRuntime::resolve_static_call_C(), where it returns
get_c2i_entry() if is_interp_only_mode() is true. However, there
is still another problem. By allowing JVMTI to suspend the thread
during call setup, but reporting the frame as still in the caller
instead of the callee, we confuse JVMTI into thinking that
execution will resume in the caller instead of the callee. We may
want to restrict where we offer JVMTI suspend points, and not
offer a JVMTI suspend point in
SharedRuntime::resolve_static_call_C and friends at all.
<br>
<br>
dl
<br>
<br>
<br>
On 11/26/18 11:14 AM, Alex Menkov wrote:
<br>
<blockquote type="cite">Hi all,
<br>
<br>
Please review the fix for
<br>
<a class="moz-txt-link-freetext" href="https://bugs.openjdk.java.net/browse/JDK-8195639">https://bugs.openjdk.java.net/browse/JDK-8195639</a>
<br>
webrev:
<br>
<a class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/~amenkov/popframe009/webrev.01/">http://cr.openjdk.java.net/~amenkov/popframe009/webrev.01/</a>
<br>
<br>
Description:
<br>
The test suspends a thread, turns on single stepping and then
calls PopFrame. SingleStep event is expected as soon as the
thread is resumed and PopFrame is processed (so we have call
stack with the depth 1 less than it was before PopFrame).
Instead SingleStep event is received with much deeper call stack
(and PopFrame processes wrong frame).
<br>
Research shown that this is caused by missed deoptimization of
the current frame.
<br>
As far as I understand CompilationPolicy::event should handle
the case when the thread has is_interp_only_mode() set, but
TieredThresholdPolicy::event checks this only then CompLevel is
CompLevel_none.
<br>
CompilerRuntime always calls policy()->event with CompLevel
== CompLevel_aot.
<br>
<br>
The fix looks quite simple, but I'd appreciate feedback from
runtime and compiler teams as I'm not sure I completely
understand all the details of the "PopFrame dance".
<br>
<br>
--alex
<br>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>