Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

Expand All @@ -69,11 +70,15 @@
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.java.LoadFieldNode;
import org.graalvm.compiler.nodes.memory.MemoryKill;
Expand Down Expand Up @@ -101,6 +106,8 @@
import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.hotspot.HotSpotConstantPool;
import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.JavaField;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.JavaType;
Expand Down Expand Up @@ -175,36 +182,9 @@ protected boolean shouldLoadClass(String className) {
if (className.equals("module-info") || className.startsWith("META-INF.versions.")) {
return false;
}
// @formatter:off
/*
* Work around to prevent:
*
* org.graalvm.compiler.debug.GraalError: java.lang.IllegalAccessError: class org.graalvm.compiler.serviceprovider.GraalServices$Lazy (in module
* jdk.internal.vm.compiler) cannot access class java.lang.management.ManagementFactory (in module java.management) because module
* jdk.internal.vm.compiler does not read module java.management
* at jdk.internal.vm.compiler/org.graalvm.compiler.debug.GraalError.shouldNotReachHere(GraalError.java:55)
* at org.graalvm.compiler.core.test.CheckGraalInvariants$InvariantsTool.handleClassLoadingException(CheckGraalInvariants.java:149)
* at org.graalvm.compiler.core.test.CheckGraalInvariants.initializeClasses(CheckGraalInvariants.java:321)
* at org.graalvm.compiler.core.test.CheckGraalInvariants.runTest(CheckGraalInvariants.java:239)
*
* which occurs because JDK8 overlays are in modular jars. They are never used normally.
*/
// @formatter:on
if (className.equals("org.graalvm.compiler.serviceprovider.GraalServices$Lazy")) {
return false;
}

return true;
}

protected void handleClassLoadingException(Throwable t) {
GraalError.shouldNotReachHere(t);
}

protected void handleParsingException(Throwable t) {
GraalError.shouldNotReachHere(t);
}

