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
