UnwindExceptionToCallerStub.java revision 12968:4d8a004e5c6d
142421Syokota/* 242421Syokota * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 342421Syokota * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 442421Syokota * 542421Syokota * This code is free software; you can redistribute it and/or modify it 642421Syokota * under the terms of the GNU General Public License version 2 only, as 742421Syokota * published by the Free Software Foundation. 842421Syokota * 942421Syokota * This code is distributed in the hope that it will be useful, but WITHOUT 1042421Syokota * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1142421Syokota * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1242421Syokota * version 2 for more details (a copy is included in the LICENSE file that 1342421Syokota * accompanied this code). 1442421Syokota * 1542421Syokota * You should have received a copy of the GNU General Public License version 1642421Syokota * 2 along with this work; if not, write to the Free Software Foundation, 1742421Syokota * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1842421Syokota * 1942421Syokota * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2042421Syokota * or visit www.oracle.com if you need additional information or have any 2142421Syokota * questions. 2242421Syokota */ 2342421Syokotapackage org.graalvm.compiler.hotspot.stubs; 2442421Syokota 2542421Syokotaimport static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; 2642421Syokotaimport static org.graalvm.compiler.hotspot.nodes.JumpToExceptionHandlerInCallerNode.jumpToExceptionHandlerInCaller; 2742421Syokotaimport static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; 2842421Syokotaimport static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.checkExceptionNotNull; 2942421Syokotaimport static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.checkNoExceptionInThread; 3042421Syokotaimport static org.graalvm.compiler.hotspot.stubs.StubUtil.cAssertionsEnabled; 3142421Syokotaimport static org.graalvm.compiler.hotspot.stubs.StubUtil.decipher; 3242421Syokotaimport static org.graalvm.compiler.hotspot.stubs.StubUtil.newDescriptor; 33119418Sobrienimport static org.graalvm.compiler.hotspot.stubs.StubUtil.printf; 34119418Sobrien 35119418Sobrienimport org.graalvm.compiler.api.replacements.Fold; 3642421Syokotaimport org.graalvm.compiler.api.replacements.Fold.InjectedParameter; 3742421Syokotaimport org.graalvm.compiler.api.replacements.Snippet; 3842421Syokotaimport org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; 3942421Syokotaimport org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; 4058271Syokotaimport org.graalvm.compiler.debug.Assertions; 4142421Syokotaimport org.graalvm.compiler.graph.Node.ConstantNodeParameter; 4242421Syokotaimport org.graalvm.compiler.graph.Node.NodeIntrinsic; 4358271Syokotaimport org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 4458271Syokotaimport org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; 4558271Syokotaimport org.graalvm.compiler.hotspot.meta.HotSpotProviders; 4642421Syokotaimport org.graalvm.compiler.hotspot.nodes.StubForeignCallNode; 47207354Ssobomaximport org.graalvm.compiler.nodes.UnwindNode; 48207354Ssobomaximport org.graalvm.compiler.options.OptionValues; 49207354Ssobomaximport org.graalvm.compiler.word.Pointer; 50207354Ssobomaximport org.graalvm.compiler.word.Word; 51147271Smarius 5242421Syokotaimport jdk.vm.ci.code.Register; 53147271Smarius 54147271Smarius/** 55147271Smarius * Stub called by an {@link UnwindNode}. This stub executes in the frame of the method throwing an 56147271Smarius * exception and completes by jumping to the exception handler in the calling frame. 57147271Smarius */ 5842421Syokotapublic class UnwindExceptionToCallerStub extends SnippetStub { 59147271Smarius 6042421Syokota public UnwindExceptionToCallerStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) { 6142421Syokota super("unwindExceptionToCaller", options, providers, linkage); 6242421Syokota } 63102149Speter 6442421Syokota /** 6542421Syokota * The current frame is unwound by this stub. Therefore, it does not need to save any registers 6642421Syokota * as HotSpot uses a caller save convention. 6742421Syokota */ 6842421Syokota @Override 6942421Syokota public boolean preservesRegisters() { 7042421Syokota return false; 7142421Syokota } 7242421Syokota 7342421Syokota @Override 7442421Syokota protected Object getConstantParameterValue(int index, String name) { 7542421Syokota if (index == 2) { 7642421Syokota return providers.getRegisters().getThreadRegister(); 7742421Syokota } 7842421Syokota assert index == 3; 7942421Syokota return options; 8058271Syokota } 8158271Syokota 8258271Syokota @Snippet 8358271Syokota private static void unwindExceptionToCaller(Object exception, Word returnAddress, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) { 8458271Syokota Pointer exceptionOop = Word.objectToTrackedPointer(exception); 8558271Syokota if (logging(options)) { 8658271Syokota printf("unwinding exception %p (", exceptionOop.rawValue()); 8742421Syokota decipher(exceptionOop.rawValue()); 8842421Syokota printf(") at %p (", returnAddress.rawValue()); 8942421Syokota decipher(returnAddress.rawValue()); 9042421Syokota printf(")\n"); 9142421Syokota } 9242421Syokota Word thread = registerAsWord(threadRegister); 9342421Syokota checkNoExceptionInThread(thread, assertionsEnabled(INJECTED_VMCONFIG)); 9442421Syokota checkExceptionNotNull(assertionsEnabled(INJECTED_VMCONFIG), exception); 9542421Syokota 9642421Syokota Word handlerInCallerPc = exceptionHandlerForReturnAddress(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, thread, returnAddress); 9742421Syokota 9842421Syokota if (logging(options)) { 9942421Syokota printf("handler for exception %p at return address %p is at %p (", exceptionOop.rawValue(), returnAddress.rawValue(), handlerInCallerPc.rawValue()); 100147271Smarius decipher(handlerInCallerPc.rawValue()); 101147271Smarius printf(")\n"); 102147271Smarius } 103147271Smarius 10442421Syokota jumpToExceptionHandlerInCaller(handlerInCallerPc, exception, returnAddress); 10542421Syokota } 10658271Syokota 10758271Syokota @Fold 10842421Syokota static boolean logging(OptionValues options) { 10942421Syokota return StubOptions.TraceUnwindStub.getValue(options); 11042421Syokota } 11142421Syokota 11242421Syokota /** 11342421Syokota * Determines if either Java assertions are enabled for Graal or if this is a HotSpot build 11442421Syokota * where the ASSERT mechanism is enabled. 11542421Syokota */ 11642421Syokota @Fold 11742421Syokota @SuppressWarnings("all") 11842421Syokota static boolean assertionsEnabled(@InjectedParameter GraalHotSpotVMConfig config) { 11942421Syokota return Assertions.ENABLED || cAssertionsEnabled(config); 12042421Syokota } 12142421Syokota 12242421Syokota public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = newDescriptor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress", Word.class, Word.class, 12342421Syokota Word.class); 12442421Syokota 12542421Syokota @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true) 12642421Syokota public static native Word exceptionHandlerForReturnAddress(@ConstantNodeParameter ForeignCallDescriptor exceptionHandlerForReturnAddress, Word thread, Word returnAddress); 12769781Sdwmalone} 12842421Syokota