On Sun, 29 May 2022 14:46:39 GMT, Alan Bateman <al...@openjdk.org> wrote:
> This patch adds an alternative virtual thread implementation where each > virtual thread is backed by an OS thread. It doesn't scale but it can be used > by ports that don't have continuations support in the VM. Aside from > scalability, the lack of continuations support means: > > 1. JVM TI is not supported when running with --enable-preview (the JVM TI > spec allows for this) > 2. jshell --enable-preview can't be used (as jshell uses the debugger APIs > and so needs JVM TI) > > The VM option "VMContinuations" is added as an experimental option so it can > be used by tests. A number of tests are changed to re-run with > -XX:-VMContinuations. A new jtreg property is added so that tests that need > the underlying VM support to be present can use "@requires vm.continuations" > in the test description. A follow-up change would be to add "@requires > vm.continuations" to the ~70 serviceability/jvmti/vthread that run with > preview features enabled. Since the package `jdk.internal.access` is exported[^1] to the `java.management` module, this can use `MethodHandle`s obtained using the trusted lookup. [^1]: https://github.com/openjdk/jdk/blob/73ba7fdce838ba8a2c227a972c176311e6cc0b41/src/java.base/share/classes/module-info.java#L151-L154 src/java.management/share/classes/java/lang/management/ThreadInfo.java line 971: > 969: throw new InternalError(e); > 970: } > 971: } Suggestion: private static boolean isVirtual(Thread thread) { try { return (boolean) IS_VIRTUAL.invokeExact(thread); } catch (Error | RuntimeException e) { throw e; } catch (Throwable t) { throw new InternalError(t); } } private static final MethodHandle IS_VIRTUAL; static { final JavaLangInvokeAccess JLIA = SharedSecrets.getJavaLangInvokeAccess(); try { MethodHandle m = JLIA.findVirtual(Thread.class, "isVirtual", MethodType.methodType(boolean.class)); assert m != null; IS_VIRTUAL = m; } catch (Exception e) { throw new InternalError(e); } } src/java.management/share/classes/sun/management/ThreadImpl.java line 661: > 659: > 660: private static final Method THREAD_IS_VIRTUAL = threadIsVirtual(); > 661: private static final Field THREADINFO_VIRTUAL = threadInfoVirtual(); Suggestion: private static boolean isVirtual(Thread thread) { try { return (boolean) THREAD_IS_VIRTUAL.invokeExact(thread); } catch (Error | RuntimeException e) { throw e; } catch (Throwable t) { throw new InternalError(t); } } /** * Returns true if the given ThreadInfo is for a virutal thread. */ private static boolean isVirtual(ThreadInfo threadInfo) { try { return (boolean) THREADINFO_VIRTUAL.invokeExact(threadInfo); } catch (Error | RuntimeException e) { throw e; } catch (Throwable t) { throw new InternalError(t); } } private static final JavaLangInvokeAccess JLIA = SharedSecrets.getJavaLangInvokeAccess(); private static MethodHandle threadIsVirtual() { try { MethodHandle m = JLIA.findVirtual(Thread.class, "isVirtual", MethodType.methodType(boolean.class)); assert m != null; return m; } catch (Exception e) { throw new InternalError(e); } } @SuppressWarnings("removal") private static MethodHandle threadInfoVirtual() { PrivilegedExceptionAction<Field> pa = () -> ThreadInfo.class.getDeclaredField("virtual"); try { return JLIA.unreflectField(AccessController.doPrivileged(pa), false); } catch (Exception e) { throw new InternalError(e); } } private static final MethodHandle THREAD_IS_VIRTUAL = threadIsVirtual(); private static final MethodHandle THREADINFO_VIRTUAL = threadInfoVirtual(); ------------- PR: https://git.openjdk.java.net/jdk/pull/8939