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