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