43972
|
1 |
/*
|
54724
|
2 |
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
43972
|
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 |
*/
|
50858
|
23 |
|
|
24 |
|
43972
|
25 |
package org.graalvm.compiler.hotspot.meta;
|
|
26 |
|
54084
|
27 |
import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
|
43972
|
28 |
import static org.graalvm.compiler.core.common.GraalOptions.AlwaysInlineVTableStubs;
|
|
29 |
import static org.graalvm.compiler.core.common.GraalOptions.InlineVTableStubs;
|
|
30 |
import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace;
|
|
31 |
import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.OSR_MIGRATION_END;
|
|
32 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_KLASS_LOCATION;
|
47798
|
33 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION;
|
43972
|
34 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_LOCATION;
|
|
35 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.COMPRESSED_HUB_LOCATION;
|
46344
|
36 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.DISPLACED_MARK_WORD_LOCATION;
|
43972
|
37 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_LOCATION;
|
|
38 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION;
|
|
39 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_LAYOUT_HELPER_LOCATION;
|
|
40 |
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION;
|
49873
|
41 |
import static jdk.internal.vm.compiler.word.LocationIdentity.any;
|
46459
|
42 |
|
43972
|
43 |
import java.lang.ref.Reference;
|
50330
|
44 |
import java.util.EnumMap;
|
43972
|
45 |
|
|
46 |
import org.graalvm.compiler.api.directives.GraalDirectives;
|
47798
|
47 |
import org.graalvm.compiler.core.common.CompressEncoding;
|
46371
|
48 |
import org.graalvm.compiler.core.common.GraalOptions;
|
43972
|
49 |
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
|
|
50 |
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
|
|
51 |
import org.graalvm.compiler.core.common.type.ObjectStamp;
|
|
52 |
import org.graalvm.compiler.core.common.type.Stamp;
|
|
53 |
import org.graalvm.compiler.core.common.type.StampFactory;
|
|
54 |
import org.graalvm.compiler.core.common.type.StampPair;
|
50330
|
55 |
import org.graalvm.compiler.debug.DebugCloseable;
|
46640
|
56 |
import org.graalvm.compiler.debug.DebugHandlersFactory;
|
43972
|
57 |
import org.graalvm.compiler.debug.GraalError;
|
|
58 |
import org.graalvm.compiler.graph.Node;
|
|
59 |
import org.graalvm.compiler.graph.NodeInputList;
|
|
60 |
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
|
61 |
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
|
46344
|
62 |
import org.graalvm.compiler.hotspot.nodes.BeginLockScopeNode;
|
46459
|
63 |
import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode;
|
43972
|
64 |
import org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode;
|
|
65 |
import org.graalvm.compiler.hotspot.nodes.HotSpotIndirectCallTargetNode;
|
58299
|
66 |
import org.graalvm.compiler.hotspot.nodes.KlassBeingInitializedCheckNode;
|
46344
|
67 |
import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
|
|
68 |
import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
|
47667
|
69 |
import org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode;
|
46344
|
70 |
import org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode;
|
|
71 |
import org.graalvm.compiler.hotspot.nodes.profiling.ProfileNode;
|
46459
|
72 |
import org.graalvm.compiler.hotspot.nodes.type.HotSpotNarrowOopStamp;
|
43972
|
73 |
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
|
|
74 |
import org.graalvm.compiler.hotspot.nodes.type.MethodPointerStamp;
|
|
75 |
import org.graalvm.compiler.hotspot.replacements.AssertionSnippets;
|
|
76 |
import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode;
|
|
77 |
import org.graalvm.compiler.hotspot.replacements.HashCodeSnippets;
|
55509
|
78 |
import org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets;
|
|
79 |
import org.graalvm.compiler.hotspot.replacements.HotSpotSerialWriteBarrierSnippets;
|
43972
|
80 |
import org.graalvm.compiler.hotspot.replacements.HubGetClassNode;
|
|
81 |
import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode;
|
|
82 |
import org.graalvm.compiler.hotspot.replacements.InstanceOfSnippets;
|
|
83 |
import org.graalvm.compiler.hotspot.replacements.KlassLayoutHelperNode;
|
|
84 |
import org.graalvm.compiler.hotspot.replacements.LoadExceptionObjectSnippets;
|
|
85 |
import org.graalvm.compiler.hotspot.replacements.MonitorSnippets;
|
|
86 |
import org.graalvm.compiler.hotspot.replacements.NewObjectSnippets;
|
52956
|
87 |
import org.graalvm.compiler.hotspot.replacements.ObjectCloneSnippets;
|
43972
|
88 |
import org.graalvm.compiler.hotspot.replacements.StringToBytesSnippets;
|
|
89 |
import org.graalvm.compiler.hotspot.replacements.UnsafeLoadSnippets;
|
|
90 |
import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
|
52956
|
91 |
import org.graalvm.compiler.hotspot.replacements.arraycopy.HotSpotArraycopySnippets;
|
43972
|
92 |
import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets;
|
52956
|
93 |
import org.graalvm.compiler.hotspot.stubs.ForeignCallSnippets;
|
43972
|
94 |
import org.graalvm.compiler.hotspot.word.KlassPointer;
|
|
95 |
import org.graalvm.compiler.nodes.AbstractBeginNode;
|
|
96 |
import org.graalvm.compiler.nodes.AbstractDeoptimizeNode;
|
46459
|
97 |
import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
|
52956
|
98 |
import org.graalvm.compiler.nodes.ComputeObjectAddressNode;
|
43972
|
99 |
import org.graalvm.compiler.nodes.ConstantNode;
|
|
100 |
import org.graalvm.compiler.nodes.FixedNode;
|
52956
|
101 |
import org.graalvm.compiler.nodes.GetObjectAddressNode;
|
43972
|
102 |
import org.graalvm.compiler.nodes.Invoke;
|
|
103 |
import org.graalvm.compiler.nodes.LogicNode;
|
|
104 |
import org.graalvm.compiler.nodes.LoweredCallTargetNode;
|
48190
|
105 |
import org.graalvm.compiler.nodes.NodeView;
|
43972
|
106 |
import org.graalvm.compiler.nodes.ParameterNode;
|
|
107 |
import org.graalvm.compiler.nodes.SafepointNode;
|
|
108 |
import org.graalvm.compiler.nodes.StartNode;
|
|
109 |
import org.graalvm.compiler.nodes.StructuredGraph;
|
|
110 |
import org.graalvm.compiler.nodes.UnwindNode;
|
|
111 |
import org.graalvm.compiler.nodes.ValueNode;
|
|
112 |
import org.graalvm.compiler.nodes.calc.AddNode;
|
|
113 |
import org.graalvm.compiler.nodes.calc.FloatingNode;
|
|
114 |
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
|
|
115 |
import org.graalvm.compiler.nodes.calc.IsNullNode;
|
|
116 |
import org.graalvm.compiler.nodes.calc.RemNode;
|
|
117 |
import org.graalvm.compiler.nodes.debug.StringToBytesNode;
|
|
118 |
import org.graalvm.compiler.nodes.debug.VerifyHeapNode;
|
|
119 |
import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode;
|
50330
|
120 |
import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode.BytecodeExceptionKind;
|
43972
|
121 |
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
|
|
122 |
import org.graalvm.compiler.nodes.extended.GetClassNode;
|
|
123 |
import org.graalvm.compiler.nodes.extended.GuardedUnsafeLoadNode;
|
|
124 |
import org.graalvm.compiler.nodes.extended.LoadHubNode;
|
|
125 |
import org.graalvm.compiler.nodes.extended.LoadMethodNode;
|
|
126 |
import org.graalvm.compiler.nodes.extended.OSRLocalNode;
|
46344
|
127 |
import org.graalvm.compiler.nodes.extended.OSRLockNode;
|
|
128 |
import org.graalvm.compiler.nodes.extended.OSRMonitorEnterNode;
|
43972
|
129 |
import org.graalvm.compiler.nodes.extended.OSRStartNode;
|
46459
|
130 |
import org.graalvm.compiler.nodes.extended.RawLoadNode;
|
43972
|
131 |
import org.graalvm.compiler.nodes.extended.StoreHubNode;
|
55509
|
132 |
import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier;
|
|
133 |
import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier;
|
|
134 |
import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
|
|
135 |
import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
|
|
136 |
import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
|
|
137 |
import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier;
|
|
138 |
import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
|
43972
|
139 |
import org.graalvm.compiler.nodes.java.ClassIsAssignableFromNode;
|
|
140 |
import org.graalvm.compiler.nodes.java.DynamicNewArrayNode;
|
|
141 |
import org.graalvm.compiler.nodes.java.DynamicNewInstanceNode;
|
|
142 |
import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
|
|
143 |
import org.graalvm.compiler.nodes.java.InstanceOfNode;
|
|
144 |
import org.graalvm.compiler.nodes.java.LoadExceptionObjectNode;
|
|
145 |
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
|
|
146 |
import org.graalvm.compiler.nodes.java.MonitorExitNode;
|
46344
|
147 |
import org.graalvm.compiler.nodes.java.MonitorIdNode;
|
43972
|
148 |
import org.graalvm.compiler.nodes.java.NewArrayNode;
|
|
149 |
import org.graalvm.compiler.nodes.java.NewInstanceNode;
|
|
150 |
import org.graalvm.compiler.nodes.java.NewMultiArrayNode;
|
|
151 |
import org.graalvm.compiler.nodes.java.RawMonitorEnterNode;
|
|
152 |
import org.graalvm.compiler.nodes.memory.FloatingReadNode;
|
|
153 |
import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
|
|
154 |
import org.graalvm.compiler.nodes.memory.ReadNode;
|
|
155 |
import org.graalvm.compiler.nodes.memory.WriteNode;
|
|
156 |
import org.graalvm.compiler.nodes.memory.address.AddressNode;
|
|
157 |
import org.graalvm.compiler.nodes.spi.LoweringProvider;
|
|
158 |
import org.graalvm.compiler.nodes.spi.LoweringTool;
|
|
159 |
import org.graalvm.compiler.nodes.spi.StampProvider;
|
|
160 |
import org.graalvm.compiler.nodes.type.StampTool;
|
|
161 |
import org.graalvm.compiler.nodes.util.GraphUtil;
|
46344
|
162 |
import org.graalvm.compiler.options.OptionValues;
|
43972
|
163 |
import org.graalvm.compiler.replacements.DefaultJavaLoweringProvider;
|
52956
|
164 |
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode;
|
|
165 |
import org.graalvm.compiler.replacements.arraycopy.ArrayCopySnippets;
|
54601
|
166 |
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyWithDelayedLoweringNode;
|
43972
|
167 |
import org.graalvm.compiler.replacements.nodes.AssertionNode;
|
54084
|
168 |
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
|
49873
|
169 |
import jdk.internal.vm.compiler.word.LocationIdentity;
|
43972
|
170 |
|
|
171 |
import jdk.vm.ci.code.TargetDescription;
|
|
172 |
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
|
|
173 |
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
|
174 |
import jdk.vm.ci.hotspot.HotSpotResolvedJavaField;
|
|
175 |
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
|
176 |
import jdk.vm.ci.meta.JavaConstant;
|
|
177 |
import jdk.vm.ci.meta.JavaKind;
|
|
178 |
import jdk.vm.ci.meta.JavaType;
|
|
179 |
import jdk.vm.ci.meta.MetaAccessProvider;
|
|
180 |
import jdk.vm.ci.meta.ResolvedJavaField;
|
|
181 |
import jdk.vm.ci.meta.ResolvedJavaType;
|
|
182 |
|
|
183 |
/**
|
|
184 |
* HotSpot implementation of {@link LoweringProvider}.
|
|
185 |
*/
|
57537
|
186 |
public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider implements HotSpotLoweringProvider {
|
43972
|
187 |
|
|
188 |
protected final HotSpotGraalRuntimeProvider runtime;
|
|
189 |
protected final HotSpotRegistersProvider registers;
|
|
190 |
protected final HotSpotConstantReflectionProvider constantReflection;
|
|
191 |
|
|
192 |
protected InstanceOfSnippets.Templates instanceofSnippets;
|
|
193 |
protected NewObjectSnippets.Templates newObjectSnippets;
|
|
194 |
protected MonitorSnippets.Templates monitorSnippets;
|
55509
|
195 |
protected HotSpotSerialWriteBarrierSnippets.Templates serialWriteBarrierSnippets;
|
|
196 |
protected HotSpotG1WriteBarrierSnippets.Templates g1WriteBarrierSnippets;
|
43972
|
197 |
protected LoadExceptionObjectSnippets.Templates exceptionObjectSnippets;
|
|
198 |
protected UnsafeLoadSnippets.Templates unsafeLoadSnippets;
|
|
199 |
protected AssertionSnippets.Templates assertionSnippets;
|
|
200 |
protected ArrayCopySnippets.Templates arraycopySnippets;
|
|
201 |
protected StringToBytesSnippets.Templates stringToBytesSnippets;
|
|
202 |
protected HashCodeSnippets.Templates hashCodeSnippets;
|
|
203 |
protected ResolveConstantSnippets.Templates resolveConstantSnippets;
|
|
204 |
protected ProfileSnippets.Templates profileSnippets;
|
|
205 |
|
52956
|
206 |
protected ObjectCloneSnippets.Templates objectCloneSnippets;
|
|
207 |
protected ForeignCallSnippets.Templates foreignCallSnippets;
|
|
208 |
|
43972
|
209 |
public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
|
|
210 |
HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {
|
47798
|
211 |
super(metaAccess, foreignCalls, target, runtime.getVMConfig().useCompressedOops);
|
43972
|
212 |
this.runtime = runtime;
|
|
213 |
this.registers = registers;
|
|
214 |
this.constantReflection = constantReflection;
|
|
215 |
}
|
|
216 |
|
|
217 |
@Override
|
46640
|
218 |
public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) {
|
|
219 |
super.initialize(options, factories, runtime, providers, providers.getSnippetReflection());
|
43972
|
220 |
|
|
221 |
assert target == providers.getCodeCache().getTarget();
|
46640
|
222 |
instanceofSnippets = new InstanceOfSnippets.Templates(options, factories, runtime, providers, target);
|
|
223 |
newObjectSnippets = new NewObjectSnippets.Templates(options, factories, runtime, providers, target, config);
|
|
224 |
monitorSnippets = new MonitorSnippets.Templates(options, factories, runtime, providers, target, config.useFastLocking);
|
55509
|
225 |
g1WriteBarrierSnippets = new HotSpotG1WriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config);
|
|
226 |
serialWriteBarrierSnippets = new HotSpotSerialWriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config);
|
46640
|
227 |
exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(options, factories, providers, target);
|
|
228 |
unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(options, factories, providers, target);
|
|
229 |
assertionSnippets = new AssertionSnippets.Templates(options, factories, providers, target);
|
52910
|
230 |
arraycopySnippets = new ArrayCopySnippets.Templates(new HotSpotArraycopySnippets(), options, factories, runtime, providers, providers.getSnippetReflection(), target);
|
46640
|
231 |
stringToBytesSnippets = new StringToBytesSnippets.Templates(options, factories, providers, target);
|
|
232 |
hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target);
|
47667
|
233 |
resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target);
|
55509
|
234 |
objectCloneSnippets = new ObjectCloneSnippets.Templates(options, factories, providers, target);
|
|
235 |
foreignCallSnippets = new ForeignCallSnippets.Templates(options, factories, providers, target);
|
|
236 |
if (JavaVersionUtil.JAVA_SPEC <= 8) {
|
|
237 |
// AOT only introduced in JDK 9
|
|
238 |
profileSnippets = null;
|
|
239 |
} else {
|
54084
|
240 |
profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target);
|
|
241 |
}
|
46344
|
242 |
}
|
|
243 |
|
54601
|
244 |
public ArrayCopySnippets.Templates getArraycopySnippets() {
|
|
245 |
return arraycopySnippets;
|
|
246 |
}
|
|
247 |
|
46344
|
248 |
public MonitorSnippets.Templates getMonitorSnippets() {
|
|
249 |
return monitorSnippets;
|
43972
|
250 |
}
|
|
251 |
|
|
252 |
@Override
|
50330
|
253 |
@SuppressWarnings("try")
|
43972
|
254 |
public void lower(Node n, LoweringTool tool) {
|
|
255 |
StructuredGraph graph = (StructuredGraph) n.graph();
|
50330
|
256 |
try (DebugCloseable context = n.withNodeSourcePosition()) {
|
|
257 |
if (n instanceof Invoke) {
|
|
258 |
lowerInvoke((Invoke) n, tool, graph);
|
|
259 |
} else if (n instanceof LoadMethodNode) {
|
|
260 |
lowerLoadMethodNode((LoadMethodNode) n);
|
|
261 |
} else if (n instanceof GetClassNode) {
|
|
262 |
lowerGetClassNode((GetClassNode) n, tool, graph);
|
|
263 |
} else if (n instanceof StoreHubNode) {
|
|
264 |
lowerStoreHubNode((StoreHubNode) n, graph);
|
|
265 |
} else if (n instanceof OSRStartNode) {
|
|
266 |
lowerOSRStartNode((OSRStartNode) n);
|
|
267 |
} else if (n instanceof BytecodeExceptionNode) {
|
|
268 |
lowerBytecodeExceptionNode((BytecodeExceptionNode) n);
|
|
269 |
} else if (n instanceof InstanceOfNode) {
|
|
270 |
InstanceOfNode instanceOfNode = (InstanceOfNode) n;
|
|
271 |
if (graph.getGuardsStage().areDeoptsFixed()) {
|
|
272 |
instanceofSnippets.lower(instanceOfNode, tool);
|
|
273 |
} else {
|
|
274 |
if (instanceOfNode.allowsNull()) {
|
|
275 |
ValueNode object = instanceOfNode.getValue();
|
|
276 |
LogicNode newTypeCheck = graph.addOrUniqueWithInputs(InstanceOfNode.create(instanceOfNode.type(), object, instanceOfNode.profile(), instanceOfNode.getAnchor()));
|
|
277 |
LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY);
|
|
278 |
instanceOfNode.replaceAndDelete(newNode);
|
|
279 |
}
|
43972
|
280 |
}
|
50330
|
281 |
} else if (n instanceof InstanceOfDynamicNode) {
|
|
282 |
InstanceOfDynamicNode instanceOfDynamicNode = (InstanceOfDynamicNode) n;
|
|
283 |
if (graph.getGuardsStage().areDeoptsFixed()) {
|
|
284 |
instanceofSnippets.lower(instanceOfDynamicNode, tool);
|
|
285 |
} else {
|
|
286 |
ValueNode mirror = instanceOfDynamicNode.getMirrorOrHub();
|
|
287 |
if (mirror.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object) {
|
|
288 |
ClassGetHubNode classGetHub = graph.unique(new ClassGetHubNode(mirror));
|
|
289 |
instanceOfDynamicNode.setMirror(classGetHub);
|
|
290 |
}
|
43972
|
291 |
|
50330
|
292 |
if (instanceOfDynamicNode.allowsNull()) {
|
|
293 |
ValueNode object = instanceOfDynamicNode.getObject();
|
|
294 |
LogicNode newTypeCheck = graph.addOrUniqueWithInputs(
|
|
295 |
InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), instanceOfDynamicNode.getMirrorOrHub(), object, false));
|
|
296 |
LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY);
|
|
297 |
instanceOfDynamicNode.replaceAndDelete(newNode);
|
|
298 |
}
|
|
299 |
}
|
|
300 |
} else if (n instanceof ClassIsAssignableFromNode) {
|
|
301 |
if (graph.getGuardsStage().areDeoptsFixed()) {
|
|
302 |
instanceofSnippets.lower((ClassIsAssignableFromNode) n, tool);
|
|
303 |
}
|
|
304 |
} else if (n instanceof NewInstanceNode) {
|
|
305 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
306 |
newObjectSnippets.lower((NewInstanceNode) n, registers, tool);
|
|
307 |
}
|
|
308 |
} else if (n instanceof DynamicNewInstanceNode) {
|
|
309 |
DynamicNewInstanceNode newInstanceNode = (DynamicNewInstanceNode) n;
|
|
310 |
if (newInstanceNode.getClassClass() == null) {
|
52956
|
311 |
JavaConstant classClassMirror = constantReflection.asJavaClass(metaAccess.lookupJavaType(Class.class));
|
50330
|
312 |
ConstantNode classClass = ConstantNode.forConstant(classClassMirror, tool.getMetaAccess(), graph);
|
|
313 |
newInstanceNode.setClassClass(classClass);
|
|
314 |
}
|
|
315 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
316 |
newObjectSnippets.lower(newInstanceNode, registers, tool);
|
|
317 |
}
|
|
318 |
} else if (n instanceof NewArrayNode) {
|
|
319 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
320 |
newObjectSnippets.lower((NewArrayNode) n, registers, tool);
|
|
321 |
}
|
|
322 |
} else if (n instanceof DynamicNewArrayNode) {
|
|
323 |
DynamicNewArrayNode dynamicNewArrayNode = (DynamicNewArrayNode) n;
|
|
324 |
if (dynamicNewArrayNode.getVoidClass() == null) {
|
52956
|
325 |
JavaConstant voidClassMirror = constantReflection.asJavaClass(metaAccess.lookupJavaType(void.class));
|
50330
|
326 |
ConstantNode voidClass = ConstantNode.forConstant(voidClassMirror, tool.getMetaAccess(), graph);
|
|
327 |
dynamicNewArrayNode.setVoidClass(voidClass);
|
|
328 |
}
|
|
329 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
330 |
newObjectSnippets.lower(dynamicNewArrayNode, registers, tool);
|
|
331 |
}
|
|
332 |
} else if (n instanceof VerifyHeapNode) {
|
|
333 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
334 |
newObjectSnippets.lower((VerifyHeapNode) n, registers, tool);
|
|
335 |
}
|
|
336 |
} else if (n instanceof RawMonitorEnterNode) {
|
|
337 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
338 |
monitorSnippets.lower((RawMonitorEnterNode) n, registers, tool);
|
|
339 |
}
|
|
340 |
} else if (n instanceof MonitorExitNode) {
|
|
341 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
342 |
monitorSnippets.lower((MonitorExitNode) n, registers, tool);
|
43972
|
343 |
}
|
50330
|
344 |
} else if (n instanceof ArrayCopyNode) {
|
|
345 |
arraycopySnippets.lower((ArrayCopyNode) n, tool);
|
54601
|
346 |
} else if (n instanceof ArrayCopyWithDelayedLoweringNode) {
|
|
347 |
arraycopySnippets.lower((ArrayCopyWithDelayedLoweringNode) n, tool);
|
50330
|
348 |
} else if (n instanceof G1PreWriteBarrier) {
|
55509
|
349 |
g1WriteBarrierSnippets.lower((G1PreWriteBarrier) n, tool);
|
50330
|
350 |
} else if (n instanceof G1PostWriteBarrier) {
|
55509
|
351 |
g1WriteBarrierSnippets.lower((G1PostWriteBarrier) n, tool);
|
50330
|
352 |
} else if (n instanceof G1ReferentFieldReadBarrier) {
|
55509
|
353 |
g1WriteBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool);
|
50330
|
354 |
} else if (n instanceof SerialWriteBarrier) {
|
55509
|
355 |
serialWriteBarrierSnippets.lower((SerialWriteBarrier) n, tool);
|
50330
|
356 |
} else if (n instanceof SerialArrayRangeWriteBarrier) {
|
55509
|
357 |
serialWriteBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
|
50330
|
358 |
} else if (n instanceof G1ArrayRangePreWriteBarrier) {
|
55509
|
359 |
g1WriteBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool);
|
50330
|
360 |
} else if (n instanceof G1ArrayRangePostWriteBarrier) {
|
55509
|
361 |
g1WriteBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool);
|
50330
|
362 |
} else if (n instanceof NewMultiArrayNode) {
|
|
363 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
364 |
newObjectSnippets.lower((NewMultiArrayNode) n, tool);
|
|
365 |
}
|
|
366 |
} else if (n instanceof LoadExceptionObjectNode) {
|
|
367 |
exceptionObjectSnippets.lower((LoadExceptionObjectNode) n, registers, tool);
|
|
368 |
} else if (n instanceof AssertionNode) {
|
|
369 |
assertionSnippets.lower((AssertionNode) n, tool);
|
|
370 |
} else if (n instanceof StringToBytesNode) {
|
|
371 |
if (graph.getGuardsStage().areDeoptsFixed()) {
|
|
372 |
stringToBytesSnippets.lower((StringToBytesNode) n, tool);
|
|
373 |
}
|
|
374 |
} else if (n instanceof IntegerDivRemNode) {
|
|
375 |
// Nothing to do for division nodes. The HotSpot signal handler catches divisions by
|
|
376 |
// zero and the MIN_VALUE / -1 cases.
|
|
377 |
} else if (n instanceof AbstractDeoptimizeNode || n instanceof UnwindNode || n instanceof RemNode || n instanceof SafepointNode) {
|
|
378 |
/* No lowering, we generate LIR directly for these nodes. */
|
|
379 |
} else if (n instanceof ClassGetHubNode) {
|
|
380 |
lowerClassGetHubNode((ClassGetHubNode) n, tool);
|
|
381 |
} else if (n instanceof HubGetClassNode) {
|
|
382 |
lowerHubGetClassNode((HubGetClassNode) n, tool);
|
|
383 |
} else if (n instanceof KlassLayoutHelperNode) {
|
|
384 |
lowerKlassLayoutHelperNode((KlassLayoutHelperNode) n, tool);
|
|
385 |
} else if (n instanceof ComputeObjectAddressNode) {
|
|
386 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
387 |
lowerComputeObjectAddressNode((ComputeObjectAddressNode) n);
|
|
388 |
}
|
|
389 |
} else if (n instanceof IdentityHashCodeNode) {
|
|
390 |
hashCodeSnippets.lower((IdentityHashCodeNode) n, tool);
|
|
391 |
} else if (n instanceof ResolveDynamicConstantNode) {
|
|
392 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
393 |
resolveConstantSnippets.lower((ResolveDynamicConstantNode) n, tool);
|
|
394 |
}
|
|
395 |
} else if (n instanceof ResolveConstantNode) {
|
|
396 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
397 |
resolveConstantSnippets.lower((ResolveConstantNode) n, tool);
|
|
398 |
}
|
|
399 |
} else if (n instanceof ResolveMethodAndLoadCountersNode) {
|
|
400 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
401 |
resolveConstantSnippets.lower((ResolveMethodAndLoadCountersNode) n, tool);
|
|
402 |
}
|
|
403 |
} else if (n instanceof InitializeKlassNode) {
|
|
404 |
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
|
|
405 |
resolveConstantSnippets.lower((InitializeKlassNode) n, tool);
|
|
406 |
}
|
|
407 |
} else if (n instanceof ProfileNode) {
|
|
408 |
profileSnippets.lower((ProfileNode) n, tool);
|
58299
|
409 |
} else if (n instanceof KlassBeingInitializedCheckNode) {
|
|
410 |
newObjectSnippets.lower((KlassBeingInitializedCheckNode) n, registers, tool);
|
50330
|
411 |
} else {
|
|
412 |
super.lower(n, tool);
|
43972
|
413 |
}
|
|
414 |
}
|
|
415 |
}
|
|
416 |
|
|
417 |
private static void lowerComputeObjectAddressNode(ComputeObjectAddressNode n) {
|
|
418 |
/*
|
|
419 |
* Lower the node into a ComputeObjectAddress node and an Add but ensure that it's below any
|
|
420 |
* potential safepoints and above it's uses.
|
|
421 |
*/
|
|
422 |
for (Node use : n.usages().snapshot()) {
|
|
423 |
if (use instanceof FixedNode) {
|
|
424 |
FixedNode fixed = (FixedNode) use;
|
|
425 |
StructuredGraph graph = n.graph();
|
|
426 |
GetObjectAddressNode address = graph.add(new GetObjectAddressNode(n.getObject()));
|
|
427 |
graph.addBeforeFixed(fixed, address);
|
|
428 |
AddNode add = graph.addOrUnique(new AddNode(address, n.getOffset()));
|
|
429 |
use.replaceFirstInput(n, add);
|
|
430 |
} else {
|
|
431 |
throw GraalError.shouldNotReachHere("Unexpected floating use of ComputeObjectAddressNode " + n);
|
|
432 |
}
|
|
433 |
}
|
|
434 |
GraphUtil.unlinkFixedNode(n);
|
|
435 |
n.safeDelete();
|
|
436 |
}
|
|
437 |
|
|
438 |
private void lowerKlassLayoutHelperNode(KlassLayoutHelperNode n, LoweringTool tool) {
|
|
439 |
if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
|
|
440 |
return;
|
|
441 |
}
|
|
442 |
StructuredGraph graph = n.graph();
|
|
443 |
assert !n.getHub().isConstant();
|
|
444 |
AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getVMConfig().klassLayoutHelperOffset);
|
48190
|
445 |
n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE)));
|
43972
|
446 |
}
|
|
447 |
|
|
448 |
private void lowerHubGetClassNode(HubGetClassNode n, LoweringTool tool) {
|
|
449 |
if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
|
|
450 |
return;
|
|
451 |
}
|
|
452 |
|
46371
|
453 |
ValueNode hub = n.getHub();
|
|
454 |
GraalHotSpotVMConfig vmConfig = runtime.getVMConfig();
|
43972
|
455 |
StructuredGraph graph = n.graph();
|
46371
|
456 |
assert !hub.isConstant() || GraalOptions.ImmutableCode.getValue(graph.getOptions());
|
|
457 |
AddressNode mirrorAddress = createOffsetAddress(graph, hub, vmConfig.classMirrorOffset);
|
48190
|
458 |
FloatingReadNode read = graph.unique(
|
|
459 |
new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(NodeView.DEFAULT),
|
|
460 |
null, BarrierType.NONE));
|
46371
|
461 |
if (vmConfig.classMirrorIsHandle) {
|
|
462 |
AddressNode address = createOffsetAddress(graph, read, 0);
|
48190
|
463 |
read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
|
46371
|
464 |
}
|
43972
|
465 |
n.replaceAtUsagesAndDelete(read);
|
|
466 |
}
|
|
467 |
|
|
468 |
private void lowerClassGetHubNode(ClassGetHubNode n, LoweringTool tool) {
|
|
469 |
if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
|
|
470 |
return;
|
|
471 |
}
|
|
472 |
|
|
473 |
StructuredGraph graph = n.graph();
|
|
474 |
assert !n.getValue().isConstant();
|
|
475 |
AddressNode address = createOffsetAddress(graph, n.getValue(), runtime.getVMConfig().klassOffset);
|
48190
|
476 |
FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
|
43972
|
477 |
n.replaceAtUsagesAndDelete(read);
|
|
478 |
}
|
|
479 |
|
|
480 |
private void lowerInvoke(Invoke invoke, LoweringTool tool, StructuredGraph graph) {
|
|
481 |
if (invoke.callTarget() instanceof MethodCallTargetNode) {
|
|
482 |
MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
|
|
483 |
NodeInputList<ValueNode> parameters = callTarget.arguments();
|
54601
|
484 |
ValueNode receiver = parameters.isEmpty() ? null : parameters.get(0);
|
|
485 |
|
|
486 |
if (!callTarget.isStatic()) {
|
|
487 |
assert receiver != null : "non-static call must have a receiver";
|
|
488 |
if (receiver.stamp(NodeView.DEFAULT) instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
|
|
489 |
ValueNode nonNullReceiver = createNullCheckedValue(receiver, invoke.asNode(), tool);
|
|
490 |
parameters.set(0, nonNullReceiver);
|
|
491 |
receiver = nonNullReceiver;
|
|
492 |
}
|
43972
|
493 |
}
|
|
494 |
JavaType[] signature = callTarget.targetMethod().getSignature().toParameterTypes(callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
|
|
495 |
|
|
496 |
LoweredCallTargetNode loweredCallTarget = null;
|
46344
|
497 |
OptionValues options = graph.getOptions();
|
|
498 |
if (InlineVTableStubs.getValue(options) && callTarget.invokeKind().isIndirect() && (AlwaysInlineVTableStubs.getValue(options) || invoke.isPolymorphic())) {
|
43972
|
499 |
HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
|
|
500 |
ResolvedJavaType receiverType = invoke.getReceiverType();
|
|
501 |
if (hsMethod.isInVirtualMethodTable(receiverType)) {
|
|
502 |
JavaKind wordKind = runtime.getTarget().wordJavaKind;
|
|
503 |
ValueNode hub = createReadHub(graph, receiver, tool);
|
|
504 |
|
|
505 |
ReadNode metaspaceMethod = createReadVirtualMethod(graph, hub, hsMethod, receiverType);
|
|
506 |
// We use LocationNode.ANY_LOCATION for the reads that access the
|
|
507 |
// compiled code entry as HotSpot does not guarantee they are final
|
|
508 |
// values.
|
|
509 |
int methodCompiledEntryOffset = runtime.getVMConfig().methodCompiledEntryOffset;
|
|
510 |
AddressNode address = createOffsetAddress(graph, metaspaceMethod, methodCompiledEntryOffset);
|
|
511 |
ReadNode compiledEntry = graph.add(new ReadNode(address, any(), StampFactory.forKind(wordKind), BarrierType.NONE));
|
|
512 |
|
|
513 |
loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters.toArray(new ValueNode[parameters.size()]), callTarget.returnStamp(),
|
|
514 |
signature, callTarget.targetMethod(),
|
|
515 |
HotSpotCallingConventionType.JavaCall, callTarget.invokeKind()));
|
|
516 |
|
|
517 |
graph.addBeforeFixed(invoke.asNode(), metaspaceMethod);
|
|
518 |
graph.addAfterFixed(metaspaceMethod, compiledEntry);
|
|
519 |
}
|
|
520 |
}
|
|
521 |
|
|
522 |
if (loweredCallTarget == null) {
|
|
523 |
loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters.toArray(new ValueNode[parameters.size()]), callTarget.returnStamp(),
|
|
524 |
signature, callTarget.targetMethod(),
|
|
525 |
HotSpotCallingConventionType.JavaCall,
|
|
526 |
callTarget.invokeKind()));
|
|
527 |
}
|
|
528 |
callTarget.replaceAndDelete(loweredCallTarget);
|
|
529 |
}
|
|
530 |
}
|
|
531 |
|
47798
|
532 |
private CompressEncoding getOopEncoding() {
|
|
533 |
return runtime.getVMConfig().getOopEncoding();
|
43972
|
534 |
}
|
|
535 |
|
|
536 |
@Override
|
47798
|
537 |
protected Stamp loadCompressedStamp(ObjectStamp stamp) {
|
|
538 |
return HotSpotNarrowOopStamp.compressed(stamp, getOopEncoding());
|
|
539 |
}
|
|
540 |
|
|
541 |
@Override
|
|
542 |
protected ValueNode newCompressionNode(CompressionOp op, ValueNode value) {
|
|
543 |
return new HotSpotCompressionNode(op, value, getOopEncoding());
|
43972
|
544 |
}
|
|
545 |
|
|
546 |
@Override
|
|
547 |
public ValueNode staticFieldBase(StructuredGraph graph, ResolvedJavaField f) {
|
|
548 |
HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) f;
|
|
549 |
JavaConstant base = constantReflection.asJavaClass(field.getDeclaringClass());
|
|
550 |
return ConstantNode.forConstant(base, metaAccess, graph);
|
|
551 |
}
|
|
552 |
|
|
553 |
@Override
|
|
554 |
protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) {
|
|
555 |
/*
|
|
556 |
* Anchor the read of the element klass to the cfg, because it is only valid when arrayClass
|
|
557 |
* is an object class, which might not be the case in other parts of the compiled method.
|
|
558 |
*/
|
|
559 |
AddressNode address = createOffsetAddress(graph, arrayHub, runtime.getVMConfig().arrayClassElementOffset);
|
|
560 |
return graph.unique(new FloatingReadNode(address, OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, null, KlassPointerStamp.klassNonNull(), AbstractBeginNode.prevBegin(anchor)));
|
|
561 |
}
|
|
562 |
|
|
563 |
@Override
|
46344
|
564 |
protected void lowerUnsafeLoadNode(RawLoadNode load, LoweringTool tool) {
|
43972
|
565 |
StructuredGraph graph = load.graph();
|
|
566 |
if (!(load instanceof GuardedUnsafeLoadNode) && !graph.getGuardsStage().allowsFloatingGuards() && addReadBarrier(load)) {
|
|
567 |
unsafeLoadSnippets.lower(load, tool);
|
|
568 |
} else {
|
|
569 |
super.lowerUnsafeLoadNode(load, tool);
|
|
570 |
}
|
|
571 |
}
|
|
572 |
|
|
573 |
private void lowerLoadMethodNode(LoadMethodNode loadMethodNode) {
|
|
574 |
StructuredGraph graph = loadMethodNode.graph();
|
|
575 |
HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) loadMethodNode.getMethod();
|
|
576 |
ReadNode metaspaceMethod = createReadVirtualMethod(graph, loadMethodNode.getHub(), method, loadMethodNode.getReceiverType());
|
|
577 |
graph.replaceFixed(loadMethodNode, metaspaceMethod);
|
|
578 |
}
|
|
579 |
|
|
580 |
private static void lowerGetClassNode(GetClassNode getClass, LoweringTool tool, StructuredGraph graph) {
|
|
581 |
StampProvider stampProvider = tool.getStampProvider();
|
|
582 |
LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, getClass.getObject()));
|
|
583 |
HubGetClassNode hubGetClass = graph.unique(new HubGetClassNode(tool.getMetaAccess(), hub));
|
|
584 |
getClass.replaceAtUsagesAndDelete(hubGetClass);
|
|
585 |
hub.lower(tool);
|
|
586 |
hubGetClass.lower(tool);
|
|
587 |
}
|
|
588 |
|
|
589 |
private void lowerStoreHubNode(StoreHubNode storeHub, StructuredGraph graph) {
|
|
590 |
WriteNode hub = createWriteHub(graph, storeHub.getObject(), storeHub.getValue());
|
|
591 |
graph.replaceFixed(storeHub, hub);
|
|
592 |
}
|
|
593 |
|
|
594 |
private void lowerOSRStartNode(OSRStartNode osrStart) {
|
|
595 |
StructuredGraph graph = osrStart.graph();
|
|
596 |
if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
|
|
597 |
StartNode newStart = graph.add(new StartNode());
|
|
598 |
ParameterNode buffer = graph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(StampFactory.forKind(runtime.getTarget().wordJavaKind))));
|
|
599 |
ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer));
|
|
600 |
migrationEnd.setStateAfter(osrStart.stateAfter());
|
|
601 |
newStart.setNext(migrationEnd);
|
|
602 |
FixedNode next = osrStart.next();
|
|
603 |
osrStart.setNext(null);
|
|
604 |
migrationEnd.setNext(next);
|
|
605 |
graph.setStart(newStart);
|
|
606 |
|
46344
|
607 |
final int wordSize = target.wordSize;
|
|
608 |
|
|
609 |
// @formatter:off
|
|
610 |
// taken from c2 locals_addr = osr_buf + (max_locals-1)*wordSize)
|
|
611 |
// @formatter:on
|
|
612 |
int localsOffset = (graph.method().getMaxLocals() - 1) * wordSize;
|
43972
|
613 |
for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.TYPE)) {
|
|
614 |
int size = osrLocal.getStackKind().getSlotCount();
|
46344
|
615 |
int offset = localsOffset - (osrLocal.index() + size - 1) * wordSize;
|
43972
|
616 |
AddressNode address = createOffsetAddress(graph, buffer, offset);
|
48190
|
617 |
ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(NodeView.DEFAULT), BarrierType.NONE));
|
43972
|
618 |
osrLocal.replaceAndDelete(load);
|
|
619 |
graph.addBeforeFixed(migrationEnd, load);
|
|
620 |
}
|
46344
|
621 |
|
|
622 |
// @formatter:off
|
|
623 |
// taken from c2 monitors_addr = osr_buf + (max_locals+mcnt*2-1)*wordSize);
|
|
624 |
// @formatter:on
|
|
625 |
final int lockCount = osrStart.stateAfter().locksSize();
|
|
626 |
final int locksOffset = (graph.method().getMaxLocals() + lockCount * 2 - 1) * wordSize;
|
|
627 |
|
|
628 |
// first initialize the lock slots for all enters with the displaced marks read from the
|
|
629 |
// buffer
|
|
630 |
for (OSRMonitorEnterNode osrMonitorEnter : graph.getNodes(OSRMonitorEnterNode.TYPE)) {
|
|
631 |
MonitorIdNode monitorID = osrMonitorEnter.getMonitorId();
|
|
632 |
OSRLockNode lock = (OSRLockNode) osrMonitorEnter.object();
|
|
633 |
final int index = lock.index();
|
|
634 |
|
|
635 |
final int offsetDisplacedHeader = locksOffset - ((index * 2) + 1) * wordSize;
|
|
636 |
final int offsetLockObject = locksOffset - index * 2 * wordSize;
|
|
637 |
|
|
638 |
// load the displaced mark from the osr buffer
|
|
639 |
AddressNode addressDisplacedHeader = createOffsetAddress(graph, buffer, offsetDisplacedHeader);
|
48190
|
640 |
ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
|
46344
|
641 |
graph.addBeforeFixed(migrationEnd, loadDisplacedHeader);
|
|
642 |
|
|
643 |
// we need to initialize the stack slot for the lock
|
|
644 |
BeginLockScopeNode beginLockScope = graph.add(new BeginLockScopeNode(lock.getStackKind(), monitorID.getLockDepth()));
|
|
645 |
graph.addBeforeFixed(migrationEnd, beginLockScope);
|
|
646 |
|
|
647 |
// write the displaced mark to the correct stack slot
|
|
648 |
AddressNode addressDisplacedMark = createOffsetAddress(graph, beginLockScope, runtime.getVMConfig().basicLockDisplacedHeaderOffset);
|
|
649 |
WriteNode writeStackSlot = graph.add(new WriteNode(addressDisplacedMark, DISPLACED_MARK_WORD_LOCATION, loadDisplacedHeader, BarrierType.NONE));
|
|
650 |
graph.addBeforeFixed(migrationEnd, writeStackSlot);
|
|
651 |
|
|
652 |
// load the lock object from the osr buffer
|
|
653 |
AddressNode addressLockObject = createOffsetAddress(graph, buffer, offsetLockObject);
|
48190
|
654 |
ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
|
46344
|
655 |
lock.replaceAndDelete(loadObject);
|
|
656 |
graph.addBeforeFixed(migrationEnd, loadObject);
|
|
657 |
}
|
|
658 |
|
43972
|
659 |
osrStart.replaceAtUsagesAndDelete(newStart);
|
|
660 |
}
|
|
661 |
}
|
|
662 |
|
|
663 |
static final class Exceptions {
|
50330
|
664 |
protected static final EnumMap<BytecodeExceptionKind, RuntimeException> cachedExceptions;
|
43972
|
665 |
|
|
666 |
static {
|
50330
|
667 |
cachedExceptions = new EnumMap<>(BytecodeExceptionKind.class);
|
|
668 |
cachedExceptions.put(BytecodeExceptionKind.NULL_POINTER, clearStackTrace(new NullPointerException()));
|
|
669 |
cachedExceptions.put(BytecodeExceptionKind.OUT_OF_BOUNDS, clearStackTrace(new ArrayIndexOutOfBoundsException()));
|
|
670 |
cachedExceptions.put(BytecodeExceptionKind.CLASS_CAST, clearStackTrace(new ClassCastException()));
|
|
671 |
cachedExceptions.put(BytecodeExceptionKind.ARRAY_STORE, clearStackTrace(new ArrayStoreException()));
|
|
672 |
cachedExceptions.put(BytecodeExceptionKind.DIVISION_BY_ZERO, clearStackTrace(new ArithmeticException()));
|
|
673 |
}
|
|
674 |
|
|
675 |
private static RuntimeException clearStackTrace(RuntimeException ex) {
|
|
676 |
ex.setStackTrace(new StackTraceElement[0]);
|
|
677 |
return ex;
|
43972
|
678 |
}
|
|
679 |
}
|
|
680 |
|
|
681 |
public static final class RuntimeCalls {
|
50330
|
682 |
public static final EnumMap<BytecodeExceptionKind, ForeignCallDescriptor> runtimeCalls;
|
|
683 |
|
|
684 |
static {
|
|
685 |
runtimeCalls = new EnumMap<>(BytecodeExceptionKind.class);
|
|
686 |
runtimeCalls.put(BytecodeExceptionKind.ARRAY_STORE, new ForeignCallDescriptor("createArrayStoreException", ArrayStoreException.class, Object.class));
|
|
687 |
runtimeCalls.put(BytecodeExceptionKind.CLASS_CAST, new ForeignCallDescriptor("createClassCastException", ClassCastException.class, Object.class, KlassPointer.class));
|
|
688 |
runtimeCalls.put(BytecodeExceptionKind.NULL_POINTER, new ForeignCallDescriptor("createNullPointerException", NullPointerException.class));
|
|
689 |
runtimeCalls.put(BytecodeExceptionKind.OUT_OF_BOUNDS, new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class, int.class));
|
|
690 |
runtimeCalls.put(BytecodeExceptionKind.DIVISION_BY_ZERO, new ForeignCallDescriptor("createDivisionByZeroException", ArithmeticException.class));
|
51436
|
691 |
runtimeCalls.put(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW, new ForeignCallDescriptor("createIntegerExactOverflowException", ArithmeticException.class));
|
|
692 |
runtimeCalls.put(BytecodeExceptionKind.LONG_EXACT_OVERFLOW, new ForeignCallDescriptor("createLongExactOverflowException", ArithmeticException.class));
|
50330
|
693 |
}
|
43972
|
694 |
}
|
|
695 |
|
50330
|
696 |
private void throwCachedException(BytecodeExceptionNode node) {
|
54084
|
697 |
if (IS_IN_NATIVE_IMAGE) {
|
|
698 |
throw new InternalError("Can't throw exception from SVM object");
|
|
699 |
}
|
50330
|
700 |
Throwable exception = Exceptions.cachedExceptions.get(node.getExceptionKind());
|
|
701 |
assert exception != null;
|
43972
|
702 |
|
|
703 |
StructuredGraph graph = node.graph();
|
|
704 |
FloatingNode exceptionNode = ConstantNode.forConstant(constantReflection.forObject(exception), metaAccess, graph);
|
|
705 |
graph.replaceFixedWithFloating(node, exceptionNode);
|
|
706 |
}
|
|
707 |
|
|
708 |
private void lowerBytecodeExceptionNode(BytecodeExceptionNode node) {
|
46344
|
709 |
if (OmitHotExceptionStacktrace.getValue(node.getOptions())) {
|
50330
|
710 |
throwCachedException(node);
|
|
711 |
return;
|
43972
|
712 |
}
|
|
713 |
|
50330
|
714 |
ForeignCallDescriptor descriptor = RuntimeCalls.runtimeCalls.get(node.getExceptionKind());
|
|
715 |
assert descriptor != null;
|
43972
|
716 |
|
|
717 |
StructuredGraph graph = node.graph();
|
48190
|
718 |
ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(NodeView.DEFAULT), node.getArguments()));
|
58299
|
719 |
foreignCallNode.setStateAfter(node.stateAfter());
|
43972
|
720 |
graph.replaceFixedWithFixed(node, foreignCallNode);
|
|
721 |
}
|
|
722 |
|
46344
|
723 |
private boolean addReadBarrier(RawLoadNode load) {
|
43972
|
724 |
if (runtime.getVMConfig().useG1GC && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().getStackKind() == JavaKind.Object &&
|
|
725 |
load.accessKind() == JavaKind.Object && !StampTool.isPointerAlwaysNull(load.object())) {
|
|
726 |
ResolvedJavaType type = StampTool.typeOrNull(load.object());
|
|
727 |
if (type != null && !type.isArray()) {
|
|
728 |
return true;
|
|
729 |
}
|
|
730 |
}
|
|
731 |
return false;
|
|
732 |
}
|
|
733 |
|
|
734 |
private ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, HotSpotResolvedJavaMethod method, ResolvedJavaType receiverType) {
|
|
735 |
return createReadVirtualMethod(graph, hub, method.vtableEntryOffset(receiverType));
|
|
736 |
}
|
|
737 |
|
|
738 |
private ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, int vtableEntryOffset) {
|
|
739 |
assert vtableEntryOffset > 0;
|
|
740 |
// We use LocationNode.ANY_LOCATION for the reads that access the vtable
|
|
741 |
// entry as HotSpot does not guarantee that this is a final value.
|
46344
|
742 |
Stamp methodStamp = MethodPointerStamp.methodNonNull();
|
43972
|
743 |
AddressNode address = createOffsetAddress(graph, hub, vtableEntryOffset);
|
|
744 |
ReadNode metaspaceMethod = graph.add(new ReadNode(address, any(), methodStamp, BarrierType.NONE));
|
|
745 |
return metaspaceMethod;
|
|
746 |
}
|
|
747 |
|
|
748 |
@Override
|
|
749 |
protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool) {
|
|
750 |
if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
|
|
751 |
return graph.unique(new LoadHubNode(tool.getStampProvider(), object));
|
|
752 |
}
|
|
753 |
assert !object.isConstant() || object.isNullConstant();
|
|
754 |
|
|
755 |
KlassPointerStamp hubStamp = KlassPointerStamp.klassNonNull();
|
|
756 |
if (runtime.getVMConfig().useCompressedClassPointers) {
|
|
757 |
hubStamp = hubStamp.compressed(runtime.getVMConfig().getKlassEncoding());
|
|
758 |
}
|
|
759 |
|
|
760 |
AddressNode address = createOffsetAddress(graph, object, runtime.getVMConfig().hubOffset);
|
|
761 |
LocationIdentity hubLocation = runtime.getVMConfig().useCompressedClassPointers ? COMPRESSED_HUB_LOCATION : HUB_LOCATION;
|
|
762 |
FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(address, hubLocation, null, hubStamp, null, BarrierType.NONE));
|
|
763 |
if (runtime.getVMConfig().useCompressedClassPointers) {
|
46459
|
764 |
return HotSpotCompressionNode.uncompress(memoryRead, runtime.getVMConfig().getKlassEncoding());
|
43972
|
765 |
} else {
|
|
766 |
return memoryRead;
|
|
767 |
}
|
|
768 |
}
|
|
769 |
|
|
770 |
private WriteNode createWriteHub(StructuredGraph graph, ValueNode object, ValueNode value) {
|
|
771 |
assert !object.isConstant() || object.asConstant().isDefaultForKind();
|
|
772 |
|
|
773 |
ValueNode writeValue = value;
|
|
774 |
if (runtime.getVMConfig().useCompressedClassPointers) {
|
46459
|
775 |
writeValue = HotSpotCompressionNode.compress(value, runtime.getVMConfig().getKlassEncoding());
|
43972
|
776 |
}
|
|
777 |
|
|
778 |
AddressNode address = createOffsetAddress(graph, object, runtime.getVMConfig().hubOffset);
|
|
779 |
return graph.add(new WriteNode(address, HUB_WRITE_LOCATION, writeValue, BarrierType.NONE));
|
|
780 |
}
|
|
781 |
|
|
782 |
@Override
|
|
783 |
protected BarrierType fieldLoadBarrierType(ResolvedJavaField f) {
|
|
784 |
HotSpotResolvedJavaField loadField = (HotSpotResolvedJavaField) f;
|
54914
|
785 |
if (loadField.getJavaKind() == JavaKind.Object && metaAccess.lookupJavaType(Reference.class).equals(loadField.getDeclaringClass()) &&
|
43972
|
786 |
loadField.getName().equals("referent")) {
|
54914
|
787 |
return BarrierType.WEAK_FIELD;
|
43972
|
788 |
}
|
54914
|
789 |
return super.fieldLoadBarrierType(f);
|
43972
|
790 |
}
|
|
791 |
|
|
792 |
@Override
|
|
793 |
public int fieldOffset(ResolvedJavaField f) {
|
52956
|
794 |
return f.getOffset();
|
43972
|
795 |
}
|
|
796 |
|
|
797 |
@Override
|
|
798 |
public int arrayLengthOffset() {
|
|
799 |
return runtime.getVMConfig().arrayOopDescLengthOffset();
|
|
800 |
}
|
47798
|
801 |
|
|
802 |
@Override
|
|
803 |
protected final JavaKind getStorageKind(ResolvedJavaField field) {
|
|
804 |
return field.getJavaKind();
|
|
805 |
}
|
52956
|
806 |
|
|
807 |
@Override
|
|
808 |
public ObjectCloneSnippets.Templates getObjectCloneSnippets() {
|
|
809 |
return objectCloneSnippets;
|
|
810 |
}
|
|
811 |
|
|
812 |
@Override
|
|
813 |
public ForeignCallSnippets.Templates getForeignCallSnippets() {
|
|
814 |
return foreignCallSnippets;
|
|
815 |
}
|
43972
|
816 |
}
|