ResolveConstantSnippets.java revision 12657:6ef01bd40ce2
1/*
2 * Copyright (c) 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 */
23package org.graalvm.compiler.hotspot.replacements.aot;
24
25import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY;
26import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
27import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
28
29import org.graalvm.compiler.api.replacements.Snippet;
30import org.graalvm.compiler.debug.GraalError;
31import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
32import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
33import org.graalvm.compiler.hotspot.nodes.aot.EncodedSymbolNode;
34import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
35import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassStubCall;
36import org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyNode;
37import org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersIndirectlyNode;
38import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
39import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantStubCall;
40import org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode;
41import org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersStubCall;
42import org.graalvm.compiler.hotspot.nodes.type.MethodPointerStamp;
43import org.graalvm.compiler.hotspot.word.KlassPointer;
44import org.graalvm.compiler.hotspot.word.MethodCountersPointer;
45import org.graalvm.compiler.hotspot.word.MethodPointer;
46import org.graalvm.compiler.nodes.ConstantNode;
47import org.graalvm.compiler.nodes.StructuredGraph;
48import org.graalvm.compiler.nodes.ValueNode;
49import org.graalvm.compiler.nodes.spi.LoweringTool;
50import org.graalvm.compiler.nodes.util.GraphUtil;
51import org.graalvm.compiler.replacements.SnippetTemplate;
52import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
53import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
54import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
55import org.graalvm.compiler.replacements.Snippets;
56
57import jdk.vm.ci.code.TargetDescription;
58import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
59import jdk.vm.ci.hotspot.HotSpotObjectConstant;
60import jdk.vm.ci.meta.Constant;
61
62public class ResolveConstantSnippets implements Snippets {
63
64    @Snippet
65    public static Object resolveObjectConstant(Object constant) {
66        Object result = LoadConstantIndirectlyNode.loadObject(constant);
67        if (probability(VERY_SLOW_PATH_PROBABILITY, result == null)) {
68            result = ResolveConstantStubCall.resolveObject(constant, EncodedSymbolNode.encode(constant));
69        }
70        return result;
71    }
72
73    @Snippet
74    public static KlassPointer resolveKlassConstant(KlassPointer constant) {
75        KlassPointer result = LoadConstantIndirectlyNode.loadKlass(constant);
76        if (probability(VERY_SLOW_PATH_PROBABILITY, result.isNull())) {
77            result = ResolveConstantStubCall.resolveKlass(constant, EncodedSymbolNode.encode(constant));
78        }
79        return result;
80    }
81
82    @Snippet
83    public static MethodCountersPointer resolveMethodAndLoadCounters(MethodPointer method, KlassPointer klassHint) {
84        MethodCountersPointer result = LoadMethodCountersIndirectlyNode.loadMethodCounters(method);
85        if (probability(VERY_SLOW_PATH_PROBABILITY, result.isNull())) {
86            result = ResolveMethodAndLoadCountersStubCall.resolveMethodAndLoadCounters(method, klassHint, EncodedSymbolNode.encode(method));
87        }
88        return result;
89    }
90
91    @Snippet
92    public static KlassPointer initializeKlass(KlassPointer constant) {
93        KlassPointer result = LoadConstantIndirectlyNode.loadKlass(constant, HotSpotConstantLoadAction.INITIALIZE);
94        if (probability(VERY_SLOW_PATH_PROBABILITY, result.isNull())) {
95            result = InitializeKlassStubCall.initializeKlass(constant, EncodedSymbolNode.encode(constant));
96        }
97        return result;
98    }
99
100    @Snippet
101    public static KlassPointer pureInitializeKlass(KlassPointer constant) {
102        KlassPointer result = LoadConstantIndirectlyNode.loadKlass(constant, HotSpotConstantLoadAction.INITIALIZE);
103        if (probability(VERY_SLOW_PATH_PROBABILITY, result.isNull())) {
104            result = ResolveConstantStubCall.resolveKlass(constant, EncodedSymbolNode.encode(constant), HotSpotConstantLoadAction.INITIALIZE);
105        }
106        return result;
107    }
108
109    public static class Templates extends AbstractTemplates {
110        private final SnippetInfo resolveObjectConstant = snippet(ResolveConstantSnippets.class, "resolveObjectConstant");
111        private final SnippetInfo resolveKlassConstant = snippet(ResolveConstantSnippets.class, "resolveKlassConstant");
112        private final SnippetInfo resolveMethodAndLoadCounters = snippet(ResolveConstantSnippets.class, "resolveMethodAndLoadCounters");
113        private final SnippetInfo initializeKlass = snippet(ResolveConstantSnippets.class, "initializeKlass");
114        private final SnippetInfo pureInitializeKlass = snippet(ResolveConstantSnippets.class, "pureInitializeKlass");
115
116        public Templates(HotSpotProviders providers, TargetDescription target) {
117            super(providers, providers.getSnippetReflection(), target);
118        }
119
120        public void lower(ResolveConstantNode resolveConstantNode, LoweringTool tool) {
121            StructuredGraph graph = resolveConstantNode.graph();
122
123            ValueNode value = resolveConstantNode.value();
124            assert value.isConstant() : "Expected a constant: " + value;
125            Constant constant = value.asConstant();
126            SnippetInfo snippet = null;
127
128            if (constant instanceof HotSpotMetaspaceConstant) {
129                HotSpotMetaspaceConstant hotspotMetaspaceConstant = (HotSpotMetaspaceConstant) constant;
130                if (hotspotMetaspaceConstant.asResolvedJavaType() != null) {
131                    if (resolveConstantNode.action() == HotSpotConstantLoadAction.RESOLVE) {
132                        snippet = resolveKlassConstant;
133                    } else {
134                        assert resolveConstantNode.action() == HotSpotConstantLoadAction.INITIALIZE;
135                        snippet = pureInitializeKlass;
136                    }
137                }
138            } else if (constant instanceof HotSpotObjectConstant) {
139                snippet = resolveObjectConstant;
140                HotSpotObjectConstant hotspotObjectConstant = (HotSpotObjectConstant) constant;
141                assert hotspotObjectConstant.isInternedString();
142            }
143            if (snippet == null) {
144                throw new GraalError("Unsupported constant type: " + constant);
145            }
146
147            Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
148            args.add("constant", value);
149
150            SnippetTemplate template = template(args);
151            template.instantiate(providers.getMetaAccess(), resolveConstantNode, DEFAULT_REPLACER, tool, args);
152
153            assert resolveConstantNode.hasNoUsages();
154            if (!resolveConstantNode.isDeleted()) {
155                GraphUtil.killWithUnusedFloatingInputs(resolveConstantNode);
156            }
157        }
158
159        public void lower(InitializeKlassNode initializeKlassNode, LoweringTool tool) {
160            StructuredGraph graph = initializeKlassNode.graph();
161
162            ValueNode value = initializeKlassNode.value();
163            assert value.isConstant() : "Expected a constant: " + value;
164            Constant constant = value.asConstant();
165
166            if (constant instanceof HotSpotMetaspaceConstant) {
167                Arguments args = new Arguments(initializeKlass, graph.getGuardsStage(), tool.getLoweringStage());
168                args.add("constant", value);
169
170                SnippetTemplate template = template(args);
171                template.instantiate(providers.getMetaAccess(), initializeKlassNode, DEFAULT_REPLACER, args);
172                assert initializeKlassNode.hasNoUsages();
173                if (!initializeKlassNode.isDeleted()) {
174                    GraphUtil.killWithUnusedFloatingInputs(initializeKlassNode);
175                }
176
177            } else {
178                throw new GraalError("Unsupported constant type: " + constant);
179            }
180        }
181
182        public void lower(ResolveMethodAndLoadCountersNode resolveMethodAndLoadCountersNode, LoweringTool tool) {
183            StructuredGraph graph = resolveMethodAndLoadCountersNode.graph();
184            ConstantNode method = ConstantNode.forConstant(MethodPointerStamp.methodNonNull(), resolveMethodAndLoadCountersNode.getMethod().getEncoding(), tool.getMetaAccess(), graph);
185            Arguments args = new Arguments(resolveMethodAndLoadCounters, graph.getGuardsStage(), tool.getLoweringStage());
186            args.add("method", method);
187            args.add("klassHint", resolveMethodAndLoadCountersNode.getHub());
188            SnippetTemplate template = template(args);
189            template.instantiate(providers.getMetaAccess(), resolveMethodAndLoadCountersNode, DEFAULT_REPLACER, tool, args);
190
191            assert resolveMethodAndLoadCountersNode.hasNoUsages();
192            if (!resolveMethodAndLoadCountersNode.isDeleted()) {
193                GraphUtil.killWithUnusedFloatingInputs(resolveMethodAndLoadCountersNode);
194            }
195        }
196    }
197}
198