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
24
25 package org.graalvm.compiler.hotspot.stubs;
26
27 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
28 import static org.graalvm.compiler.hotspot.nodes.JumpToExceptionHandlerInCallerNode.jumpToExceptionHandlerInCaller;
29 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
30 import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.checkExceptionNotNull;
31 import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.checkNoExceptionInThread;
32 import static org.graalvm.compiler.hotspot.stubs.StubUtil.cAssertionsEnabled;
33 import static org.graalvm.compiler.hotspot.stubs.StubUtil.decipher;
34 import static org.graalvm.compiler.hotspot.stubs.StubUtil.newDescriptor;
35 import static org.graalvm.compiler.hotspot.stubs.StubUtil.printf;
36
37 import org.graalvm.compiler.api.replacements.Fold;
38 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
39 import org.graalvm.compiler.api.replacements.Snippet;
40 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
41 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
42 import org.graalvm.compiler.debug.Assertions;
43 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
44 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
45 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
46 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
60 public class UnwindExceptionToCallerStub extends SnippetStub {
61
62 public UnwindExceptionToCallerStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
63 super("unwindExceptionToCaller", options, providers, linkage);
64 }
65
66 /**
67 * The current frame is unwound by this stub. Therefore, it does not need to save any registers
68 * as HotSpot uses a caller save convention.
69 */
70 @Override
71 public boolean preservesRegisters() {
72 return false;
73 }
74
75 @Override
76 protected Object getConstantParameterValue(int index, String name) {
77 if (index == 2) {
78 return providers.getRegisters().getThreadRegister();
79 }
80 assert index == 3;
81 return options;
82 }
83
84 @Snippet
85 private static void unwindExceptionToCaller(Object exception, Word returnAddress, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) {
86 Pointer exceptionOop = Word.objectToTrackedPointer(exception);
87 if (logging(options)) {
88 printf("unwinding exception %p (", exceptionOop.rawValue());
89 decipher(exceptionOop.rawValue());
90 printf(") at %p (", returnAddress.rawValue());
91 decipher(returnAddress.rawValue());
92 printf(")\n");
93 }
94 Word thread = registerAsWord(threadRegister);
95 checkNoExceptionInThread(thread, assertionsEnabled(INJECTED_VMCONFIG));
96 checkExceptionNotNull(assertionsEnabled(INJECTED_VMCONFIG), exception);
97
98 Word handlerInCallerPc = exceptionHandlerForReturnAddress(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, thread, returnAddress);
99
100 if (logging(options)) {
101 printf("handler for exception %p at return address %p is at %p (", exceptionOop.rawValue(), returnAddress.rawValue(), handlerInCallerPc.rawValue());
102 decipher(handlerInCallerPc.rawValue());
103 printf(")\n");
104 }
105
106 jumpToExceptionHandlerInCaller(handlerInCallerPc, exception, returnAddress);
107 }
108
109 @Fold
110 static boolean logging(OptionValues options) {
111 return StubOptions.TraceUnwindStub.getValue(options);
112 }
113
114 /**
115 * Determines if either Java assertions are enabled for Graal or if this is a HotSpot build
116 * where the ASSERT mechanism is enabled.
117 */
118 @Fold
119 @SuppressWarnings("all")
120 static boolean assertionsEnabled(@InjectedParameter GraalHotSpotVMConfig config) {
121 return Assertions.assertionsEnabled() || cAssertionsEnabled(config);
122 }
123
124 public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = newDescriptor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress", Word.class, Word.class,
125 Word.class);
126
127 @NodeIntrinsic(value = StubForeignCallNode.class)
128 public static native Word exceptionHandlerForReturnAddress(@ConstantNodeParameter ForeignCallDescriptor exceptionHandlerForReturnAddress, Word thread, Word returnAddress);
129 }
|
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
24
25 package org.graalvm.compiler.hotspot.stubs;
26
27 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_OPTIONVALUES;
28 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
29 import static org.graalvm.compiler.hotspot.nodes.JumpToExceptionHandlerInCallerNode.jumpToExceptionHandlerInCaller;
30 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
31 import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.checkExceptionNotNull;
32 import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.checkNoExceptionInThread;
33 import static org.graalvm.compiler.hotspot.stubs.StubUtil.cAssertionsEnabled;
34 import static org.graalvm.compiler.hotspot.stubs.StubUtil.decipher;
35 import static org.graalvm.compiler.hotspot.stubs.StubUtil.newDescriptor;
36 import static org.graalvm.compiler.hotspot.stubs.StubUtil.printf;
37
38 import org.graalvm.compiler.api.replacements.Fold;
39 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
40 import org.graalvm.compiler.api.replacements.Snippet;
41 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
42 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
43 import org.graalvm.compiler.debug.Assertions;
44 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
45 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
46 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
47 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
61 public class UnwindExceptionToCallerStub extends SnippetStub {
62
63 public UnwindExceptionToCallerStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
64 super("unwindExceptionToCaller", options, providers, linkage);
65 }
66
67 /**
68 * The current frame is unwound by this stub. Therefore, it does not need to save any registers
69 * as HotSpot uses a caller save convention.
70 */
71 @Override
72 public boolean preservesRegisters() {
73 return false;
74 }
75
76 @Override
77 protected Object getConstantParameterValue(int index, String name) {
78 if (index == 2) {
79 return providers.getRegisters().getThreadRegister();
80 }
81 throw new InternalError();
82 }
83
84 @Snippet
85 private static void unwindExceptionToCaller(Object exception, Word returnAddress, @ConstantParameter Register threadRegister) {
86 Pointer exceptionOop = Word.objectToTrackedPointer(exception);
87 if (logging(INJECTED_OPTIONVALUES)) {
88 printf("unwinding exception %p (", exceptionOop.rawValue());
89 decipher(exceptionOop.rawValue());
90 printf(") at %p (", returnAddress.rawValue());
91 decipher(returnAddress.rawValue());
92 printf(")\n");
93 }
94 Word thread = registerAsWord(threadRegister);
95 checkNoExceptionInThread(thread, assertionsEnabled(INJECTED_VMCONFIG));
96 checkExceptionNotNull(assertionsEnabled(INJECTED_VMCONFIG), exception);
97
98 Word handlerInCallerPc = exceptionHandlerForReturnAddress(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, thread, returnAddress);
99
100 if (logging(INJECTED_OPTIONVALUES)) {
101 printf("handler for exception %p at return address %p is at %p (", exceptionOop.rawValue(), returnAddress.rawValue(), handlerInCallerPc.rawValue());
102 decipher(handlerInCallerPc.rawValue());
103 printf(")\n");
104 }
105
106 jumpToExceptionHandlerInCaller(handlerInCallerPc, exception, returnAddress);
107 }
108
109 @Fold
110 static boolean logging(@Fold.InjectedParameter OptionValues options) {
111 return StubOptions.TraceUnwindStub.getValue(options);
112 }
113
114 /**
115 * Determines if either Java assertions are enabled for Graal or if this is a HotSpot build
116 * where the ASSERT mechanism is enabled.
117 */
118 @Fold
119 @SuppressWarnings("all")
120 static boolean assertionsEnabled(@InjectedParameter GraalHotSpotVMConfig config) {
121 return Assertions.assertionsEnabled() || cAssertionsEnabled(config);
122 }
123
124 public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = newDescriptor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress", Word.class, Word.class,
125 Word.class);
126
127 @NodeIntrinsic(value = StubForeignCallNode.class)
128 public static native Word exceptionHandlerForReturnAddress(@ConstantNodeParameter ForeignCallDescriptor exceptionHandlerForReturnAddress, Word thread, Word returnAddress);
129 }
|