RFR 8152065: TraceBytecodes breaks the interpreter expression stack
Daniel D. Daugherty
daniel.daugherty at oracle.com
Fri Mar 18 15:45:34 UTC 2016
On 3/18/16 8:02 AM, Coleen Phillimore wrote:
> On 3/18/16 8:41 AM, David Holmes wrote:
>> On 18/03/2016 9:43 PM, Coleen Phillimore wrote:
>>>
>>>
>>> On 3/17/16 10:09 PM, David Holmes wrote:
>>>>
>>>> On 18/03/2016 11:34 AM, Coleen Phillimore wrote:
>>>>>
>>>>> Hi, Thank you for looking at this.
>>>>>
>>>>> IRT_LEAF and JRT_LEAF are almost identical, just like JRT_ENTRY and
>>>>> IRT_ENTRY. It's just the convention in interpreterRuntime.cpp to use
>>>>> the IRT version.
>>>>
>>>> Sure - but then why the move from SharedRuntime to IntepreterRuntime ?
>>>
>>> Because it's used by the interpreter only. That's the first place to
>>> look for it so it's where it belongs.
>>
>> I'll take your word for it - I have no idea what belongs in
>> sharedRuntime. :)
>>
>> But I'm still confused about the fix. How does the change to being a
>> leaf method fix the rsp problem? And what is the connection with
>> safepoints?
> So the IRT/JRT_ENTRY macro has a ThreadInVMFromJava scoped object,
> where the destructor does SafepointSynchronize::block. So there's a
> safepoint check at the IRT/JRT_END of these functions (JRT_BLOCK_END
> also).
>
> On x86, rsp - the stack pointer- is also the top of the expression
> stack. When we do a call_VM, we save rsp to last_Java_sp in the
> frame. The C++ frame.cpp code uses last_Java_sp to find oops on the
> expression stack.
>
> I verified that all the other calls into the call_VM() leave the
> correct state on the stack, but trace_bytecode pushes registers to
> save before calling call_VM.
>
> Look for trace_bytecode in
> src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp. It pushes the 4
> argument registers to the stack. The failure I was debugging showed
> that these were causing the wrong oops to be found on the expression
> stack with Tom Benson's debugging code.
>
> The alternatives were to change all the cpu dependent code to not pass
> any arguments to trace_bytecode, since tos can be retrieved with
> frame::interpreter_frame_expression_stack_at(0), but I didn't really
> want to do that. I can't test a lot of platforms! Another choice was
> to copy the guts of call_VM into the trace_bytecode generator so that
> last_Java_sp is saved before the call to vm. I briefly looked at
> this, which is why I noticed that there were incorrect comments in the
> code. There are also way too many call_VM variants on x86 at least.
> All seem needed.
>
> So making trace_bytecode IRT_LEAF is the simplest fix so that we could
> get to the bottom of these other reported bugs.
>
> thanks,
> Coleen
> open webrev at http://cr.openjdk.java.net/~coleenp/8152065.01/webrev
src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp
src/share/vm/interpreter/bytecodeInterpreter.cpp
No comments on these renames.
src/cpu/x86/vm/frame_x86.hpp
No comments (comment removal).
src/cpu/x86/vm/interp_masm_x86.cpp
No comments (name typo in mesg).
src/share/vm/interpreter/interpreterRuntime.cpp
No comments (comment removal).
trace_bytecode() function moves to here and changes from
JRT_ENTRY -> IRT_LEAF.
src/share/vm/interpreter/interpreterRuntime.hpp
No comments.
src/share/vm/runtime/sharedRuntime.cpp
trace_bytecode() function moves from here and changes from
JRT_ENTRY -> IRT_LEAF.
src/share/vm/runtime/sharedRuntime.hpp
No comments.
So the old version of trace_bytecode() was marked JRT_ENTRY which
meant that the built-in "ThreadInVMfromJava __tiv(thread)" caused
the caller of trace_bytcode() to potentially safepoint at the end
of the call to trace_bytecode() when ThreadInVMfromJava is destroyed.
src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp:
#ifndef _LP64
<snip>
#else
__ push(state);
__ push(c_rarg0);
__ push(c_rarg1);
__ push(c_rarg2);
__ push(c_rarg3);
__ mov(c_rarg2, rax); // Pass itos
#ifdef _WIN64
__ movflt(xmm3, xmm0); // Pass ftos
#endif
__ call_VM(noreg,
CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode),
c_rarg1, c_rarg2, c_rarg3);
// So the JRT_ENTRY marking of SharedRuntime::trace_bytecode() means
// that we can go to a safepoint just before call_VM() returns and
// that safepoint might be confused by the regs pushed above.
__ pop(c_rarg3);
__ pop(c_rarg2);
__ pop(c_rarg1);
__ pop(c_rarg0);
__ pop(state);
__ ret(0); // return from result
handler
#endif // _LP64
So if I understand what you said above, the safepoint code is
expecting last_Java_sp to refer to the interpreter expression
stack and instead it finds four registers on the top of the
stack.
Of course, now that trace_bytecode() is marked as an IRT_LEAF,
I start wondering if we should be using one of the "leaf" variants
of call_VM(), but I see that call_VM_leaf() isn't used anywhere
in templateInterpreterGenerator_x86.cpp. Sigh... Do you happen
to know why we shouldn't use a leaf variant?
Thumbs up on the fix. Would be good to nail down some of the
nagging questions, but not absolutely necessary...
Dan
>
>> Thanks,
>> David
>>
>>> Coleen
>>>
>>>>
>>>> Thanks,
>>>> David
>>>>
>>>>> I guess someday we should get rid of the IRT versions. I'm not sure
>>>>> what the history was behind them.
>>>>>
>>>>> Coleen
>>>>>
>>>>>
>>>>> On 3/17/16 8:47 PM, David Holmes wrote:
>>>>>> On 18/03/2016 10:08 AM, Jiangli Zhou wrote:
>>>>>>> Hi Coleen,
>>>>>>>
>>>>>>> This looks like a safe fix, but I probably can’t serve as a very
>>>>>>> good
>>>>>>> reviewer for this area. I have a question. Would ‘JRT_LEAF’ work
>>>>>>> also
>>>>>>> in this case?
>>>>>>
>>>>>> That was my question too!
>>>>>>
>>>>>> David
>>>>>>
>>>>>>> Thanks,
>>>>>>> Jiangli
>>>>>>>
>>>>>>>> On Mar 17, 2016, at 2:39 PM, Coleen Phillimore
>>>>>>>> <coleen.phillimore at oracle.com> wrote:
>>>>>>>>
>>>>>>>> Summary: Move trace_bytecode to InterpreterRuntime and make
>>>>>>>> trace_bytecode an IRT_LEAF so that safepoints are not allowed.
>>>>>>>>
>>>>>>>> open webrev at
>>>>>>>> http://cr.openjdk.java.net/~coleenp/8152065.01/webrev
>>>>>>>> bug link https://bugs.openjdk.java.net/browse/JDK-8152065
>>>>>>>>
>>>>>>>> Tested with test program for bug
>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8151256 and runThese with
>>>>>>>> -XX:+TraceBytecodes for a few minutes (output file got too big).
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Coleen
>>>>>>>
>>>>>
>>>
>
More information about the hotspot-runtime-dev
mailing list