1 /*
   2  * Copyright (c) 2015, 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  */
  23 package org.graalvm.compiler.core.test;
  24 
  25 import static org.graalvm.compiler.core.test.GraalCompilerTest.getInitialOptions;
  26 
  27 import java.lang.reflect.Method;
  28 import java.lang.reflect.Modifier;
  29 
  30 import org.junit.Test;
  31 
  32 import org.graalvm.compiler.api.test.Graal;
  33 import org.graalvm.compiler.debug.Debug;
  34 import org.graalvm.compiler.debug.DebugConfigScope;
  35 import org.graalvm.compiler.debug.GraalError;
  36 import org.graalvm.compiler.debug.Indent;
  37 import org.graalvm.compiler.graph.Node;
  38 import org.graalvm.compiler.java.GraphBuilderPhase;
  39 import org.graalvm.compiler.nodes.StructuredGraph;
  40 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
  41 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
  42 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
  43 import org.graalvm.compiler.phases.OptimisticOptimizations;
  44 import org.graalvm.compiler.phases.Phase;
  45 import org.graalvm.compiler.phases.PhaseSuite;
  46 import org.graalvm.compiler.phases.VerifyPhase.VerificationError;
  47 import org.graalvm.compiler.phases.tiers.HighTierContext;
  48 import org.graalvm.compiler.phases.util.Providers;
  49 import org.graalvm.compiler.phases.verify.VerifyDebugUsage;
  50 import org.graalvm.compiler.runtime.RuntimeProvider;
  51 
  52 import jdk.vm.ci.meta.MetaAccessProvider;
  53 import jdk.vm.ci.meta.ResolvedJavaMethod;
  54 
  55 public class VerifyDebugUsageTest {
  56 
  57     private static class InvalidLogUsagePhase extends Phase {
  58 
  59         @Override
  60         protected void run(StructuredGraph graph) {
  61             for (Node n : graph.getNodes()) {
  62                 Debug.log("%s", n.toString());
  63             }
  64         }
  65 
  66     }
  67 
  68     private static class InvalidLogAndIndentUsagePhase extends Phase {
  69 
  70         @Override
  71         @SuppressWarnings("try")
  72         protected void run(StructuredGraph graph) {
  73             try (Indent i = Debug.logAndIndent("%s", graph.toString())) {
  74                 for (Node n : graph.getNodes()) {
  75                     Debug.log("%s", n);
  76                 }
  77             }
  78         }
  79 
  80     }
  81 
  82     private static class InvalidDumpUsagePhase extends Phase {
  83 
  84         @Override
  85         protected void run(StructuredGraph graph) {
  86             Debug.dump(Debug.BASIC_LEVEL, graph, "%s", graph.toString());
  87         }
  88     }
  89 
  90     private static class InvalidDumpLevelPhase extends Phase {
  91 
  92         @Override
  93         protected void run(StructuredGraph graph) {
  94             Debug.dump(Debug.VERY_DETAILED_LEVEL + 1, graph, "%s", graph);
  95         }
  96     }
  97 
  98     private static class NonConstantDumpLevelPhase extends Phase {
  99 
 100         @Override
 101         protected void run(StructuredGraph graph) {
 102             Debug.dump(getLevel(), graph, "%s", graph);
 103         }
 104 
 105         int getLevel() {
 106             return 10;
 107         }
 108     }
 109 
 110     private static class InvalidVerifyUsagePhase extends Phase {
 111 
 112         @Override
 113         protected void run(StructuredGraph graph) {
 114             Debug.verify(graph, "%s", graph.toString());
 115         }
 116 
 117     }
 118 
 119     private static class InvalidConcatLogUsagePhase extends Phase {
 120 
 121         @Override
 122         protected void run(StructuredGraph graph) {
 123             for (Node n : graph.getNodes()) {
 124                 Debug.log("error " + n);
 125             }
 126         }
 127 
 128     }
 129 
 130     private static class InvalidConcatLogAndIndentUsagePhase extends Phase {
 131 
 132         @Override
 133         @SuppressWarnings("try")
 134         protected void run(StructuredGraph graph) {
 135             try (Indent i = Debug.logAndIndent("error " + graph)) {
 136                 for (Node n : graph.getNodes()) {
 137                     Debug.log("%s", n);
 138                 }
 139             }
 140         }
 141 
 142     }
 143 
 144     private static class InvalidConcatDumpUsagePhase extends Phase {
 145 
 146         @Override
 147         protected void run(StructuredGraph graph) {
 148             Debug.dump(Debug.BASIC_LEVEL, graph, "error " + graph);
 149         }
 150 
 151     }
 152 
 153     private static class InvalidConcatVerifyUsagePhase extends Phase {
 154 
 155         @Override
 156         protected void run(StructuredGraph graph) {
 157             Debug.verify(graph, "error " + graph);
 158         }
 159 
 160     }
 161 
 162     private static class ValidLogUsagePhase extends Phase {
 163 
 164         @Override
 165         protected void run(StructuredGraph graph) {
 166             for (Node n : graph.getNodes()) {
 167                 Debug.log("%s", n);
 168             }
 169         }
 170 
 171     }
 172 
 173     private static class ValidLogAndIndentUsagePhase extends Phase {
 174 
 175         @Override
 176         @SuppressWarnings("try")
 177         protected void run(StructuredGraph graph) {
 178             try (Indent i = Debug.logAndIndent("%s", graph)) {
 179                 for (Node n : graph.getNodes()) {
 180                     Debug.log("%s", n);
 181                 }
 182             }
 183         }
 184 
 185     }
 186 
 187     private static class ValidDumpUsagePhase extends Phase {
 188 
 189         @Override
 190         protected void run(StructuredGraph graph) {
 191             Debug.dump(Debug.BASIC_LEVEL, graph, "%s", graph);
 192         }
 193 
 194     }
 195 
 196     private static class ValidVerifyUsagePhase extends Phase {
 197 
 198         @Override
 199         protected void run(StructuredGraph graph) {
 200             Debug.verify(graph, "%s", graph);
 201         }
 202 
 203     }
 204 
 205     private static class InvalidGraalErrorGuaranteePhase extends Phase {
 206         @Override
 207         protected void run(StructuredGraph graph) {
 208             GraalError.guarantee(graph.getNodes().count() > 0, "Graph must contain nodes %s %s %s", graph, graph, graph.toString());
 209         }
 210     }
 211 
 212     private static class ValidGraalErrorGuaranteePhase extends Phase {
 213         @Override
 214         protected void run(StructuredGraph graph) {
 215             GraalError.guarantee(graph.getNodes().count() > 0, "Graph must contain nodes %s", graph);
 216         }
 217     }
 218 
 219     public static Object sideEffect;
 220 
 221     private static class InvalidGraalErrorCtorPhase extends Phase {
 222         @Override
 223         protected void run(StructuredGraph graph) {
 224             sideEffect = new GraalError("No Error %s", graph.toString());
 225         }
 226     }
 227 
 228     private static class ValidGraalErrorCtorPhase extends Phase {
 229         @Override
 230         protected void run(StructuredGraph graph) {
 231             sideEffect = new GraalError("Error %s", graph);
 232         }
 233     }
 234 
 235     @Test(expected = VerificationError.class)
 236     public void testLogInvalid() {
 237         testDebugUsageClass(InvalidLogUsagePhase.class);
 238     }
 239 
 240     @Test(expected = VerificationError.class)
 241     public void testLogAndIndentInvalid() {
 242         testDebugUsageClass(InvalidLogAndIndentUsagePhase.class);
 243     }
 244 
 245     @Test(expected = VerificationError.class)
 246     public void testVerifyInvalid() {
 247         testDebugUsageClass(InvalidVerifyUsagePhase.class);
 248     }
 249 
 250     @Test(expected = VerificationError.class)
 251     public void testDumpInvalid() {
 252         testDebugUsageClass(InvalidDumpUsagePhase.class);
 253     }
 254 
 255     @Test(expected = VerificationError.class)
 256     public void testDumpLevelInvalid() {
 257         testDebugUsageClass(InvalidDumpLevelPhase.class);
 258     }
 259 
 260     @Test(expected = VerificationError.class)
 261     public void testDumpNonConstantLevelInvalid() {
 262         testDebugUsageClass(NonConstantDumpLevelPhase.class);
 263     }
 264 
 265     @Test(expected = VerificationError.class)
 266     public void testLogInvalidConcat() {
 267         testDebugUsageClass(InvalidConcatLogUsagePhase.class);
 268     }
 269 
 270     @Test(expected = VerificationError.class)
 271     public void testLogAndIndentInvalidConcat() {
 272         testDebugUsageClass(InvalidConcatLogAndIndentUsagePhase.class);
 273     }
 274 
 275     @Test(expected = VerificationError.class)
 276     public void testVerifyInvalidConcat() {
 277         testDebugUsageClass(InvalidConcatVerifyUsagePhase.class);
 278     }
 279 
 280     @Test(expected = VerificationError.class)
 281     public void testDumpInvalidConcat() {
 282         testDebugUsageClass(InvalidConcatDumpUsagePhase.class);
 283     }
 284 
 285     @Test
 286     public void testLogValid() {
 287         testDebugUsageClass(ValidLogUsagePhase.class);
 288     }
 289 
 290     @Test()
 291     public void testLogAndIndentValid() {
 292         testDebugUsageClass(ValidLogAndIndentUsagePhase.class);
 293     }
 294 
 295     @Test
 296     public void testVerifyValid() {
 297         testDebugUsageClass(ValidVerifyUsagePhase.class);
 298     }
 299 
 300     @Test
 301     public void testDumpValid() {
 302         testDebugUsageClass(ValidDumpUsagePhase.class);
 303     }
 304 
 305     @Test(expected = VerificationError.class)
 306     public void testGraalGuaranteeInvalid() {
 307         testDebugUsageClass(InvalidGraalErrorGuaranteePhase.class);
 308     }
 309 
 310     @Test
 311     public void testGraalGuaranteeValid() {
 312         testDebugUsageClass(ValidGraalErrorGuaranteePhase.class);
 313     }
 314 
 315     @Test(expected = VerificationError.class)
 316     public void testGraalCtorInvalid() {
 317         testDebugUsageClass(InvalidGraalErrorCtorPhase.class);
 318     }
 319 
 320     @Test
 321     public void testGraalCtorValid() {
 322         testDebugUsageClass(ValidGraalErrorCtorPhase.class);
 323     }
 324 
 325     @SuppressWarnings("try")
 326     private static void testDebugUsageClass(Class<?> c) {
 327         RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class);
 328         Providers providers = rt.getHostBackend().getProviders();
 329         MetaAccessProvider metaAccess = providers.getMetaAccess();
 330         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
 331         Plugins plugins = new Plugins(new InvocationPlugins());
 332         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true);
 333         graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
 334         HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
 335         for (Method m : c.getDeclaredMethods()) {
 336             if (!Modifier.isNative(m.getModifiers()) && !Modifier.isAbstract(m.getModifiers())) {
 337                 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
 338                 StructuredGraph graph = new StructuredGraph.Builder(getInitialOptions()).method(method).build();
 339                 graphBuilderSuite.apply(graph, context);
 340                 try (DebugConfigScope s = Debug.disableIntercept()) {
 341                     new VerifyDebugUsage().apply(graph, context);
 342                 }
 343             }
 344         }
 345     }
 346 }