1 /* 2 * Copyright (c) 2016, 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 */ 23 24 25 package org.graalvm.compiler.core.test; 26 27 import static org.graalvm.compiler.core.test.GraalCompilerTest.getInitialOptions; 28 29 import java.lang.reflect.Method; 30 import java.lang.reflect.Modifier; 31 32 import org.graalvm.compiler.api.test.Graal; 33 import org.graalvm.compiler.core.common.PermanentBailoutException; 34 import org.graalvm.compiler.core.common.RetryableBailoutException; 35 import org.graalvm.compiler.debug.DebugCloseable; 36 import org.graalvm.compiler.debug.DebugHandlersFactory; 37 import org.graalvm.compiler.debug.DebugContext; 38 import org.graalvm.compiler.debug.GraalError; 39 import org.graalvm.compiler.java.GraphBuilderPhase; 40 import org.graalvm.compiler.nodes.StructuredGraph; 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.options.OptionValues; 45 import org.graalvm.compiler.phases.OptimisticOptimizations; 46 import org.graalvm.compiler.phases.Phase; 47 import org.graalvm.compiler.phases.PhaseSuite; 48 import org.graalvm.compiler.phases.VerifyPhase.VerificationError; 49 import org.graalvm.compiler.phases.tiers.HighTierContext; 50 import org.graalvm.compiler.phases.util.Providers; 51 import org.graalvm.compiler.runtime.RuntimeProvider; 52 import org.junit.Test; 53 54 import jdk.vm.ci.code.BailoutException; 55 import jdk.vm.ci.meta.MetaAccessProvider; 56 import jdk.vm.ci.meta.ResolvedJavaMethod; 57 58 public class VerifyBailoutUsageTest { 59 60 private static class InvalidBailoutUsagePhase1 extends Phase { 61 @Override 62 protected void run(StructuredGraph graph) { 63 throw new BailoutException("Bailout in graph %s", graph); 64 } 65 } 66 67 private static class InvalidBailoutUsagePhase2 extends Phase { 68 @Override 69 protected void run(StructuredGraph graph) { 70 throw new BailoutException(new GraalError("other cause"), "Bailout in graph %s", graph); 71 } 72 } 73 74 private static class InvalidBailoutUsagePhase3 extends Phase { 75 @Override 76 protected void run(StructuredGraph graph) { 77 throw new BailoutException(true/* permanent */, "Bailout in graph %s", graph); 78 } 79 } 80 81 private static class ValidPermanentBailoutUsage extends Phase { 82 @Override 83 protected void run(StructuredGraph graph) { 84 throw new PermanentBailoutException("Valid permanent bailout %s", graph); 85 } 86 } 87 88 private static class ValidRetryableBailoutUsage extends Phase { 89 @Override 90 protected void run(StructuredGraph graph) { 91 throw new RetryableBailoutException("Valid retryable bailout %s", graph); 92 } 93 } 94 95 @Test(expected = VerificationError.class) 96 public void testInvalidBailout01() { 97 testBailoutUsage(InvalidBailoutUsagePhase1.class); 98 } 99 100 @Test(expected = VerificationError.class) 101 public void testInvalidBailout02() { 102 testBailoutUsage(InvalidBailoutUsagePhase2.class); 103 } 104 105 @Test(expected = VerificationError.class) 106 public void testInvalidBailout03() { 107 testBailoutUsage(InvalidBailoutUsagePhase3.class); 108 } 109 110 @Test 111 public void testValidPermanentBailout() { 112 testBailoutUsage(ValidPermanentBailoutUsage.class); 113 } 114 115 @Test 116 public void testValidRetryableBailout() { 117 testBailoutUsage(ValidRetryableBailoutUsage.class); 118 } 119 120 @SuppressWarnings("try") 121 private static void testBailoutUsage(Class<?> c) { 122 RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class); 123 Providers providers = rt.getHostBackend().getProviders(); 124 MetaAccessProvider metaAccess = providers.getMetaAccess(); 125 PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>(); 126 Plugins plugins = new Plugins(new InvocationPlugins()); 127 GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true); 128 graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); 129 HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); 130 OptionValues options = getInitialOptions(); 131 DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER); 132 for (Method m : c.getDeclaredMethods()) { 133 if (!Modifier.isNative(m.getModifiers()) && !Modifier.isAbstract(m.getModifiers())) { 134 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m); 135 StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).build(); 136 graphBuilderSuite.apply(graph, context); 137 try (DebugCloseable s = debug.disableIntercept()) { 138 new VerifyBailoutUsage().apply(graph, context); 139 } 140 } 141 } 142 } 143 }