When a virtual thread suspended at a breakpoint gets unmounted and mounted 
again only the top frame is thawed. The caller stays frozen in the stack chunk 
and the popped frame returns into the continuation return barrier. The 
interpreter's popframe entry treats that return address like a deoptimized 
caller, preserves the arguments, sets the reexecution bit and returns. The 
barrier then thawed the caller as a plain return. Arguments and bit left 
behind, no reexecution of the invoke, run() went on with a zero result.

Thaw finishes it now. An interpreted caller gets the preserved arguments back 
on its expression stack and its return slot is patched to the interpreter deopt 
entry after push_return_frame, the x86 deopt entry reloads rsp from last_sp for 
that, aarch64 already does. A compiled caller frozen in the chunk is 
deoptimized from UpdateForPopTopFrameClosure::doit the same way set_frame_pop 
does it. Thaw leaves the arguments alone in that case and unpack_on_stack puts 
them back. A frozen compiled frame being popped stays opaque.

A linkTo caller needs one more thing. The linker consumed the trailing 
MemberName before the target ran and the preserved arguments are sized by the 
target, so the MemberName is not among them. Thaw takes it from the caller's 
local 0 the way the interpreter's popframe entry does, the lookup from 
member_name_arg_or_null moved into a plain helper both can call. The arguments 
go one slot up and the MemberName goes back on top.

popframes002 runs popframes001 on a virtual thread with the join Chris Plummer 
wrote enabled by a property in the debuggee. It unmounts the tested thread 
before the breakpoint so the caller is frozen when popped, and run() is 
excluded from compilation so this stays the interpreted case. popframes003 is 
the compiled caller case, -Xcomp with the breakpoint in a separate stop() so 
testedMethod keeps its compiled frame and run() stays frozen, the debugger pops 
frame 1 and the debuggee checks with WhiteBox that run() and testedMethod are 
compiled and that testedMethod ran twice. -XX:+PreserveFramePointer keeps the 
thaw on the slow path. Both fail on master without the hotspot change. 
popframes001 itself runs the plain case as before and is off the virtual 
problem list. If separate copies of the debugger and debuggee are preferred 
over the properties that is easy to change. PopFrameMethodNameInvariantTest got 
an unmount mode, the same linkToStatic pop on a virtual thread that sleeps
 before the breakpoint so its caller is frozen.

Open: the reexecution after thaw is only run on x86 and aarch64. riscv restores 
the sp in its deopt entry like aarch64 does. ppc and s390 do not, their deopt 
entries expect the interpreter state set up before entry, ppc by the deopt blob 
and the return entry, s390 by the frame resize to top_frame_sp in the return 
entry and the resume adapter. The direct jump from thaw skips that. Read only, 
not run.

---

Testing:
- [x] popframes001, 002 and 003 x20 with platform and virtual threads and x10 
with -Xcomp on virtual threads, nsk/jdwp/StackFrame x200 at jtreg concurrency 4 
with -XX:-VerifyContinuations on virtual threads, nsk/jdwp, nsk/jdi and 
java/lang/Thread/virtual with both thread factories, 
serviceability/jvmti/vthread on virtual threads, nsk/jvmti and 
serviceability/jvmti on platform threads, and tier1-3, all on linux-x64 and 
linux-aarch64 debug. One tier3 timeout in vm/mlvm breakpointInCompiledCode on 
aarch64, a platform thread test with no PopFrame that has its own open timeout 
issue, same build passed that task twice and 10 standalone reruns were clean. 
For the MemberName change: tier1-3 again, PopFrameMethodNameInvariantTest x20 
and popframes001, 002 and 003 x20 with both thread factories, on both 
platforms, all clean. The unmount mode of PopFrameMethodNameInvariantTest x10 
on the previous commit crashes every time in the linkToStatic adapter. For the 
popframes003 rework: the PopFrames,
 StackFrame, group and tier1-3 runs again on both platforms, plus the PopFrames 
tests x10 with -XX:-TieredCompilation and x10 with -XX:TieredStopAtLevel=1 on 
both, and x10 on windows-x64 and macosx-aarch64, all clean, and popframes002 
and popframes003 on master without the hotspot change fail every run in both 
compiler modes. Also the three PopFrames tests under the 39 flag sets our CI 
tasks use for them plus plain preview, x3 on linux-x64 and linux-aarch64 debug, 
and plain plus virtual x3 on windows-x64 and macosx-aarch64 












---------
- [x] I confirm that I make this contribution in accordance with the [OpenJDK 
Interim AI Policy](https://openjdk.org/legal/ai).

-------------

Commit messages:
 - Keep testedMethod and run free of deoptimization before the freeze, drop the 
WhiteBox check
 - Break in stop() and pop its caller in popframes003, make the unmount 
deterministic
 - Put the MemberName back for a linkTo caller and factor the popframe block out
 - Run popframes002 and popframes003 on the popframes001 classes
 - Patch the return pc instead of rebuilding the frame
 - Exclude the popframes002 caller from compilation
 - Keep the popframes002 caller interpreted and add popframes003 for a compiled 
one
 - Deoptimize a frozen compiled caller instead of refusing the pop
 - Move the frozen caller case to popframes002 and restore popframes001
 - Refuse the pop when the frozen caller is compiled
 - ... and 9 more: https://git.openjdk.org/jdk/compare/c5a31111...173a40d5

Changes: https://git.openjdk.org/jdk/pull/32661/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=32661&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8391440
  Stats: 417 lines in 11 files changed: 377 ins; 14 del; 26 mod
  Patch: https://git.openjdk.org/jdk/pull/32661.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/32661/head:pull/32661

PR: https://git.openjdk.org/jdk/pull/32661

Reply via email to