JDK-8203481 : Incorrect constraint for unextended_sp in frame:safe_for_sender
Type:Bug
Component:hotspot
Sub-Component:runtime
Priority:P3
Status:Resolved
Resolution:Fixed
OS:linux
CPU:generic
Submitted:2018-05-21
Updated:2021-02-01
Resolved:2018-06-24
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
Constraint in safe_for_sender "unextended sp must be within the stack and above or equal sp" is incorrect.
Comments
-------- Forwarded Message --------
From: Andrew Haley <aph@redhat.com>
...
While we're interpreting, the machine SP is always <= the Java
expression SP, ESP. When we enter a new intrpreted frame, the old
machine SP is saved in interpreter_frame_sender_sp in the new frame
and the machine SP is adjusted so that it is just below ESP.
interpreter_frame_sender_sp is used to calculate the unextended_sp
while we're unwinding the frame.
So, A correct frame layout can look like this:
0x000003ffb61bdf40: 0x000003ffb61bdfb0 #2 method java.security.AccessController.getContext()Ljava/security/AccessControlContext; @ 0
- 1 locals 5 max stack
0x000003ffb61bdf38: 0x000003ffb61bdf20 interpreter_frame_sender_sp
0x000003ffb61bdf30: 0x000003ffb61bdef0 interpreter_frame_last_sp
0x000003ffb61bdf28: 0x000003ff88fb0bc0 interpreter_frame_method
0x000003ffb61bdf20: 0x0000000000000000 unextended_sp for #3
interpreter_frame_mdp
0x000003ffb61bdf18: 0x0000000000000000
0x000003ffb61bdf10: 0x000000070ff06a48 interpreter_frame_mirror
0x000003ffb61bdf08: 0x000003ff88fb0de8 interpreter_frame_cache
0x000003ffb61bdf00: 0x000003ffb61bdf50 interpreter_frame_locals
0x000003ffb61bdef8: 0x000003ff88fb0b90 interpreter_frame_bcp
0x000003ffb61bdef0: 0x000003ffb61bdef0 interpreter_frame_initial_sp
0x000003ffb61bdee8: 0x000000070ff06a48
0x000003ffb61bdee0: 0x0000000000000000 sp for #2
0x000003ffb61bded8: 0x000003ffa1081360
0x000003ffb61bded0: 0x000003ffb61bdf40 #1 method java.security.AccessController.getStackAccessControlContext()Ljava/security/AccessControlContext; @ 0
- 0 locals 1 max stack
0x000003ffb61bdec8: 0x000003ffb61bdeb0 interpreter_frame_sender_sp
0x000003ffb61bdec0: 0x0000000000000000 interpreter_frame_last_sp
0x000003ffb61bdeb8: 0x000003ff88fb0a30 interpreter_frame_method
0x000003ffb61bdeb0: 0x0000000000000000 unextended_sp for #2
interpreter_frame_mdp
0x000003ffb61bdea8: 0x0000000000000000
0x000003ffb61bdea0: 0x000000070ff06a48 interpreter_frame_mirror
0x000003ffb61bde98: 0x000003ff88fb0de8 interpreter_frame_cache
0x000003ffb61bde90: 0x000003ffb61bdee8 interpreter_frame_locals
0x000003ffb61bde88: 0x0000000000000000 interpreter_frame_bcp
0x000003ffb61bde80: 0x000003ffb61bde80 sp for #1
interpreter_frame_initial_sp
unextended_sp for #1
Note that getStackAccessControlContext()'s saved sender SP from
AccessController.getContext() is 0x000003ffb61bdeb0: this really is
less than 0x000003ffb61bdee0, which was the SP before
getStackAccessControlContext()'s frame was created. This is OK, and
explains why the assert failed for you.
Given that the unextended_sp can be greater or less than the saved SP,
I think the assert can be removed.
10-06-2018
I agree with Dan's comment on review thread. For stacks that grow down the expectation is:
sp <= unextended_sp <= stack_base()
22-05-2018
74 // unextended sp must be within the stack and above or equal sp
75 bool unextended_sp_safe = (unextended_sp < thread->stack_base()) &&
76 (unextended_sp >= sp);
unextended_sp must be *below or equal to sp*.
On x86 unextended_sp is always equal to sp so constraint passed, but on aarch64 unextended_sp is below sp.