001/* 002 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.hotspot.test; 024 025import org.junit.*; 026 027import com.oracle.graal.api.replacements.*; 028import com.oracle.graal.api.runtime.*; 029import com.oracle.graal.compiler.common.spi.*; 030import com.oracle.graal.compiler.test.*; 031import com.oracle.graal.graph.Node.ConstantNodeParameter; 032import com.oracle.graal.graph.Node.NodeIntrinsic; 033import com.oracle.graal.hotspot.meta.*; 034import com.oracle.graal.nodes.extended.*; 035import com.oracle.graal.nodes.spi.*; 036import com.oracle.graal.runtime.*; 037 038/** 039 * Tests that deoptimization upon exception handling works. 040 */ 041public class ForeignCallDeoptimizeTest extends GraalCompilerTest { 042 043 private static boolean substitutionsInstalled; 044 045 public ForeignCallDeoptimizeTest() { 046 if (!substitutionsInstalled) { 047 Replacements replacements = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getReplacements(); 048 replacements.registerSubstitutions(ForeignCallDeoptimizeTest.class, Substitutions.class); 049 substitutionsInstalled = true; 050 } 051 } 052 053 @ClassSubstitution(ForeignCallDeoptimizeTest.class) 054 static class Substitutions { 055 056 @MethodSubstitution(isStatic = true) 057 static int testCallInt(int value) { 058 return testDeoptimizeCallInt(HotSpotForeignCallsProviderImpl.TEST_DEOPTIMIZE_CALL_INT, value); 059 } 060 } 061 062 /** 063 * Exercise deoptimization inside of a non leaf runtime call. 064 */ 065 @NodeIntrinsic(ForeignCallNode.class) 066 static native int testDeoptimizeCallInt(@ConstantNodeParameter ForeignCallDescriptor descriptor, int value); 067 068 public static int testCallInt(int value) { 069 return value; 070 } 071 072 public static int testForeignCall(int value) { 073 if (testCallInt(value) != value) { 074 throw new InternalError(); 075 } 076 return value; 077 } 078 079 @Test 080 public void test1() { 081 test("testForeignCall", 0); 082 } 083 084 @Test 085 public void test2() { 086 test("testForeignCall", -1); 087 } 088}