1 /*
   2  * Copyright (c) 2011, 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.replacements.test;
  24 
  25 import org.junit.Assert;
  26 import org.junit.Test;
  27 
  28 import org.graalvm.compiler.core.common.CompilationIdentifier;
  29 import org.graalvm.compiler.core.phases.HighTier;
  30 import org.graalvm.compiler.core.test.GraalCompilerTest;
  31 import org.graalvm.compiler.nodes.StructuredGraph;
  32 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  33 import org.graalvm.compiler.nodes.ValueNode;
  34 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
  35 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo;
  36 import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
  37 import org.graalvm.compiler.options.OptionValue;
  38 import org.graalvm.compiler.options.OptionValue.OverrideScope;
  39 import org.graalvm.compiler.phases.tiers.Suites;
  40 
  41 import jdk.vm.ci.meta.ResolvedJavaMethod;
  42 
  43 /**
  44  * Tests compilation of a hot exception handler.
  45  */
  46 public class CompiledExceptionHandlerTest extends GraalCompilerTest {
  47 
  48     @Override
  49     @SuppressWarnings("try")
  50     protected Suites createSuites() {
  51         try (OverrideScope scope = OptionValue.override(HighTier.Options.Inline, false)) {
  52             return super.createSuites();
  53         }
  54     }
  55 
  56     @Override
  57     protected InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
  58         /*
  59          * We don't care whether other invokes are inlined or not, but we definitely don't want
  60          * another explicit exception handler in the graph.
  61          */
  62         return InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
  63     }
  64 
  65     @Override
  66     protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) {
  67         StructuredGraph graph = super.parseEager(m, allowAssumptions, compilationId);
  68         int handlers = graph.getNodes().filter(ExceptionObjectNode.class).count();
  69         Assert.assertEquals(1, handlers);
  70         return graph;
  71     }
  72 
  73     @BytecodeParserNeverInline(invokeWithException = true)
  74     private static void raiseExceptionSimple(String s) {
  75         throw new RuntimeException("Raising exception with message \"" + s + "\"");
  76     }
  77 
  78     @Test
  79     public void test1() {
  80         test("test1Snippet", "a string");
  81         test("test1Snippet", (String) null);
  82     }
  83 
  84     public static String test1Snippet(String message) {
  85         if (message != null) {
  86             try {
  87                 raiseExceptionSimple(message);
  88             } catch (Exception e) {
  89                 return message + e.getMessage();
  90             }
  91         }
  92         return null;
  93     }
  94 
  95     @BytecodeParserNeverInline(invokeWithException = true)
  96     private static void raiseException(String m1, String m2, String m3, String m4, String m5) {
  97         throw new RuntimeException(m1 + m2 + m3 + m4 + m5);
  98     }
  99 
 100     @Test
 101     public void test2() {
 102         test("test2Snippet", "m1", "m2", "m3", "m4", "m5");
 103         test("test2Snippet", null, "m2", "m3", "m4", "m5");
 104     }
 105 
 106     public static String test2Snippet(String m1, String m2, String m3, String m4, String m5) {
 107         if (m1 != null) {
 108             try {
 109                 raiseException(m1, m2, m3, m4, m5);
 110             } catch (Exception e) {
 111                 return m5 + m4 + m3 + m2 + m1;
 112             }
 113         }
 114         return m4 + m3;
 115     }
 116 }