8343132: Remove temporary transitions from Virtual thread implementation

Reviewed-by: dholmes, sspitsyn, pchilanomate
This commit is contained in:
Alan Bateman 2024-10-31 08:53:19 +00:00
parent 2f1ba5ef09
commit dee0982c60
16 changed files with 184 additions and 263 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -232,8 +232,8 @@ public class ThreadLocal<T> {
if (this instanceof TerminatingThreadLocal<?> ttl) {
TerminatingThreadLocal.register(ttl);
}
if (TRACE_VTHREAD_LOCALS) {
dumpStackIfVirtualThread();
if (TRACE_VTHREAD_LOCALS && t == Thread.currentThread() && t.isVirtual()) {
printStackTrace();
}
return value;
}
@ -249,8 +249,8 @@ public class ThreadLocal<T> {
*/
public void set(T value) {
set(Thread.currentThread(), value);
if (TRACE_VTHREAD_LOCALS) {
dumpStackIfVirtualThread();
if (TRACE_VTHREAD_LOCALS && Thread.currentThread().isVirtual()) {
printStackTrace();
}
}
@ -799,7 +799,6 @@ public class ThreadLocal<T> {
}
}
/**
* Reads the value of the jdk.traceVirtualThreadLocals property to determine if
* a stack trace should be printed when a virtual thread sets a thread local.
@ -811,30 +810,28 @@ public class ThreadLocal<T> {
}
/**
* Print a stack trace if the current thread is a virtual thread.
* Print the stack trace of the current thread, skipping the printStackTrace frame.
* A thread local is used to detect reentrancy as the printing may itself use
* thread locals.
*/
static void dumpStackIfVirtualThread() {
if (Thread.currentThread() instanceof VirtualThread vthread) {
private void printStackTrace() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map.getEntry(DUMPING_STACK) == null) {
map.set(DUMPING_STACK, true);
try {
var stack = StackWalkerHolder.STACK_WALKER.walk(s ->
var stack = StackWalker.getInstance().walk(s ->
s.skip(1) // skip caller
.collect(Collectors.toList()));
// switch to carrier thread to avoid recursive use of thread-locals
vthread.executeOnCarrierThread(() -> {
System.out.println(vthread);
for (StackWalker.StackFrame frame : stack) {
System.out.format(" %s%n", frame.toStackTraceElement());
}
return null;
});
} catch (Exception e) {
throw new InternalError(e);
System.out.println(t);
for (StackWalker.StackFrame frame : stack) {
System.out.format(" %s%n", frame.toStackTraceElement());
}
} finally {
map.remove(DUMPING_STACK);
}
}
}
private static class StackWalkerHolder {
static final StackWalker STACK_WALKER = StackWalker.getInstance();
}
private static final ThreadLocal<Boolean> DUMPING_STACK = new ThreadLocal<>();
}