public boolean shouldVerifyFoldableMethods() {
return true;
}
Expand Down Expand Up @@ -260,6 +240,7 @@ public static void runTest(InvariantsTool tool) {

PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
Plugins plugins = new Plugins(new InvocationPlugins());
plugins.setClassInitializationPlugin(new DoNotInitializeClassInitializationPlugin());
GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
Expand Down Expand Up @@ -394,8 +375,7 @@ public static void runTest(InvariantsTool tool) {
if (errors.isEmpty()) {
// Order outer classes before the inner classes
classNames.sort((String a, String b) -> a.compareTo(b));
// Initialize classes in single thread to avoid deadlocking issues during initialization
List<Class<?>> classes = initializeClasses(tool, classNames);
List<Class<?>> classes = loadClasses(tool, classNames);
for (Class<?> c : classes) {
String className = c.getName();
executor.execute(() -> {
Expand Down Expand Up @@ -438,18 +418,12 @@ public static void runTest(InvariantsTool tool) {
checkGraph(verifiers, context, graph);
} catch (VerificationError e) {
errors.add(e.getMessage());
} catch (LinkageError e) {
// suppress linkages errors resulting from eager resolution
} catch (BailoutException e) {
// Graal bail outs on certain patterns in Java bytecode
// (e.g.,
// unbalanced monitors introduced by jacoco).
} catch (Throwable e) {
try {
tool.handleParsingException(e);
} catch (Throwable t) {
errors.add(String.format("Error while checking %s:%n%s", methodName, printStackTraceToString(e)));
}
errors.add(String.format("Error while checking %s:%n%s", methodName, printStackTraceToString(e)));
}
}
});
Expand Down Expand Up @@ -560,27 +534,19 @@ private static boolean isGSON(String className) {
return className.contains("com.google.gson");
}

private static List<Class<?>> initializeClasses(InvariantsTool tool, List<String> classNames) {
private static List<Class<?>> loadClasses(InvariantsTool tool, List<String> classNames) {
List<Class<?>> classes = new ArrayList<>(classNames.size());
for (String className : classNames) {
if (!tool.shouldLoadClass(className)) {
continue;
}
try {
Class<?> c = Class.forName(className, true, CheckGraalInvariants.class.getClassLoader());
Class<?> c = Class.forName(className, false, CheckGraalInvariants.class.getClassLoader());
classes.add(c);
} catch (UnsupportedClassVersionError e) {
// graal-test.jar can contain classes compiled for different Java versions
} catch (NoClassDefFoundError e) {
if (!e.getMessage().contains("Could not initialize class")) {
throw e;
} else {
// A second or later attempt to initialize a class
// results in this confusing error where the
// original cause of initialization failure is lost
}
} catch (Throwable t) {
tool.handleClassLoadingException(t);
GraalError.shouldNotReachHere(t);
}
}
return classes;
Expand Down Expand Up @@ -761,3 +727,21 @@ boolean test21(ArithmeticOpTable.Op f) {
}
}
}

class DoNotInitializeClassInitializationPlugin implements ClassInitializationPlugin {

@Override
public boolean supportsLazyInitialization(ConstantPool cp) {
return true;
}

@Override
public void loadReferencedType(GraphBuilderContext builder, ConstantPool cp, int cpi, int bytecode) {
((HotSpotConstantPool) cp).loadReferencedType(cpi, bytecode, false);
}

@Override
public boolean apply(GraphBuilderContext builder, ResolvedJavaType type, Supplier<FrameState> frameState, ValueNode[] classInit) {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ protected void verify(StructuredGraph graph, CoreProviders context) {
ResolvedJavaMethod method = graph.method();
ResolvedJavaType restrictedType = context.getMetaAccess().lookupJavaType(restrictedClass);

if (method.getDeclaringClass().equals(restrictedType)) {
// Allow violation in methods of the restricted type itself.
if (restrictedType.isAssignableFrom(method.getDeclaringClass())) {
// Allow violation in methods of the restricted type itself and its subclasses.
} else if (isIllegalUsage(method, cn.getX(), cn.getY(), context.getMetaAccess()) || isIllegalUsage(method, cn.getY(), cn.getX(), context.getMetaAccess())) {
throw new VerificationError("Verification of " + restrictedClass.getName() + " usage failed: Comparing " + cn.getX() + " and " + cn.getY() + " in " + method +
" must use .equals() for object equality, not '==' or '!='");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1571,7 +1571,7 @@ private static Breakpoint installBreakpoint(JNIEnvironment jni, BreakpointSpecif
return null;
}
Breakpoint bp = new Breakpoint(br, clazz, method);
guarantee(map.put(method.rawValue(), bp) == null, "Duplicate breakpoint: " + bp);
guarantee(map.put(method.rawValue(), bp) == null, "Duplicate breakpoint: %s", bp);
return bp;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ final class AlignedChunk extends Chunk {

public long allocate(ImageHeapObject obj, boolean writable) {
long size = obj.getSize();
VMError.guarantee(size <= getUnallocatedBytes(), "Object of size " + size + " does not fit in the chunk's remaining bytes");
VMError.guarantee(size <= getUnallocatedBytes(), "Object of size %s does not fit in the chunk's remaining bytes", size);
long objStart = getTop();
topOffset += size;
objects.add(obj);
Expand Down Expand Up @@ -226,7 +226,7 @@ public void alignInAlignedChunk(int multiple) {
if (!currentAlignedChunk.tryAlignTop(multiple)) {
startNewAlignedChunk();
boolean aligned = currentAlignedChunk.tryAlignTop(multiple);
VMError.guarantee(aligned, "Cannot align to " + multiple + " bytes within an aligned chunk's object area");
VMError.guarantee(aligned, "Cannot align to %s bytes within an aligned chunk's object area", multiple);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ private void anchorReturnValue() {

int nodesAnchored = anchorNodes(this);
if (leaveAction == LeaveAction.ExceptionAbort) {
VMError.guarantee(nodesAnchored == 0, "Unexpected values were anchored in method " + graph().method().format("%H.%n(%p)") + " as ExceptionAbort must not have any return value.");
VMError.guarantee(nodesAnchored == 0, "Unexpected values were anchored in method %s as ExceptionAbort must not have any return value.", graph().method());
} else {
VMError.guarantee(nodesAnchored == 1, "An unexpected number of values was anchored in method " + graph().method().format("%H.%n(%p)"));
VMError.guarantee(nodesAnchored == 1, "An unexpected number of values was anchored in method %s", graph().method());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ private ForeignCallDescriptor lookupBytecodeException(BytecodeExceptionKind exce
}
outArguments.addAll(exceptionArguments);
}
VMError.guarantee(descriptor != null, "No ForeignCallDescriptor for ByteCodeExceptionKind " + exceptionKind);
VMError.guarantee(descriptor != null, "No ForeignCallDescriptor for ByteCodeExceptionKind %s", exceptionKind);
assert descriptor.getArgumentTypes().length == outArguments.size();
return descriptor;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private void addGCCauseMapping() {
while (HostedGCCauseList.size() <= id) {
HostedGCCauseList.add(null);
}
VMError.guarantee(HostedGCCauseList.get(id) == null, name + " and another GCCause have the same id.");
VMError.guarantee(HostedGCCauseList.get(id) == null, "%s and another GCCause have the same id.", name);
HostedGCCauseList.set(id, this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ protected static void rerunClassInit(FeatureAccess access, String... classNames)

protected static Class<?> clazz(FeatureAccess access, String className) {
Class<?> classByName = access.findClassByName(className);
VMError.guarantee(classByName != null, "class " + className + " not found");
VMError.guarantee(classByName != null, "class %s not found", className);
return classByName;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public void duringSetup(DuringSetupAccess access) {
JavaNetSubstitutions.defaultProtocols.forEach(protocol -> {
if (!disabledURLProtocols.contains(protocol)) {
boolean registered = JavaNetSubstitutions.addURLStreamHandler(protocol);
VMError.guarantee(registered, "The URL protocol " + protocol + " is not available.");
VMError.guarantee(registered, "The URL protocol %s is not available.", protocol);
}
});

Expand All @@ -155,7 +155,7 @@ public void duringSetup(DuringSetupAccess access) {
"The option " + JavaNetSubstitutions.enableProtocolsOption + protocol + " is not needed.");
} else if (JavaNetSubstitutions.onDemandProtocols.contains(protocol)) {
boolean registered = JavaNetSubstitutions.addURLStreamHandler(protocol);
VMError.guarantee(registered, "The URL protocol " + protocol + " is not available.");
VMError.guarantee(registered, "The URL protocol %s is not available.", protocol);
} else {
printWarning("The URL protocol " + protocol + " is not tested and might not work as expected." +
System.lineSeparator() + JavaNetSubstitutions.supportedProtocols());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private static SubstrateForeignCallDescriptor findForeignCall(String descriptorN
LocationIdentity... additionalKilledLocations) {
Method method = findMethod(declaringClass, methodName);
SubstrateForeignCallTarget foreignCallTargetAnnotation = AnnotationAccess.getAnnotation(method, SubstrateForeignCallTarget.class);
VMError.guarantee(foreignCallTargetAnnotation != null, "Add missing @SubstrateForeignCallTarget to " + declaringClass.getName() + "." + methodName);
VMError.guarantee(foreignCallTargetAnnotation != null, "Add missing @SubstrateForeignCallTarget to %s.%s", declaringClass.getName(), methodName);

boolean isUninterruptible = Uninterruptible.Utils.isUninterruptible(method);
boolean isFullyUninterruptible = foreignCallTargetAnnotation.fullyUninterruptible();
Expand All @@ -86,7 +86,7 @@ private static SubstrateForeignCallDescriptor findForeignJdkCall(String descript
boolean isFullyUninterruptible, LocationIdentity... additionalKilledLocations) {
Method method = findMethod(declaringClass, methodName);
SubstrateForeignCallTarget foreignCallTargetAnnotation = AnnotationAccess.getAnnotation(method, SubstrateForeignCallTarget.class);
VMError.guarantee(foreignCallTargetAnnotation == null, declaringClass.getName() + "." + methodName + " must not be annotated with @SubstrateForeignCallTarget.");
VMError.guarantee(foreignCallTargetAnnotation == null, "%s.%s must not be annotated with @SubstrateForeignCallTarget.", declaringClass.getName(), methodName);

return findForeignCall(descriptorName, method, isReexecutable, isUninterruptible, isFullyUninterruptible, additionalKilledLocations);
}
Expand All @@ -100,7 +100,7 @@ private static SubstrateForeignCallDescriptor findForeignCall(String descriptorN
*/
LocationIdentity[] killedLocations;
if (isFullyUninterruptible) {
VMError.guarantee(isUninterruptible, method.toString() + " is fully uninterruptible but not annotated with @Uninterruptible.");
VMError.guarantee(isUninterruptible, "%s is fully uninterruptible but not annotated with @Uninterruptible.", method);
killedLocations = additionalKilledLocations;
} else if (additionalKilledLocations.length == 0 || additionalKilledLocations == TLAB_LOCATIONS) {
killedLocations = TLAB_LOCATIONS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ public void closeOSThreadHandle(OSThreadHandle threadHandle) {
static final Method FORK_JOIN_POOL_TRY_TERMINATE_METHOD;

static {
VMError.guarantee(ImageInfo.inImageBuildtimeCode(), PlatformThreads.class.getSimpleName() + " must be initialized at build time.");
VMError.guarantee(ImageInfo.inImageBuildtimeCode(), "PlatformThreads must be initialized at build time.");
FORK_JOIN_POOL_TRY_TERMINATE_METHOD = ReflectionUtil.lookupMethod(ForkJoinPool.class, "tryTerminate", boolean.class, boolean.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,8 @@ public static void guarantee(boolean condition, String format, Object... args) {
* @param args arguments to process
* @return a copy of {@code args} with certain values converted to strings as described above
*/
public static Object[] formatArguments(Object... args) {
Object[] newArgs = new Object[args.length];
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg instanceof ResolvedJavaType) {
newArgs[i] = ((ResolvedJavaType) arg).toJavaName(true);
} else if (arg instanceof ResolvedJavaMethod) {
newArgs[i] = ((ResolvedJavaMethod) arg).format("%H.%n(%p)");
} else if (arg instanceof ResolvedJavaField) {
newArgs[i] = ((ResolvedJavaField) arg).format("%H.%n");
} else {
newArgs[i] = arg;
}
}
return newArgs;
static Object[] formatArguments(Object... args) {
return VMError.formatArguments(args);
}

/**
Expand Down
Loading