LoadExceptionObjectSnippets.java revision 13083:b9a173f12fe6
1/*
2 * Copyright (c) 2012, 2015, 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 */
23package org.graalvm.compiler.hotspot.replacements;
24
25import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.LOAD_AND_CLEAR_EXCEPTION;
26import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.EXCEPTION_OOP_LOCATION;
27import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.EXCEPTION_PC_LOCATION;
28import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readExceptionOop;
29import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
30import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.writeExceptionOop;
31import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.writeExceptionPc;
32import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.LoadExceptionObjectInVM;
33import static org.graalvm.compiler.nodes.PiNode.piCastToSnippetReplaceeStamp;
34import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
35
36import org.graalvm.api.word.WordFactory;
37import org.graalvm.compiler.api.replacements.Snippet;
38import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
39import org.graalvm.compiler.core.common.type.Stamp;
40import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
41import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
42import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
43import org.graalvm.compiler.nodes.StructuredGraph;
44import org.graalvm.compiler.nodes.extended.ForeignCallNode;
45import org.graalvm.compiler.nodes.java.LoadExceptionObjectNode;
46import org.graalvm.compiler.nodes.spi.LoweringTool;
47import org.graalvm.compiler.options.OptionValues;
48import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
49import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
50import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
51import org.graalvm.compiler.replacements.Snippets;
52import org.graalvm.compiler.replacements.nodes.ReadRegisterNode;
53import org.graalvm.compiler.word.Word;
54
55import jdk.vm.ci.code.BytecodeFrame;
56import jdk.vm.ci.code.Register;
57import jdk.vm.ci.code.TargetDescription;
58import jdk.vm.ci.meta.ResolvedJavaType;
59
60/**
61 * Snippet for loading the exception object at the start of an exception dispatcher.
62 * <p>
63 * The frame state upon entry to an exception handler is such that it is a
64 * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly the
65 * exception object (per the JVM spec) to rethrow. This means that the code generated for this node
66 * must not cause a deoptimization as the runtime/interpreter would not have a valid location to
67 * find the exception object to be rethrown.
68 */
69public class LoadExceptionObjectSnippets implements Snippets {
70
71    @Snippet
72    public static Object loadException(@ConstantParameter Register threadRegister) {
73        Word thread = registerAsWord(threadRegister);
74        Object exception = readExceptionOop(thread);
75        writeExceptionOop(thread, null);
76        writeExceptionPc(thread, WordFactory.zero());
77        return piCastToSnippetReplaceeStamp(exception);
78    }
79
80    public static class Templates extends AbstractTemplates {
81
82        private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException", EXCEPTION_OOP_LOCATION, EXCEPTION_PC_LOCATION);
83        private final HotSpotWordTypes wordTypes;
84
85        public Templates(OptionValues options, HotSpotProviders providers, TargetDescription target) {
86            super(options, providers, providers.getSnippetReflection(), target);
87            this.wordTypes = providers.getWordTypes();
88        }
89
90        public void lower(LoadExceptionObjectNode loadExceptionObject, HotSpotRegistersProvider registers, LoweringTool tool) {
91            StructuredGraph graph = loadExceptionObject.graph();
92            if (LoadExceptionObjectInVM.getValue(graph.getOptions())) {
93                ResolvedJavaType wordType = providers.getMetaAccess().lookupJavaType(Word.class);
94                Stamp stamp = wordTypes.getWordStamp(wordType);
95                ReadRegisterNode thread = graph.add(new ReadRegisterNode(stamp, registers.getThreadRegister(), true, false));
96                graph.addBeforeFixed(loadExceptionObject, thread);
97                ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(providers.getForeignCalls(), LOAD_AND_CLEAR_EXCEPTION, thread));
98                loadExceptionC.setStateAfter(loadExceptionObject.stateAfter());
99                graph.replaceFixedWithFixed(loadExceptionObject, loadExceptionC);
100            } else {
101                Arguments args = new Arguments(loadException, loadExceptionObject.graph().getGuardsStage(), tool.getLoweringStage());
102                args.addConst("threadRegister", registers.getThreadRegister());
103                template(args).instantiate(providers.getMetaAccess(), loadExceptionObject, DEFAULT_REPLACER, args);
104            }
105        }
106    }
107}
108