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.debug;
  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.Debug;
  32 import org.graalvm.compiler.debug.DebugConfigScope;
  33 import org.graalvm.compiler.debug.DebugMethodMetrics;
  34 import org.graalvm.compiler.graph.Node;
  35 import org.graalvm.compiler.java.GraphBuilderPhase;
  36 import org.graalvm.compiler.nodes.StructuredGraph;
  37 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
  38 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
  39 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
  40 import org.graalvm.compiler.phases.OptimisticOptimizations;
  41 import org.graalvm.compiler.phases.Phase;
  42 import org.graalvm.compiler.phases.PhaseSuite;
  43 import org.graalvm.compiler.phases.VerifyPhase.VerificationError;
  44 import org.graalvm.compiler.phases.tiers.HighTierContext;
  45 import org.graalvm.compiler.phases.util.Providers;
  46 import org.graalvm.compiler.phases.verify.VerifyDebugUsage;
  47 import org.graalvm.compiler.runtime.RuntimeProvider;
  48 import org.junit.Test;
  49 
  50 import jdk.vm.ci.meta.MetaAccessProvider;
  51 import jdk.vm.ci.meta.ResolvedJavaMethod;
  52 
  53 /**
  54  *
  55  * Tests to verify that the usage of method metrics does not generate compile time overhead through
  56  * eager evaluation of arguments.
  57  */
  58 public class VerifyMethodMetricsTest {
  59 
  60     private static class InvalidCCP_ToString01Inc extends Phase {
  61         @Override
  62         protected void run(StructuredGraph graph) {
  63             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
  64             for (Node n : graph.getNodes()) {
  65                 m.incrementMetric(n.toString());
  66             }
  67         }
  68     }
  69 
  70     private static class InvalidCCP_Concat01Inc extends Phase {
  71         @Override
  72         protected void run(StructuredGraph graph) {
  73             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
  74             for (Node n : graph.getNodes()) {
  75                 m.incrementMetric("a" + n.toString());
  76             }
  77         }
  78     }
  79 
  80     private static class InvalidCCP_ToString02Inc extends Phase {
  81         @Override
  82         protected void run(StructuredGraph graph) {
  83             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
  84             for (Node n : graph.getNodes()) {
  85                 m.incrementMetric("%s", n.toString());
  86             }
  87         }
  88     }
  89 
  90     private static class InvalidCCP_Concat02Inc extends Phase {
  91         private final String s = this.getClass().toGenericString();
  92 
  93         @Override
  94         protected void run(StructuredGraph graph) {
  95             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
  96             for (Node n : graph.getNodes()) {
  97                 m.incrementMetric("%s%s", "a" + s, n);
  98             }
  99         }
 100     }
 101 
 102     private static class ValidCCP_ToStringInc extends Phase {
 103         @Override
 104         protected void run(StructuredGraph graph) {
 105             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 106             for (Node n : graph.getNodes()) {
 107                 m.addToMetric(1, "%s", n);
 108             }
 109         }
 110     }
 111 
 112     private static class ValidCCP_ConcatInc extends Phase {
 113         @Override
 114         protected void run(StructuredGraph graph) {
 115             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 116             for (Node n : graph.getNodes()) {
 117                 m.incrementMetric("%s%s", "a", n);
 118             }
 119         }
 120     }
 121 
 122     private static class InvalidCCP_ToString01Add extends Phase {
 123         @Override
 124         protected void run(StructuredGraph graph) {
 125             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 126             for (Node n : graph.getNodes()) {
 127                 m.addToMetric(1, n.toString());
 128             }
 129         }
 130     }
 131 
 132     private static class InvalidCCP_Concat01Add extends Phase {
 133         @Override
 134         protected void run(StructuredGraph graph) {
 135             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 136             for (Node n : graph.getNodes()) {
 137                 m.addToMetric(1, "a" + n.toString());
 138             }
 139         }
 140     }
 141 
 142     private static class InvalidCCP_ToString02Add extends Phase {
 143         @Override
 144         protected void run(StructuredGraph graph) {
 145             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 146             for (Node n : graph.getNodes()) {
 147                 m.addToMetric(1, "%s", n.toString());
 148             }
 149         }
 150     }
 151 
 152     private static class InvalidCCP_Concat02Add extends Phase {
 153         private final String s = this.getClass().toGenericString();
 154 
 155         @Override
 156         protected void run(StructuredGraph graph) {
 157             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 158             for (Node n : graph.getNodes()) {
 159                 m.addToMetric(1, "%s%s", "a" + s, n);
 160             }
 161         }
 162     }
 163 
 164     private static class ValidCCP_ToStringAdd extends Phase {
 165         @Override
 166         protected void run(StructuredGraph graph) {
 167             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 168             for (Node n : graph.getNodes()) {
 169                 m.addToMetric(1, "%s", n);
 170             }
 171         }
 172     }
 173 
 174     private static class ValidCCP_ConcatAdd extends Phase {
 175         @Override
 176         protected void run(StructuredGraph graph) {
 177             DebugMethodMetrics m = Debug.methodMetrics(graph.method());
 178             for (Node n : graph.getNodes()) {
 179                 m.addToMetric(1, "%s%s", "a", n);
 180             }
 181         }
 182     }
 183 
 184     @Test(expected = VerificationError.class)
 185     public void testLogInvalidToString01Add() {
 186         testDebugUsageClass(InvalidCCP_ToString01Add.class);
 187     }
 188 
 189     @Test(expected = VerificationError.class)
 190     public void testLogInvalidConcat01Add() {
 191         testDebugUsageClass(InvalidCCP_Concat01Add.class);
 192     }
 193 
 194     @Test(expected = VerificationError.class)
 195     public void testLogInvalidToString02Add() {
 196         testDebugUsageClass(InvalidCCP_ToString02Add.class);
 197     }
 198 
 199     @Test(expected = VerificationError.class)
 200     public void testLogInvalidConcat02Add() {
 201         testDebugUsageClass(InvalidCCP_Concat02Add.class);
 202     }
 203 
 204     @Test
 205     public void testLogValidToStringAdd() {
 206         testDebugUsageClass(ValidCCP_ToStringAdd.class);
 207     }
 208 
 209     @Test
 210     public void testLogValidConcatAdd() {
 211         testDebugUsageClass(ValidCCP_ConcatAdd.class);
 212     }
 213 
 214     @Test(expected = VerificationError.class)
 215     public void testLogInvalidToString01Inc() {
 216         testDebugUsageClass(InvalidCCP_ToString01Inc.class);
 217     }
 218 
 219     @Test(expected = VerificationError.class)
 220     public void testLogInvalidConcat01Inc() {
 221         testDebugUsageClass(InvalidCCP_Concat01Inc.class);
 222     }
 223 
 224     @Test(expected = VerificationError.class)
 225     public void testLogInvalidToString02Inc() {
 226         testDebugUsageClass(InvalidCCP_ToString02Inc.class);
 227     }
 228 
 229     @Test(expected = VerificationError.class)
 230     public void testLogInvalidConcat02Inc() {
 231         testDebugUsageClass(InvalidCCP_Concat02Inc.class);
 232     }
 233 
 234     @Test
 235     public void testLogValidToStringInc() {
 236         testDebugUsageClass(ValidCCP_ToStringInc.class);
 237     }
 238 
 239     @Test
 240     public void testLogValidConcatInc() {
 241         testDebugUsageClass(ValidCCP_ConcatInc.class);
 242     }
 243 
 244     @SuppressWarnings("try")
 245     private static void testDebugUsageClass(Class<?> c) {
 246         RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class);
 247         Providers providers = rt.getHostBackend().getProviders();
 248         MetaAccessProvider metaAccess = providers.getMetaAccess();
 249         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
 250         Plugins plugins = new Plugins(new InvocationPlugins(metaAccess));
 251         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true);
 252         graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
 253         HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
 254         for (Method m : c.getDeclaredMethods()) {
 255             if (!Modifier.isNative(m.getModifiers()) && !Modifier.isAbstract(m.getModifiers())) {
 256                 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
 257                 StructuredGraph graph = new StructuredGraph.Builder(getInitialOptions()).method(method).build();
 258                 graphBuilderSuite.apply(graph, context);
 259                 try (DebugConfigScope s = Debug.disableIntercept()) {
 260                     new VerifyDebugUsage().apply(graph, context);
 261                 }
 262             }
 263         }
 264     }
 265 }