8287186: JDK modules participating in preview
Reviewed-by: alanb, jlahoda
This commit is contained in:
parent
0530f4e517
commit
fb297705f6
src
java.base/share/classes
java.management/share/classes
jdk.compiler/share/classes/com/sun/tools/javac
jdk.incubator.concurrent/share/classes
jdk.incubator.vector/share/classes
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.internal.javac;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates, when declared on a module declaration, that the module participates
|
||||
* in preview features and therefore does not need to be compiled with "--enable-preview".
|
||||
*/
|
||||
@Target(ElementType.MODULE)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface ParticipatesInPreview {
|
||||
}
|
@ -141,9 +141,17 @@ module java.base {
|
||||
jdk.compiler;
|
||||
exports com.sun.security.ntlm to
|
||||
java.security.sasl;
|
||||
// Note: all modules in the exported list participate in preview features
|
||||
// and therefore if they use preview features they do not need to be
|
||||
// compiled with "--enable-preview".
|
||||
// It is recommended for any modules that do participate that their
|
||||
// module declaration be annotated with jdk.internal.javac.ParticipatesInPreview
|
||||
exports jdk.internal.javac to
|
||||
java.compiler,
|
||||
java.management, // participates in preview features
|
||||
jdk.compiler,
|
||||
jdk.incubator.concurrent, // participates in preview features
|
||||
jdk.incubator.vector, // participates in preview features
|
||||
jdk.jdi,
|
||||
jdk.jfr,
|
||||
jdk.jshell,
|
||||
|
@ -29,8 +29,6 @@ import javax.management.openmbean.ArrayType;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import sun.management.ManagementFactoryHelper;
|
||||
import sun.management.ThreadInfoCompositeData;
|
||||
import sun.management.Util;
|
||||
import static java.lang.Thread.State.*;
|
||||
|
||||
/**
|
||||
* Thread information. {@code ThreadInfo} contains the information
|
||||
@ -226,7 +224,7 @@ public class ThreadInfo {
|
||||
StackTraceElement[] stackTrace,
|
||||
MonitorInfo[] lockedMonitors,
|
||||
LockInfo[] lockedSynchronizers) {
|
||||
this.virtual = Util.isVirtual(t);
|
||||
this.virtual = t.isVirtual();
|
||||
this.threadId = t.threadId();
|
||||
this.threadName = t.getName();
|
||||
this.threadState = ManagementFactoryHelper.toThreadState(state);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2022, 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
|
||||
@ -23,6 +23,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.javac.ParticipatesInPreview;
|
||||
|
||||
/**
|
||||
* Defines the Java Management Extensions (JMX) API.
|
||||
* <P>
|
||||
@ -35,6 +37,7 @@
|
||||
* @moduleGraph
|
||||
* @since 9
|
||||
*/
|
||||
@ParticipatesInPreview
|
||||
module java.management {
|
||||
|
||||
exports java.lang.management;
|
||||
|
@ -31,7 +31,6 @@ import java.lang.management.ThreadMXBean;
|
||||
import java.util.stream.Stream;
|
||||
import javax.management.ObjectName;
|
||||
import java.util.Objects;
|
||||
import sun.management.Util;
|
||||
|
||||
/**
|
||||
* Implementation for java.lang.management.ThreadMXBean as well as providing the
|
||||
@ -222,7 +221,7 @@ public class ThreadImpl implements ThreadMXBean {
|
||||
|
||||
private boolean verifyCurrentThreadCpuTime() {
|
||||
// check if Thread CPU time measurement is supported.
|
||||
if (Util.isVirtual(Thread.currentThread())) {
|
||||
if (Thread.currentThread().isVirtual()) {
|
||||
throw new UnsupportedOperationException("Not supported by virtual threads");
|
||||
}
|
||||
if (!isCurrentThreadCpuTimeSupported()) {
|
||||
@ -284,7 +283,7 @@ public class ThreadImpl implements ThreadMXBean {
|
||||
long id = ids[0];
|
||||
Thread thread = Thread.currentThread();
|
||||
if (id == thread.threadId()) {
|
||||
if (Util.isVirtual(thread)) {
|
||||
if (thread.isVirtual()) {
|
||||
times[0] = -1;
|
||||
} else {
|
||||
times[0] = getThreadTotalCpuTime0(0);
|
||||
@ -327,7 +326,7 @@ public class ThreadImpl implements ThreadMXBean {
|
||||
long id = ids[0];
|
||||
Thread thread = Thread.currentThread();
|
||||
if (id == thread.threadId()) {
|
||||
if (Util.isVirtual(thread)) {
|
||||
if (thread.isVirtual()) {
|
||||
times[0] = -1;
|
||||
} else {
|
||||
times[0] = getThreadUserCpuTime0(0);
|
||||
@ -361,7 +360,7 @@ public class ThreadImpl implements ThreadMXBean {
|
||||
}
|
||||
|
||||
protected long getCurrentThreadAllocatedBytes() {
|
||||
if (isThreadAllocatedMemoryEnabled() && !Util.isVirtual(Thread.currentThread())) {
|
||||
if (isThreadAllocatedMemoryEnabled() && !Thread.currentThread().isVirtual()) {
|
||||
return getThreadAllocatedMemory0(0);
|
||||
}
|
||||
return -1;
|
||||
@ -377,7 +376,7 @@ public class ThreadImpl implements ThreadMXBean {
|
||||
if (verified) {
|
||||
Thread thread = Thread.currentThread();
|
||||
if (id == thread.threadId()) {
|
||||
if (Util.isVirtual(thread)) {
|
||||
if (thread.isVirtual()) {
|
||||
return -1L;
|
||||
} else {
|
||||
return getThreadAllocatedMemory0(0);
|
||||
@ -577,7 +576,7 @@ public class ThreadImpl implements ThreadMXBean {
|
||||
*/
|
||||
private static long[] platformThreadIds(Thread[] threads) {
|
||||
return Stream.of(threads)
|
||||
.filter(t -> !Util.isVirtual(t))
|
||||
.filter(t -> !t.isVirtual())
|
||||
.mapToLong(Thread::threadId)
|
||||
.toArray();
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package sun.management;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.management.ManagementPermission;
|
||||
import java.lang.management.ThreadInfo;
|
||||
@ -88,20 +87,6 @@ public class Util {
|
||||
checkAccess(controlPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given Thread is a virtual thread.
|
||||
*
|
||||
* @implNote This method uses reflection because Thread::isVirtual is a preview API
|
||||
* and the java.management module cannot be compiled with --enable-preview.
|
||||
*/
|
||||
public static boolean isVirtual(Thread thread) {
|
||||
try {
|
||||
return (boolean) THREAD_IS_VIRTUAL.invoke(thread);
|
||||
} catch (Exception e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given ThreadInfo is for a virtual thread.
|
||||
*/
|
||||
@ -113,16 +98,6 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static Method threadIsVirtual() {
|
||||
PrivilegedExceptionAction<Method> pa = () -> Thread.class.getMethod("isVirtual");
|
||||
try {
|
||||
return AccessController.doPrivileged(pa);
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static Field threadInfoVirtual() {
|
||||
PrivilegedExceptionAction<Field> pa = () -> {
|
||||
@ -137,6 +112,5 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Method THREAD_IS_VIRTUAL = threadIsVirtual();
|
||||
private static final Field THREADINFO_VIRTUAL = threadInfoVirtual();
|
||||
}
|
||||
|
@ -124,15 +124,22 @@ public class Preview {
|
||||
* Returns true if {@code s} is deemed to participate in the preview of {@code previewSymbol}, and
|
||||
* therefore no warnings or errors will be produced.
|
||||
*
|
||||
* @parem syms the symbol table
|
||||
* @param s the symbol depending on the preview symbol
|
||||
* @param previewSymbol the preview symbol marked with @Preview
|
||||
* @return true if {@code s} is participating in the preview of {@code previewSymbol}
|
||||
*/
|
||||
public boolean participatesInPreview(Symbol s, Symbol previewSymbol) {
|
||||
// Hardcode the incubating vector API module for now
|
||||
// Will generalize with an annotation, @PreviewParticipating say, later
|
||||
return previewSymbol.packge().modle == s.packge().modle ||
|
||||
s.packge().modle.name == names.jdk_incubator_vector;
|
||||
public boolean participatesInPreview(Symtab syms, Symbol s, Symbol previewSymbol) {
|
||||
// All symbols in the same module as the preview symbol participate in the preview API
|
||||
if (previewSymbol.packge().modle == s.packge().modle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If java.base's jdk.internal.javac package is exported to s's module then
|
||||
// s participates in the preview API
|
||||
return syms.java_base.exports.stream()
|
||||
.filter(ed -> ed.packge.fullname == names.jdk_internal_javac)
|
||||
.anyMatch(ed -> ed.modules.contains(s.packge().modle));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3600,7 +3600,7 @@ public class Check {
|
||||
}
|
||||
|
||||
void checkPreview(DiagnosticPosition pos, Symbol other, Symbol s) {
|
||||
if ((s.flags() & PREVIEW_API) != 0 && !preview.participatesInPreview(other, s)) {
|
||||
if ((s.flags() & PREVIEW_API) != 0 && !preview.participatesInPreview(syms, other, s)) {
|
||||
if ((s.flags() & PREVIEW_REFLECTIVE) == 0) {
|
||||
if (!preview.isEnabled()) {
|
||||
log.error(pos, Errors.IsPreview(s));
|
||||
|
@ -120,11 +120,11 @@ public class Names {
|
||||
// package names
|
||||
public final Name java;
|
||||
public final Name java_lang;
|
||||
public final Name jdk_internal_javac;
|
||||
|
||||
// module names
|
||||
public final Name java_base;
|
||||
public final Name jdk_unsupported;
|
||||
public final Name jdk_incubator_vector;
|
||||
|
||||
// attribute names
|
||||
public final Name Annotation;
|
||||
@ -302,11 +302,11 @@ public class Names {
|
||||
// package names
|
||||
java = fromString("java");
|
||||
java_lang = fromString("java.lang");
|
||||
jdk_internal_javac = fromString("jdk.internal.javac");
|
||||
|
||||
// module names
|
||||
java_base = fromString("java.base");
|
||||
jdk_unsupported = fromString("jdk.unsupported");
|
||||
jdk_incubator_vector = fromString("jdk.incubator.vector");
|
||||
|
||||
// attribute names
|
||||
Annotation = fromString("Annotation");
|
||||
|
@ -26,7 +26,6 @@ package jdk.incubator.concurrent;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.time.Duration;
|
||||
@ -300,7 +299,7 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
||||
*/
|
||||
public StructuredTaskScope() {
|
||||
PreviewFeatures.ensureEnabled();
|
||||
this.factory = FactoryHolder.VIRTUAL_THREAD_FACTORY;
|
||||
this.factory = Thread.ofVirtual().factory();
|
||||
this.flock = ThreadFlock.open(null);
|
||||
}
|
||||
|
||||
@ -839,7 +838,7 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
||||
* name of {@code null} and a thread factory that creates virtual threads.
|
||||
*/
|
||||
public ShutdownOnSuccess() {
|
||||
super(null, FactoryHolder.VIRTUAL_THREAD_FACTORY);
|
||||
super(null, Thread.ofVirtual().factory());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1015,7 +1014,7 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
||||
* name of {@code null} and a thread factory that creates virtual threads.
|
||||
*/
|
||||
public ShutdownOnFailure() {
|
||||
super(null, FactoryHolder.VIRTUAL_THREAD_FACTORY);
|
||||
super(null, Thread.ofVirtual().factory());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1161,29 +1160,4 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holder class for the virtual thread factory. It uses reflection to allow
|
||||
* this class be compiled in an incubator module without also enabling preview
|
||||
* features.
|
||||
*/
|
||||
private static class FactoryHolder {
|
||||
static final ThreadFactory VIRTUAL_THREAD_FACTORY = virtualThreadFactory();
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static ThreadFactory virtualThreadFactory() {
|
||||
PrivilegedAction<ThreadFactory> pa = () -> {
|
||||
try {
|
||||
Method ofVirtualMethod = Thread.class.getDeclaredMethod("ofVirtual");
|
||||
Object virtualThreadBuilder = ofVirtualMethod.invoke(null);
|
||||
Class<?> ofVirtualClass = Class.forName("java.lang.Thread$Builder$OfVirtual");
|
||||
Method factoryMethod = ofVirtualClass.getMethod("factory");
|
||||
return (ThreadFactory) factoryMethod.invoke(virtualThreadBuilder);
|
||||
} catch (Exception e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
};
|
||||
return AccessController.doPrivileged(pa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,15 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.javac.ParticipatesInPreview;
|
||||
|
||||
/**
|
||||
* Defines non-final APIs for concurrent programming.
|
||||
* {@Incubating}
|
||||
*
|
||||
* @moduleGraph
|
||||
*/
|
||||
@ParticipatesInPreview
|
||||
module jdk.incubator.concurrent {
|
||||
exports jdk.incubator.concurrent;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2022, 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
|
||||
@ -23,6 +23,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.javac.ParticipatesInPreview;
|
||||
|
||||
/**
|
||||
* Defines an API for expressing computations that can be reliably compiled
|
||||
* at runtime into SIMD instructions, such as AVX instructions on x64, and
|
||||
@ -31,6 +33,7 @@
|
||||
*
|
||||
* @moduleGraph
|
||||
*/
|
||||
@ParticipatesInPreview
|
||||
module jdk.incubator.vector {
|
||||
exports jdk.incubator.vector;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user