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