< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java

Print this page
rev 52889 : 8214023: Update Graal
   1 /*
   2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */


  55 import org.graalvm.compiler.debug.DebugContext;
  56 import org.graalvm.compiler.debug.DebugHandlersFactory;
  57 import org.graalvm.compiler.debug.GraalError;
  58 import org.graalvm.compiler.graph.Node;
  59 import org.graalvm.compiler.graph.NodeClass;
  60 import org.graalvm.compiler.java.GraphBuilderPhase;
  61 import org.graalvm.compiler.nodeinfo.NodeInfo;
  62 import org.graalvm.compiler.nodes.PhiNode;
  63 import org.graalvm.compiler.nodes.StructuredGraph;
  64 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  65 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
  66 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
  67 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
  68 import org.graalvm.compiler.options.OptionValues;
  69 import org.graalvm.compiler.phases.OptimisticOptimizations;
  70 import org.graalvm.compiler.phases.PhaseSuite;
  71 import org.graalvm.compiler.phases.VerifyPhase;
  72 import org.graalvm.compiler.phases.VerifyPhase.VerificationError;
  73 import org.graalvm.compiler.phases.contract.VerifyNodeCosts;
  74 import org.graalvm.compiler.phases.tiers.HighTierContext;

  75 import org.graalvm.compiler.phases.util.Providers;
  76 import org.graalvm.compiler.phases.verify.VerifyBailoutUsage;
  77 import org.graalvm.compiler.phases.verify.VerifyCallerSensitiveMethods;
  78 import org.graalvm.compiler.phases.verify.VerifyDebugUsage;
  79 import org.graalvm.compiler.phases.verify.VerifyGetOptionsUsage;
  80 import org.graalvm.compiler.phases.verify.VerifyGraphAddUsage;
  81 import org.graalvm.compiler.phases.verify.VerifyInstanceOfUsage;
  82 import org.graalvm.compiler.phases.verify.VerifyUpdateUsages;
  83 import org.graalvm.compiler.phases.verify.VerifyUsageWithEquals;
  84 import org.graalvm.compiler.phases.verify.VerifyVirtualizableUsage;
  85 import org.graalvm.compiler.runtime.RuntimeProvider;
  86 import jdk.internal.vm.compiler.word.LocationIdentity;
  87 import org.junit.Assert;
  88 import org.junit.Assume;
  89 import org.junit.Test;
  90 
  91 import jdk.vm.ci.code.BailoutException;
  92 import jdk.vm.ci.code.Register;
  93 import jdk.vm.ci.code.Register.RegisterCategory;
  94 import jdk.vm.ci.meta.JavaField;
  95 import jdk.vm.ci.meta.JavaMethod;
  96 import jdk.vm.ci.meta.JavaType;
  97 import jdk.vm.ci.meta.MetaAccessProvider;
  98 import jdk.vm.ci.meta.ResolvedJavaMethod;
  99 import jdk.vm.ci.meta.ResolvedJavaType;
 100 import jdk.vm.ci.meta.Value;
 101 
 102 /**
 103  * Checks that all classes in *graal*.jar and *jvmci*.jar entries on the boot class path comply with
 104  * global invariants such as using {@link Object#equals(Object)} to compare certain types instead of


 159                  *     at org.graalvm.compiler.core.test.CheckGraalInvariants.initializeClasses(CheckGraalInvariants.java:321)
 160                  *     at org.graalvm.compiler.core.test.CheckGraalInvariants.runTest(CheckGraalInvariants.java:239)
 161                  *
 162                  * which occurs because JDK8 overlays are in modular jars. They are never used normally.
 163                  */
 164                 // @formatter:on
 165                 if (className.equals("org.graalvm.compiler.serviceprovider.GraalServices$Lazy")) {
 166                     return false;
 167                 }
 168             }
 169             return true;
 170         }
 171 
 172         protected void handleClassLoadingException(Throwable t) {
 173             GraalError.shouldNotReachHere(t);
 174         }
 175 
 176         protected void handleParsingException(Throwable t) {
 177             GraalError.shouldNotReachHere(t);
 178         }




 179     }
 180 
 181     @Test
 182     @SuppressWarnings("try")
 183     public void test() {
 184         assumeManagementLibraryIsLoadable();
 185         runTest(new InvariantsTool());
 186     }
 187 
 188     @SuppressWarnings("try")
 189     public static void runTest(InvariantsTool tool) {
 190         RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class);
 191         Providers providers = rt.getHostBackend().getProviders();
 192         MetaAccessProvider metaAccess = providers.getMetaAccess();
 193 
 194         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
 195         Plugins plugins = new Plugins(new InvocationPlugins());
 196         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
 197         graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
 198         HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);


 202         String bootclasspath = tool.getClassPath();
 203         Assert.assertNotNull("Cannot find boot class path", bootclasspath);
 204 
 205         final List<String> classNames = new ArrayList<>();
 206         for (String path : bootclasspath.split(File.pathSeparator)) {
 207             if (tool.shouldProcess(path)) {
 208                 try {
 209                     final ZipFile zipFile = new ZipFile(new File(path));
 210                     for (final Enumeration<? extends ZipEntry> entry = zipFile.entries(); entry.hasMoreElements();) {
 211                         final ZipEntry zipEntry = entry.nextElement();
 212                         String name = zipEntry.getName();
 213                         if (name.endsWith(".class") && !name.startsWith("META-INF/versions/")) {
 214                             String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
 215                             if (isInNativeImage(className)) {
 216                                 /*
 217                                  * Native Image is an external tool and does not need to follow the
 218                                  * Graal invariants.
 219                                  */
 220                                 continue;
 221                             }






 222                             classNames.add(className);
 223                         }
 224                     }
 225                 } catch (IOException ex) {
 226                     Assert.fail(ex.toString());
 227                 }
 228             }
 229         }
 230         Assert.assertFalse("Could not find graal jars on boot class path: " + bootclasspath, classNames.isEmpty());
 231 
 232         // Allows a subset of methods to be checked through use of a system property
 233         String property = System.getProperty(CheckGraalInvariants.class.getName() + ".filters");
 234         String[] filters = property == null ? null : property.split(",");
 235 
 236         OptionValues options = getInitialOptions();
 237         CompilerThreadFactory factory = new CompilerThreadFactory("CheckInvariantsThread");
 238         int availableProcessors = Runtime.getRuntime().availableProcessors();
 239         ThreadPoolExecutor executor = new ThreadPoolExecutor(availableProcessors, availableProcessors, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
 240 
 241         List<String> errors = Collections.synchronizedList(new ArrayList<>());
 242 





























 243         for (Method m : BadUsageWithEquals.class.getDeclaredMethods()) {
 244             ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
 245             try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
 246                 StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).method(method).build();
 247                 try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
 248                     graphBuilderSuite.apply(graph, context);
 249                     // update phi stamps
 250                     graph.getNodes().filter(PhiNode.class).forEach(PhiNode::inferStamp);
 251                     checkGraph(context, graph);
 252                     errors.add(String.format("Expected error while checking %s", m));
 253                 } catch (VerificationError e) {
 254                     // expected!
 255                 } catch (Throwable e) {
 256                     errors.add(String.format("Error while checking %s:%n%s", m, printStackTraceToString(e)));
 257                 }
 258             }
 259         }
 260         if (errors.isEmpty()) {
 261             // Order outer classes before the inner classes
 262             classNames.sort((String a, String b) -> a.compareTo(b));
 263             // Initialize classes in single thread to avoid deadlocking issues during initialization
 264             List<Class<?>> classes = initializeClasses(tool, classNames);
 265             for (Class<?> c : classes) {
 266                 String className = c.getName();
 267                 executor.execute(() -> {
 268                     try {
 269                         checkClass(c, metaAccess);
 270                     } catch (Throwable e) {
 271                         errors.add(String.format("Error while checking %s:%n%s", className, printStackTraceToString(e)));
 272                     }
 273                 });
 274 
 275                 for (Method m : c.getDeclaredMethods()) {
 276                     if (Modifier.isNative(m.getModifiers()) || Modifier.isAbstract(m.getModifiers())) {
 277                         // ignore
 278                     } else {
 279                         String methodName = className + "." + m.getName();
 280                         if (matches(filters, methodName)) {
 281                             executor.execute(() -> {
 282                                 try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
 283                                     ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
 284                                     boolean isSubstitution = method.getAnnotation(Snippet.class) != null || method.getAnnotation(MethodSubstitution.class) != null;
 285                                     StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).setIsSubstitution(isSubstitution).build();
 286                                     try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
 287                                         checkMethod(method);
 288                                         graphBuilderSuite.apply(graph, context);
 289                                         // update phi stamps
 290                                         graph.getNodes().filter(PhiNode.class).forEach(PhiNode::inferStamp);
 291                                         checkGraph(context, graph);
 292                                     } catch (VerificationError e) {
 293                                         errors.add(e.getMessage());
 294                                     } catch (LinkageError e) {
 295                                         // suppress linkages errors resulting from eager resolution
 296                                     } catch (BailoutException e) {
 297                                         // Graal bail outs on certain patterns in Java bytecode
 298                                         // (e.g.,
 299                                         // unbalanced monitors introduced by jacoco).
 300                                     } catch (Throwable e) {
 301                                         try {
 302                                             tool.handleParsingException(e);
 303                                         } catch (Throwable t) {
 304                                             errors.add(String.format("Error while checking %s:%n%s", methodName, printStackTraceToString(e)));
 305                                         }
 306                                     }
 307                                 }
 308                             });
 309                         }
 310                     }
 311                 }
 312             }

 313             executor.shutdown();
 314             try {
 315                 executor.awaitTermination(1, TimeUnit.HOURS);
 316             } catch (InterruptedException e1) {
 317                 throw new RuntimeException(e1);
 318             }








 319         }
 320         if (!errors.isEmpty()) {
 321             StringBuilder msg = new StringBuilder();
 322             String nl = String.format("%n");
 323             for (String e : errors) {
 324                 if (msg.length() != 0) {
 325                     msg.append(nl);
 326                 }
 327                 msg.append(e);
 328             }
 329             Assert.fail(msg.toString());
 330         }
 331     }
 332 
 333     private static boolean isInNativeImage(String className) {
 334         return className.startsWith("org.graalvm.nativeimage");
 335     }
 336 




 337     private static List<Class<?>> initializeClasses(InvariantsTool tool, List<String> classNames) {
 338         List<Class<?>> classes = new ArrayList<>(classNames.size());
 339         for (String className : classNames) {
 340             if (!tool.shouldLoadClass(className)) {
 341                 continue;
 342             }
 343             try {
 344                 Class<?> c = Class.forName(className, true, CheckGraalInvariants.class.getClassLoader());
 345                 classes.add(c);
 346             } catch (Throwable t) {
 347                 tool.handleClassLoadingException(t);
 348             }
 349         }
 350         return classes;
 351     }
 352 
 353     /**
 354      * @param metaAccess
 355      */
 356     private static void checkClass(Class<?> c, MetaAccessProvider metaAccess) {


 365     private static void checkMethod(ResolvedJavaMethod method) {
 366         if (method.getAnnotation(Snippet.class) == null) {
 367             Annotation[][] parameterAnnotations = method.getParameterAnnotations();
 368             for (int i = 0; i < parameterAnnotations.length; i++) {
 369                 for (Annotation a : parameterAnnotations[i]) {
 370                     Class<? extends Annotation> annotationType = a.annotationType();
 371                     if (annotationType == ConstantParameter.class || annotationType == VarargsParameter.class || annotationType == NonNullParameter.class) {
 372                         VerificationError verificationError = new VerificationError("Parameter %d of %s is annotated with %s but the method is not annotated with %s", i, method,
 373                                         annotationType.getSimpleName(),
 374                                         Snippet.class.getSimpleName());
 375                         throw verificationError;
 376                     }
 377                 }
 378             }
 379         }
 380     }
 381 
 382     /**
 383      * Checks the invariants for a single graph.
 384      */
 385     private static void checkGraph(HighTierContext context, StructuredGraph graph) {
 386         if (shouldVerifyEquals(graph.method())) {
 387             // If you add a new type to test here, be sure to add appropriate
 388             // methods to the BadUsageWithEquals class below
 389             new VerifyUsageWithEquals(Value.class).apply(graph, context);
 390             new VerifyUsageWithEquals(Register.class).apply(graph, context);
 391             new VerifyUsageWithEquals(RegisterCategory.class).apply(graph, context);
 392             new VerifyUsageWithEquals(JavaType.class).apply(graph, context);
 393             new VerifyUsageWithEquals(JavaMethod.class).apply(graph, context);
 394             new VerifyUsageWithEquals(JavaField.class).apply(graph, context);
 395             new VerifyUsageWithEquals(LocationIdentity.class).apply(graph, context);
 396             new VerifyUsageWithEquals(LIRKind.class).apply(graph, context);
 397             new VerifyUsageWithEquals(ArithmeticOpTable.class).apply(graph, context);
 398             new VerifyUsageWithEquals(ArithmeticOpTable.Op.class).apply(graph, context);
 399         }
 400         new VerifyDebugUsage().apply(graph, context);
 401         new VerifyCallerSensitiveMethods().apply(graph, context);
 402         new VerifyVirtualizableUsage().apply(graph, context);
 403         new VerifyUpdateUsages().apply(graph, context);
 404         new VerifyBailoutUsage().apply(graph, context);
 405         new VerifyInstanceOfUsage().apply(graph, context);
 406         new VerifyGraphAddUsage().apply(graph, context);
 407         new VerifyGetOptionsUsage().apply(graph, context);
 408         if (graph.method().isBridge()) {
 409             BridgeMethodUtils.getBridgedMethod(graph.method());
 410         }
 411     }
 412 
 413     private static boolean matches(String[] filters, String s) {
 414         if (filters == null || filters.length == 0) {
 415             return true;
 416         }
 417         for (String filter : filters) {
 418             if (s.contains(filter)) {
 419                 return true;
 420             }
 421         }
 422         return false;
 423     }
 424 
 425     private static String printStackTraceToString(Throwable t) {
 426         StringWriter sw = new StringWriter();
 427         t.printStackTrace(new PrintWriter(sw));


   1 /*
   2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */


  55 import org.graalvm.compiler.debug.DebugContext;
  56 import org.graalvm.compiler.debug.DebugHandlersFactory;
  57 import org.graalvm.compiler.debug.GraalError;
  58 import org.graalvm.compiler.graph.Node;
  59 import org.graalvm.compiler.graph.NodeClass;
  60 import org.graalvm.compiler.java.GraphBuilderPhase;
  61 import org.graalvm.compiler.nodeinfo.NodeInfo;
  62 import org.graalvm.compiler.nodes.PhiNode;
  63 import org.graalvm.compiler.nodes.StructuredGraph;
  64 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  65 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
  66 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
  67 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
  68 import org.graalvm.compiler.options.OptionValues;
  69 import org.graalvm.compiler.phases.OptimisticOptimizations;
  70 import org.graalvm.compiler.phases.PhaseSuite;
  71 import org.graalvm.compiler.phases.VerifyPhase;
  72 import org.graalvm.compiler.phases.VerifyPhase.VerificationError;
  73 import org.graalvm.compiler.phases.contract.VerifyNodeCosts;
  74 import org.graalvm.compiler.phases.tiers.HighTierContext;
  75 import org.graalvm.compiler.phases.tiers.PhaseContext;
  76 import org.graalvm.compiler.phases.util.Providers;









  77 import org.graalvm.compiler.runtime.RuntimeProvider;
  78 import jdk.internal.vm.compiler.word.LocationIdentity;
  79 import org.junit.Assert;
  80 import org.junit.Assume;
  81 import org.junit.Test;
  82 
  83 import jdk.vm.ci.code.BailoutException;
  84 import jdk.vm.ci.code.Register;
  85 import jdk.vm.ci.code.Register.RegisterCategory;
  86 import jdk.vm.ci.meta.JavaField;
  87 import jdk.vm.ci.meta.JavaMethod;
  88 import jdk.vm.ci.meta.JavaType;
  89 import jdk.vm.ci.meta.MetaAccessProvider;
  90 import jdk.vm.ci.meta.ResolvedJavaMethod;
  91 import jdk.vm.ci.meta.ResolvedJavaType;
  92 import jdk.vm.ci.meta.Value;
  93 
  94 /**
  95  * Checks that all classes in *graal*.jar and *jvmci*.jar entries on the boot class path comply with
  96  * global invariants such as using {@link Object#equals(Object)} to compare certain types instead of


 151                  *     at org.graalvm.compiler.core.test.CheckGraalInvariants.initializeClasses(CheckGraalInvariants.java:321)
 152                  *     at org.graalvm.compiler.core.test.CheckGraalInvariants.runTest(CheckGraalInvariants.java:239)
 153                  *
 154                  * which occurs because JDK8 overlays are in modular jars. They are never used normally.
 155                  */
 156                 // @formatter:on
 157                 if (className.equals("org.graalvm.compiler.serviceprovider.GraalServices$Lazy")) {
 158                     return false;
 159                 }
 160             }
 161             return true;
 162         }
 163 
 164         protected void handleClassLoadingException(Throwable t) {
 165             GraalError.shouldNotReachHere(t);
 166         }
 167 
 168         protected void handleParsingException(Throwable t) {
 169             GraalError.shouldNotReachHere(t);
 170         }
 171 
 172         public boolean shouldVerifyFoldableMethods() {
 173             return true;
 174         }
 175     }
 176 
 177     @Test
 178     @SuppressWarnings("try")
 179     public void test() {
 180         assumeManagementLibraryIsLoadable();
 181         runTest(new InvariantsTool());
 182     }
 183 
 184     @SuppressWarnings("try")
 185     public static void runTest(InvariantsTool tool) {
 186         RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class);
 187         Providers providers = rt.getHostBackend().getProviders();
 188         MetaAccessProvider metaAccess = providers.getMetaAccess();
 189 
 190         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
 191         Plugins plugins = new Plugins(new InvocationPlugins());
 192         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
 193         graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
 194         HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);


 198         String bootclasspath = tool.getClassPath();
 199         Assert.assertNotNull("Cannot find boot class path", bootclasspath);
 200 
 201         final List<String> classNames = new ArrayList<>();
 202         for (String path : bootclasspath.split(File.pathSeparator)) {
 203             if (tool.shouldProcess(path)) {
 204                 try {
 205                     final ZipFile zipFile = new ZipFile(new File(path));
 206                     for (final Enumeration<? extends ZipEntry> entry = zipFile.entries(); entry.hasMoreElements();) {
 207                         final ZipEntry zipEntry = entry.nextElement();
 208                         String name = zipEntry.getName();
 209                         if (name.endsWith(".class") && !name.startsWith("META-INF/versions/")) {
 210                             String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
 211                             if (isInNativeImage(className)) {
 212                                 /*
 213                                  * Native Image is an external tool and does not need to follow the
 214                                  * Graal invariants.
 215                                  */
 216                                 continue;
 217                             }
 218                             if (isGSON(className)) {
 219                                 /*
 220                                  * GSON classes are compiled with old JDK
 221                                  */
 222                                 continue;
 223                             }
 224                             classNames.add(className);
 225                         }
 226                     }
 227                 } catch (IOException ex) {
 228                     Assert.fail(ex.toString());
 229                 }
 230             }
 231         }
 232         Assert.assertFalse("Could not find graal jars on boot class path: " + bootclasspath, classNames.isEmpty());
 233 
 234         // Allows a subset of methods to be checked through use of a system property
 235         String property = System.getProperty(CheckGraalInvariants.class.getName() + ".filters");
 236         String[] filters = property == null ? null : property.split(",");
 237 
 238         OptionValues options = getInitialOptions();
 239         CompilerThreadFactory factory = new CompilerThreadFactory("CheckInvariantsThread");
 240         int availableProcessors = Runtime.getRuntime().availableProcessors();
 241         ThreadPoolExecutor executor = new ThreadPoolExecutor(availableProcessors, availableProcessors, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
 242 
 243         List<String> errors = Collections.synchronizedList(new ArrayList<>());
 244 
 245         List<VerifyPhase<PhaseContext>> verifiers = new ArrayList<>();
 246 
 247         // If you add a new type to test here, be sure to add appropriate
 248         // methods to the BadUsageWithEquals class below
 249         verifiers.add(new VerifyUsageWithEquals(Value.class));
 250         verifiers.add(new VerifyUsageWithEquals(Register.class));
 251         verifiers.add(new VerifyUsageWithEquals(RegisterCategory.class));
 252         verifiers.add(new VerifyUsageWithEquals(JavaType.class));
 253         verifiers.add(new VerifyUsageWithEquals(JavaMethod.class));
 254         verifiers.add(new VerifyUsageWithEquals(JavaField.class));
 255         verifiers.add(new VerifyUsageWithEquals(LocationIdentity.class));
 256         verifiers.add(new VerifyUsageWithEquals(LIRKind.class));
 257         verifiers.add(new VerifyUsageWithEquals(ArithmeticOpTable.class));
 258         verifiers.add(new VerifyUsageWithEquals(ArithmeticOpTable.Op.class));
 259 
 260         verifiers.add(new VerifyDebugUsage());
 261         verifiers.add(new VerifyCallerSensitiveMethods());
 262         verifiers.add(new VerifyVirtualizableUsage());
 263         verifiers.add(new VerifyUpdateUsages());
 264         verifiers.add(new VerifyBailoutUsage());
 265         verifiers.add(new VerifyInstanceOfUsage());
 266         verifiers.add(new VerifyGraphAddUsage());
 267         verifiers.add(new VerifyGetOptionsUsage());
 268 
 269         VerifyFoldableMethods foldableMethodsVerifier = new VerifyFoldableMethods();
 270         if (tool.shouldVerifyFoldableMethods()) {
 271             verifiers.add(foldableMethodsVerifier);
 272         }
 273 
 274         for (Method m : BadUsageWithEquals.class.getDeclaredMethods()) {
 275             ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
 276             try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
 277                 StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).method(method).build();
 278                 try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
 279                     graphBuilderSuite.apply(graph, context);
 280                     // update phi stamps
 281                     graph.getNodes().filter(PhiNode.class).forEach(PhiNode::inferStamp);
 282                     checkGraph(verifiers, context, graph);
 283                     errors.add(String.format("Expected error while checking %s", m));
 284                 } catch (VerificationError e) {
 285                     // expected!
 286                 } catch (Throwable e) {
 287                     errors.add(String.format("Error while checking %s:%n%s", m, printStackTraceToString(e)));
 288                 }
 289             }
 290         }
 291         if (errors.isEmpty()) {
 292             // Order outer classes before the inner classes
 293             classNames.sort((String a, String b) -> a.compareTo(b));
 294             // Initialize classes in single thread to avoid deadlocking issues during initialization
 295             List<Class<?>> classes = initializeClasses(tool, classNames);
 296             for (Class<?> c : classes) {
 297                 String className = c.getName();
 298                 executor.execute(() -> {
 299                     try {
 300                         checkClass(c, metaAccess);
 301                     } catch (Throwable e) {
 302                         errors.add(String.format("Error while checking %s:%n%s", className, printStackTraceToString(e)));
 303                     }
 304                 });
 305 
 306                 for (Method m : c.getDeclaredMethods()) {
 307                     if (Modifier.isNative(m.getModifiers()) || Modifier.isAbstract(m.getModifiers())) {
 308                         // ignore
 309                     } else {
 310                         String methodName = className + "." + m.getName();
 311                         if (matches(filters, methodName)) {
 312                             executor.execute(() -> {
 313                                 try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
 314                                     ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
 315                                     boolean isSubstitution = method.getAnnotation(Snippet.class) != null || method.getAnnotation(MethodSubstitution.class) != null;
 316                                     StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).setIsSubstitution(isSubstitution).build();
 317                                     try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
 318                                         checkMethod(method);
 319                                         graphBuilderSuite.apply(graph, context);
 320                                         // update phi stamps
 321                                         graph.getNodes().filter(PhiNode.class).forEach(PhiNode::inferStamp);
 322                                         checkGraph(verifiers, context, graph);
 323                                     } catch (VerificationError e) {
 324                                         errors.add(e.getMessage());
 325                                     } catch (LinkageError e) {
 326                                         // suppress linkages errors resulting from eager resolution
 327                                     } catch (BailoutException e) {
 328                                         // Graal bail outs on certain patterns in Java bytecode
 329                                         // (e.g.,
 330                                         // unbalanced monitors introduced by jacoco).
 331                                     } catch (Throwable e) {
 332                                         try {
 333                                             tool.handleParsingException(e);
 334                                         } catch (Throwable t) {
 335                                             errors.add(String.format("Error while checking %s:%n%s", methodName, printStackTraceToString(e)));
 336                                         }
 337                                     }
 338                                 }
 339                             });
 340                         }
 341                     }
 342                 }
 343             }
 344 
 345             executor.shutdown();
 346             try {
 347                 executor.awaitTermination(1, TimeUnit.HOURS);
 348             } catch (InterruptedException e1) {
 349                 throw new RuntimeException(e1);
 350             }
 351 
 352             if (tool.shouldVerifyFoldableMethods()) {
 353                 try {
 354                     foldableMethodsVerifier.finish();
 355                 } catch (Throwable e) {
 356                     errors.add(e.getMessage());
 357                 }
 358             }
 359         }
 360         if (!errors.isEmpty()) {
 361             StringBuilder msg = new StringBuilder();
 362             String nl = String.format("%n");
 363             for (String e : errors) {
 364                 if (msg.length() != 0) {
 365                     msg.append(nl);
 366                 }
 367                 msg.append(e);
 368             }
 369             Assert.fail(msg.toString());
 370         }
 371     }
 372 
 373     private static boolean isInNativeImage(String className) {
 374         return className.startsWith("org.graalvm.nativeimage");
 375     }
 376 
 377     private static boolean isGSON(String className) {
 378         return className.contains("com.google.gson");
 379     }
 380 
 381     private static List<Class<?>> initializeClasses(InvariantsTool tool, List<String> classNames) {
 382         List<Class<?>> classes = new ArrayList<>(classNames.size());
 383         for (String className : classNames) {
 384             if (!tool.shouldLoadClass(className)) {
 385                 continue;
 386             }
 387             try {
 388                 Class<?> c = Class.forName(className, true, CheckGraalInvariants.class.getClassLoader());
 389                 classes.add(c);
 390             } catch (Throwable t) {
 391                 tool.handleClassLoadingException(t);
 392             }
 393         }
 394         return classes;
 395     }
 396 
 397     /**
 398      * @param metaAccess
 399      */
 400     private static void checkClass(Class<?> c, MetaAccessProvider metaAccess) {


 409     private static void checkMethod(ResolvedJavaMethod method) {
 410         if (method.getAnnotation(Snippet.class) == null) {
 411             Annotation[][] parameterAnnotations = method.getParameterAnnotations();
 412             for (int i = 0; i < parameterAnnotations.length; i++) {
 413                 for (Annotation a : parameterAnnotations[i]) {
 414                     Class<? extends Annotation> annotationType = a.annotationType();
 415                     if (annotationType == ConstantParameter.class || annotationType == VarargsParameter.class || annotationType == NonNullParameter.class) {
 416                         VerificationError verificationError = new VerificationError("Parameter %d of %s is annotated with %s but the method is not annotated with %s", i, method,
 417                                         annotationType.getSimpleName(),
 418                                         Snippet.class.getSimpleName());
 419                         throw verificationError;
 420                     }
 421                 }
 422             }
 423         }
 424     }
 425 
 426     /**
 427      * Checks the invariants for a single graph.
 428      */
 429     private static void checkGraph(List<VerifyPhase<PhaseContext>> verifiers, HighTierContext context, StructuredGraph graph) {
 430         for (VerifyPhase<PhaseContext> verifier : verifiers) {
 431             if (!(verifier instanceof VerifyUsageWithEquals) || shouldVerifyEquals(graph.method())) {
 432                 verifier.apply(graph, context);
 433             } else {
 434                 verifier.apply(graph, context);
 435             }
 436         }















 437         if (graph.method().isBridge()) {
 438             BridgeMethodUtils.getBridgedMethod(graph.method());
 439         }
 440     }
 441 
 442     private static boolean matches(String[] filters, String s) {
 443         if (filters == null || filters.length == 0) {
 444             return true;
 445         }
 446         for (String filter : filters) {
 447             if (s.contains(filter)) {
 448                 return true;
 449             }
 450         }
 451         return false;
 452     }
 453 
 454     private static String printStackTraceToString(Throwable t) {
 455         StringWriter sw = new StringWriter();
 456         t.printStackTrace(new PrintWriter(sw));


< prev index next >