> If a thread tries to initialize a class that is already being initialized by > another thread, it will block until notified. Since at this blocking point > there are native frames on the stack, a virtual thread cannot be unmounted > and is pinned to its carrier. Besides harming scalability, this can, in some > pathological cases, lead to a deadlock, for example, if the thread executing > the class initialization method is blocked waiting for some unmounted virtual > thread to run, but all carriers are blocked waiting for that class to be > initialized. > > As of JDK-8338383, virtual threads blocked in the VM on `ObjectMonitor` > operations can be unmounted. Since synchronization on class initialization is > implemented using `ObjectLocker`, we can reuse the same mechanism to unmount > virtual threads on these cases too. > > This patch adds support for unmounting virtual threads on some of the most > common class initialization paths, specifically when calling > `InterpreterRuntime::_new` (`new` bytecode), and > `InterpreterRuntime::resolve_from_cache` for `invokestatic`, `getstatic` or > `putstatic` bytecodes. In the future we might consider extending this > mechanism to include initialization calls originating from native methods > such as `Class.forName0`. > > ### Summary of implementation > > The ObjectLocker class was modified to not pin the continuation if we are > coming from a preemptable path, which will be the case when calling > `InstanceKlass::initialize_impl` from new method > `InstanceKlass::initialize_preemptable`. This means that for these cases, a > virtual thread can now be unmounted either when contending for the init_lock > in the `ObjectLocker` constructor, or in the call to `wait_uninterruptibly`. > Also, since the call to initialize a class includes a previous call to > `link_class` which also uses `ObjectLocker` to protect concurrent calls from > multiple threads, we will allow preemption there too. > > If preempted, we will throw a pre-allocated exception which will get > propagated with the `TRAPS/CHECK` macros all the way back to the VM entry > point. The exception will be cleared and on return back to Java the virtual > thread will go through the preempt stub and unmount. When running again, at > the end of the thaw call we will identify this preemption case and redo the > original VM call (either `InterpreterRuntime::_new` or > `InterpreterRuntime::resolve_from_cache`). > > ### Notes > > `InterpreterRuntime::call_VM_preemptable` used previously only for > `InterpreterRuntime::monitorenter`, was renamed to `In...
Patricio Chilano Mateo has updated the pull request incrementally with one additional commit since the last revision: fix verify_frame_kind ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27802/files - new: https://git.openjdk.org/jdk/pull/27802/files/79fce80f..ac557152 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27802&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27802&range=01-02 Stats: 10 lines in 1 file changed: 6 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/27802.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27802/head:pull/27802 PR: https://git.openjdk.org/jdk/pull/27802
