30 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_WRITE;
31 import static jdk.vm.ci.meta.DeoptimizationAction.InvalidateReprofile;
32 import static jdk.vm.ci.meta.DeoptimizationReason.BoundsCheckException;
33 import static jdk.vm.ci.meta.DeoptimizationReason.NullCheckException;
34 import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.UseIndexMasking;
35 import static org.graalvm.compiler.nodes.NamedLocationIdentity.ARRAY_LENGTH_LOCATION;
36 import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.branchlessMax;
37 import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.branchlessMin;
38 import static org.graalvm.compiler.nodes.java.ArrayLengthNode.readArrayLength;
39 import static org.graalvm.compiler.nodes.util.GraphUtil.skipPiWhileNonNull;
40
41 import java.nio.ByteOrder;
42 import java.util.ArrayList;
43 import java.util.BitSet;
44 import java.util.List;
45
46 import org.graalvm.compiler.api.directives.GraalDirectives;
47 import org.graalvm.compiler.api.replacements.Snippet;
48 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
49 import org.graalvm.compiler.core.common.LIRKind;
50 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
51 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
52 import org.graalvm.compiler.core.common.type.IntegerStamp;
53 import org.graalvm.compiler.core.common.type.ObjectStamp;
54 import org.graalvm.compiler.core.common.type.Stamp;
55 import org.graalvm.compiler.core.common.type.StampFactory;
56 import org.graalvm.compiler.core.common.type.TypeReference;
57 import org.graalvm.compiler.debug.DebugCloseable;
58 import org.graalvm.compiler.debug.DebugHandlersFactory;
59 import org.graalvm.compiler.debug.GraalError;
60 import org.graalvm.compiler.graph.Node;
61 import org.graalvm.compiler.nodeinfo.InputType;
62 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
63 import org.graalvm.compiler.nodes.ConstantNode;
64 import org.graalvm.compiler.nodes.FieldLocationIdentity;
65 import org.graalvm.compiler.nodes.FixedNode;
66 import org.graalvm.compiler.nodes.LogicNode;
67 import org.graalvm.compiler.nodes.NamedLocationIdentity;
68 import org.graalvm.compiler.nodes.NodeView;
69 import org.graalvm.compiler.nodes.PiNode;
70 import org.graalvm.compiler.nodes.StructuredGraph;
106 import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
107 import org.graalvm.compiler.nodes.java.InstanceOfNode;
108 import org.graalvm.compiler.nodes.java.LoadFieldNode;
109 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
110 import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
111 import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
112 import org.graalvm.compiler.nodes.java.MonitorEnterNode;
113 import org.graalvm.compiler.nodes.java.MonitorIdNode;
114 import org.graalvm.compiler.nodes.java.NewArrayNode;
115 import org.graalvm.compiler.nodes.java.NewInstanceNode;
116 import org.graalvm.compiler.nodes.java.RawMonitorEnterNode;
117 import org.graalvm.compiler.nodes.java.StoreFieldNode;
118 import org.graalvm.compiler.nodes.java.StoreIndexedNode;
119 import org.graalvm.compiler.nodes.java.UnsafeCompareAndExchangeNode;
120 import org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode;
121 import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
122 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
123 import org.graalvm.compiler.nodes.memory.ReadNode;
124 import org.graalvm.compiler.nodes.memory.WriteNode;
125 import org.graalvm.compiler.nodes.memory.address.AddressNode;
126 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
127 import org.graalvm.compiler.nodes.spi.Lowerable;
128 import org.graalvm.compiler.nodes.spi.LoweringProvider;
129 import org.graalvm.compiler.nodes.spi.LoweringTool;
130 import org.graalvm.compiler.nodes.type.StampTool;
131 import org.graalvm.compiler.nodes.util.GraphUtil;
132 import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
133 import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
134 import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
135 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
136 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
137 import org.graalvm.compiler.options.OptionValues;
138 import org.graalvm.compiler.phases.util.Providers;
139 import org.graalvm.compiler.replacements.SnippetLowerableMemoryNode.SnippetLowering;
140 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
141 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation;
142 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
143 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
144 import jdk.internal.vm.compiler.word.LocationIdentity;
145
146 import jdk.vm.ci.code.CodeUtil;
147 import jdk.vm.ci.code.MemoryBarriers;
148 import jdk.vm.ci.code.TargetDescription;
149 import jdk.vm.ci.meta.DeoptimizationAction;
150 import jdk.vm.ci.meta.DeoptimizationReason;
151 import jdk.vm.ci.meta.JavaKind;
152 import jdk.vm.ci.meta.MetaAccessProvider;
153 import jdk.vm.ci.meta.ResolvedJavaField;
154 import jdk.vm.ci.meta.ResolvedJavaMethod;
155 import jdk.vm.ci.meta.ResolvedJavaType;
156 import jdk.vm.ci.meta.SpeculationLog;
157
158 /**
159 * VM-independent lowerings for standard Java nodes. VM-specific methods are abstract and must be
160 * implemented by VM-specific subclasses.
161 */
162 public abstract class DefaultJavaLoweringProvider implements LoweringProvider {
163
189 }
190
191 public MetaAccessProvider getMetaAccess() {
192 return metaAccess;
193 }
194
195 @Override
196 @SuppressWarnings("try")
197 public void lower(Node n, LoweringTool tool) {
198 assert n instanceof Lowerable;
199 StructuredGraph graph = (StructuredGraph) n.graph();
200 try (DebugCloseable context = n.withNodeSourcePosition()) {
201 if (n instanceof LoadFieldNode) {
202 lowerLoadFieldNode((LoadFieldNode) n, tool);
203 } else if (n instanceof StoreFieldNode) {
204 lowerStoreFieldNode((StoreFieldNode) n, tool);
205 } else if (n instanceof LoadIndexedNode) {
206 lowerLoadIndexedNode((LoadIndexedNode) n, tool);
207 } else if (n instanceof StoreIndexedNode) {
208 lowerStoreIndexedNode((StoreIndexedNode) n, tool);
209 } else if (n instanceof ArrayLengthNode) {
210 lowerArrayLengthNode((ArrayLengthNode) n, tool);
211 } else if (n instanceof LoadHubNode) {
212 lowerLoadHubNode((LoadHubNode) n, tool);
213 } else if (n instanceof LoadArrayComponentHubNode) {
214 lowerLoadArrayComponentHubNode((LoadArrayComponentHubNode) n);
215 } else if (n instanceof MonitorEnterNode) {
216 lowerMonitorEnterNode((MonitorEnterNode) n, tool, graph);
217 } else if (n instanceof UnsafeCompareAndSwapNode) {
218 lowerCompareAndSwapNode((UnsafeCompareAndSwapNode) n);
219 } else if (n instanceof UnsafeCompareAndExchangeNode) {
220 lowerCompareAndExchangeNode((UnsafeCompareAndExchangeNode) n);
221 } else if (n instanceof AtomicReadAndWriteNode) {
222 lowerAtomicReadAndWriteNode((AtomicReadAndWriteNode) n);
223 } else if (n instanceof RawLoadNode) {
224 lowerUnsafeLoadNode((RawLoadNode) n, tool);
225 } else if (n instanceof UnsafeMemoryLoadNode) {
226 lowerUnsafeMemoryLoadNode((UnsafeMemoryLoadNode) n);
227 } else if (n instanceof RawStoreNode) {
228 lowerUnsafeStoreNode((RawStoreNode) n);
304 public void lower(SnippetLowerableMemoryNode node, LoweringTool tool) {
305 if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
306 return;
307 }
308 indexOfSnippets.lowerUTF16(node, tool);
309 }
310 };
311 SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), n.stamp(NodeView.DEFAULT), n.toArgumentArray());
312 n.graph().add(snippetLower);
313 n.graph().replaceFixedWithFixed(n, snippetLower);
314 }
315 }
316
317 private void lowerBinaryMath(BinaryMathIntrinsicNode math, LoweringTool tool) {
318 if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
319 return;
320 }
321 ResolvedJavaMethod method = math.graph().method();
322 if (method != null) {
323 if (method.getAnnotation(Snippet.class) != null) {
324 /*
325 * In the context of the snippet use the LIR lowering instead of the Node lowering.
326 */
327 return;
328 }
329 if (method.getName().equalsIgnoreCase(math.getOperation().name()) && tool.getMetaAccess().lookupJavaType(Math.class).equals(method.getDeclaringClass())) {
330 /*
331 * A root compilation of the intrinsic method should emit the full assembly
332 * implementation.
333 */
334 return;
335 }
336
337 }
338 ForeignCallDescriptor foreignCall = toForeignCall(math.getOperation());
339 if (foreignCall != null) {
340 StructuredGraph graph = math.graph();
341 ForeignCallNode call = graph.add(new ForeignCallNode(foreignCalls, toForeignCall(math.getOperation()), math.getX(), math.getY()));
342 graph.addAfterFixed(tool.lastFixedNode(), call);
343 math.replaceAtUsages(call);
344 }
345 }
346
347 private void lowerUnaryMath(UnaryMathIntrinsicNode math, LoweringTool tool) {
348 if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
349 return;
350 }
351 ResolvedJavaMethod method = math.graph().method();
352 if (method != null) {
353 if (method.getAnnotation(Snippet.class) != null) {
354 /*
355 * In the context of the snippet use the LIR lowering instead of the Node lowering.
356 */
357 return;
358 }
359 if (method.getName().equalsIgnoreCase(math.getOperation().name()) && tool.getMetaAccess().lookupJavaType(Math.class).equals(method.getDeclaringClass())) {
360 /*
361 * A root compilation of the intrinsic method should emit the full assembly
362 * implementation.
363 */
364 return;
365 }
366
367 }
368 ForeignCallDescriptor foreignCall = toForeignCall(math.getOperation());
369 if (foreignCall != null) {
370 StructuredGraph graph = math.graph();
371 ForeignCallNode call = math.graph().add(new ForeignCallNode(foreignCalls, foreignCall, math.getValue()));
372 graph.addAfterFixed(tool.lastFixedNode(), call);
373 math.replaceAtUsages(call);
374 }
375 }
376
377 protected ForeignCallDescriptor toForeignCall(UnaryOperation operation) {
378 return operation.foreignCallDescriptor;
379 }
380
381 protected ForeignCallDescriptor toForeignCall(BinaryOperation operation) {
382 return operation.foreignCallDescriptor;
383 }
384
385 protected void lowerVerifyHeap(VerifyHeapNode n) {
386 GraphUtil.removeFixedWithUnusedInputs(n);
387 }
388
389 protected AddressNode createOffsetAddress(StructuredGraph graph, ValueNode object, long offset) {
390 ValueNode o = ConstantNode.forIntegerKind(target.wordJavaKind, offset, graph);
391 return graph.unique(new OffsetAddressNode(object, o));
392 }
393
394 protected AddressNode createFieldAddress(StructuredGraph graph, ValueNode object, ResolvedJavaField field) {
395 int offset = fieldOffset(field);
396 if (offset >= 0) {
397 return createOffsetAddress(graph, object, offset);
398 } else {
399 return null;
400 }
401 }
402
457 ValueNode positiveIndex = graph.maybeAddOrUnique(PiNode.create(index, POSITIVE_ARRAY_INDEX_STAMP, boundsCheck != null ? boundsCheck.asNode() : null));
458 return createArrayAddress(graph, array, elementKind, positiveIndex);
459 }
460
461 public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index) {
462 ValueNode wordIndex;
463 if (target.wordSize > 4) {
464 wordIndex = graph.unique(new SignExtendNode(index, target.wordSize * 8));
465 } else {
466 assert target.wordSize == 4 : "unsupported word size";
467 wordIndex = index;
468 }
469
470 int shift = CodeUtil.log2(metaAccess.getArrayIndexScale(elementKind));
471 ValueNode scaledIndex = graph.unique(new LeftShiftNode(wordIndex, ConstantNode.forInt(shift, graph)));
472
473 int base = metaAccess.getArrayBaseOffset(elementKind);
474 ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forIntegerKind(target.wordJavaKind, base, graph)));
475
476 return graph.unique(new OffsetAddressNode(array, offset));
477 }
478
479 protected void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) {
480 StructuredGraph graph = loadIndexed.graph();
481 ValueNode array = loadIndexed.array();
482 array = createNullCheckedValue(array, loadIndexed, tool);
483 JavaKind elementKind = loadIndexed.elementKind();
484 Stamp loadStamp = loadStamp(loadIndexed.stamp(NodeView.DEFAULT), elementKind);
485
486 GuardingNode boundsCheck = getBoundsCheck(loadIndexed, array, tool);
487 ValueNode index = loadIndexed.index();
488 if (UseIndexMasking.getValue(graph.getOptions())) {
489 index = proxyIndex(loadIndexed, index, array, tool);
490 }
491 AddressNode address = createArrayIndexAddress(graph, array, elementKind, index, boundsCheck);
492
493 ReadNode memoryRead = graph.add(new ReadNode(address, NamedLocationIdentity.getArrayLocation(elementKind), loadStamp, BarrierType.NONE));
494 memoryRead.setGuard(boundsCheck);
495 ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead);
496
|
30 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_WRITE;
31 import static jdk.vm.ci.meta.DeoptimizationAction.InvalidateReprofile;
32 import static jdk.vm.ci.meta.DeoptimizationReason.BoundsCheckException;
33 import static jdk.vm.ci.meta.DeoptimizationReason.NullCheckException;
34 import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.UseIndexMasking;
35 import static org.graalvm.compiler.nodes.NamedLocationIdentity.ARRAY_LENGTH_LOCATION;
36 import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.branchlessMax;
37 import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.branchlessMin;
38 import static org.graalvm.compiler.nodes.java.ArrayLengthNode.readArrayLength;
39 import static org.graalvm.compiler.nodes.util.GraphUtil.skipPiWhileNonNull;
40
41 import java.nio.ByteOrder;
42 import java.util.ArrayList;
43 import java.util.BitSet;
44 import java.util.List;
45
46 import org.graalvm.compiler.api.directives.GraalDirectives;
47 import org.graalvm.compiler.api.replacements.Snippet;
48 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
49 import org.graalvm.compiler.core.common.LIRKind;
50 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
51 import org.graalvm.compiler.core.common.type.IntegerStamp;
52 import org.graalvm.compiler.core.common.type.ObjectStamp;
53 import org.graalvm.compiler.core.common.type.Stamp;
54 import org.graalvm.compiler.core.common.type.StampFactory;
55 import org.graalvm.compiler.core.common.type.TypeReference;
56 import org.graalvm.compiler.debug.DebugCloseable;
57 import org.graalvm.compiler.debug.DebugHandlersFactory;
58 import org.graalvm.compiler.debug.GraalError;
59 import org.graalvm.compiler.graph.Node;
60 import org.graalvm.compiler.nodeinfo.InputType;
61 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
62 import org.graalvm.compiler.nodes.ConstantNode;
63 import org.graalvm.compiler.nodes.FieldLocationIdentity;
64 import org.graalvm.compiler.nodes.FixedNode;
65 import org.graalvm.compiler.nodes.LogicNode;
66 import org.graalvm.compiler.nodes.NamedLocationIdentity;
67 import org.graalvm.compiler.nodes.NodeView;
68 import org.graalvm.compiler.nodes.PiNode;
69 import org.graalvm.compiler.nodes.StructuredGraph;
105 import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
106 import org.graalvm.compiler.nodes.java.InstanceOfNode;
107 import org.graalvm.compiler.nodes.java.LoadFieldNode;
108 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
109 import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
110 import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
111 import org.graalvm.compiler.nodes.java.MonitorEnterNode;
112 import org.graalvm.compiler.nodes.java.MonitorIdNode;
113 import org.graalvm.compiler.nodes.java.NewArrayNode;
114 import org.graalvm.compiler.nodes.java.NewInstanceNode;
115 import org.graalvm.compiler.nodes.java.RawMonitorEnterNode;
116 import org.graalvm.compiler.nodes.java.StoreFieldNode;
117 import org.graalvm.compiler.nodes.java.StoreIndexedNode;
118 import org.graalvm.compiler.nodes.java.UnsafeCompareAndExchangeNode;
119 import org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode;
120 import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
121 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
122 import org.graalvm.compiler.nodes.memory.ReadNode;
123 import org.graalvm.compiler.nodes.memory.WriteNode;
124 import org.graalvm.compiler.nodes.memory.address.AddressNode;
125 import org.graalvm.compiler.nodes.memory.address.IndexAddressNode;
126 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
127 import org.graalvm.compiler.nodes.spi.Lowerable;
128 import org.graalvm.compiler.nodes.spi.LoweringProvider;
129 import org.graalvm.compiler.nodes.spi.LoweringTool;
130 import org.graalvm.compiler.nodes.type.StampTool;
131 import org.graalvm.compiler.nodes.util.GraphUtil;
132 import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
133 import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
134 import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
135 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
136 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
137 import org.graalvm.compiler.options.OptionValues;
138 import org.graalvm.compiler.phases.util.Providers;
139 import org.graalvm.compiler.replacements.SnippetLowerableMemoryNode.SnippetLowering;
140 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
141 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
142 import jdk.internal.vm.compiler.word.LocationIdentity;
143
144 import jdk.vm.ci.code.CodeUtil;
145 import jdk.vm.ci.code.MemoryBarriers;
146 import jdk.vm.ci.code.TargetDescription;
147 import jdk.vm.ci.meta.DeoptimizationAction;
148 import jdk.vm.ci.meta.DeoptimizationReason;
149 import jdk.vm.ci.meta.JavaKind;
150 import jdk.vm.ci.meta.MetaAccessProvider;
151 import jdk.vm.ci.meta.ResolvedJavaField;
152 import jdk.vm.ci.meta.ResolvedJavaMethod;
153 import jdk.vm.ci.meta.ResolvedJavaType;
154 import jdk.vm.ci.meta.SpeculationLog;
155
156 /**
157 * VM-independent lowerings for standard Java nodes. VM-specific methods are abstract and must be
158 * implemented by VM-specific subclasses.
159 */
160 public abstract class DefaultJavaLoweringProvider implements LoweringProvider {
161
187 }
188
189 public MetaAccessProvider getMetaAccess() {
190 return metaAccess;
191 }
192
193 @Override
194 @SuppressWarnings("try")
195 public void lower(Node n, LoweringTool tool) {
196 assert n instanceof Lowerable;
197 StructuredGraph graph = (StructuredGraph) n.graph();
198 try (DebugCloseable context = n.withNodeSourcePosition()) {
199 if (n instanceof LoadFieldNode) {
200 lowerLoadFieldNode((LoadFieldNode) n, tool);
201 } else if (n instanceof StoreFieldNode) {
202 lowerStoreFieldNode((StoreFieldNode) n, tool);
203 } else if (n instanceof LoadIndexedNode) {
204 lowerLoadIndexedNode((LoadIndexedNode) n, tool);
205 } else if (n instanceof StoreIndexedNode) {
206 lowerStoreIndexedNode((StoreIndexedNode) n, tool);
207 } else if (n instanceof IndexAddressNode) {
208 lowerIndexAddressNode((IndexAddressNode) n);
209 } else if (n instanceof ArrayLengthNode) {
210 lowerArrayLengthNode((ArrayLengthNode) n, tool);
211 } else if (n instanceof LoadHubNode) {
212 lowerLoadHubNode((LoadHubNode) n, tool);
213 } else if (n instanceof LoadArrayComponentHubNode) {
214 lowerLoadArrayComponentHubNode((LoadArrayComponentHubNode) n);
215 } else if (n instanceof MonitorEnterNode) {
216 lowerMonitorEnterNode((MonitorEnterNode) n, tool, graph);
217 } else if (n instanceof UnsafeCompareAndSwapNode) {
218 lowerCompareAndSwapNode((UnsafeCompareAndSwapNode) n);
219 } else if (n instanceof UnsafeCompareAndExchangeNode) {
220 lowerCompareAndExchangeNode((UnsafeCompareAndExchangeNode) n);
221 } else if (n instanceof AtomicReadAndWriteNode) {
222 lowerAtomicReadAndWriteNode((AtomicReadAndWriteNode) n);
223 } else if (n instanceof RawLoadNode) {
224 lowerUnsafeLoadNode((RawLoadNode) n, tool);
225 } else if (n instanceof UnsafeMemoryLoadNode) {
226 lowerUnsafeMemoryLoadNode((UnsafeMemoryLoadNode) n);
227 } else if (n instanceof RawStoreNode) {
228 lowerUnsafeStoreNode((RawStoreNode) n);
304 public void lower(SnippetLowerableMemoryNode node, LoweringTool tool) {
305 if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
306 return;
307 }
308 indexOfSnippets.lowerUTF16(node, tool);
309 }
310 };
311 SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), n.stamp(NodeView.DEFAULT), n.toArgumentArray());
312 n.graph().add(snippetLower);
313 n.graph().replaceFixedWithFixed(n, snippetLower);
314 }
315 }
316
317 private void lowerBinaryMath(BinaryMathIntrinsicNode math, LoweringTool tool) {
318 if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
319 return;
320 }
321 ResolvedJavaMethod method = math.graph().method();
322 if (method != null) {
323 if (method.getAnnotation(Snippet.class) != null) {
324 // In the context of SnippetStub, i.e., Graal-generated stubs, use the LIR
325 // lowering to emit the stub assembly code instead of the Node lowering.
326 return;
327 }
328 if (method.getName().equalsIgnoreCase(math.getOperation().name()) && tool.getMetaAccess().lookupJavaType(Math.class).equals(method.getDeclaringClass())) {
329 // A root compilation of the intrinsic method should emit the full assembly
330 // implementation.
331 return;
332 }
333 }
334 StructuredGraph graph = math.graph();
335 ForeignCallNode call = graph.add(new ForeignCallNode(foreignCalls, math.getOperation().foreignCallDescriptor, math.getX(), math.getY()));
336 graph.addAfterFixed(tool.lastFixedNode(), call);
337 math.replaceAtUsages(call);
338 }
339
340 private void lowerUnaryMath(UnaryMathIntrinsicNode math, LoweringTool tool) {
341 if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
342 return;
343 }
344 ResolvedJavaMethod method = math.graph().method();
345 if (method != null) {
346 if (method.getName().equalsIgnoreCase(math.getOperation().name()) && tool.getMetaAccess().lookupJavaType(Math.class).equals(method.getDeclaringClass())) {
347 // A root compilation of the intrinsic method should emit the full assembly
348 // implementation.
349 return;
350 }
351 }
352 StructuredGraph graph = math.graph();
353 ForeignCallNode call = math.graph().add(new ForeignCallNode(foreignCalls, math.getOperation().foreignCallDescriptor, math.getValue()));
354 graph.addAfterFixed(tool.lastFixedNode(), call);
355 math.replaceAtUsages(call);
356 }
357
358 protected void lowerVerifyHeap(VerifyHeapNode n) {
359 GraphUtil.removeFixedWithUnusedInputs(n);
360 }
361
362 protected AddressNode createOffsetAddress(StructuredGraph graph, ValueNode object, long offset) {
363 ValueNode o = ConstantNode.forIntegerKind(target.wordJavaKind, offset, graph);
364 return graph.unique(new OffsetAddressNode(object, o));
365 }
366
367 protected AddressNode createFieldAddress(StructuredGraph graph, ValueNode object, ResolvedJavaField field) {
368 int offset = fieldOffset(field);
369 if (offset >= 0) {
370 return createOffsetAddress(graph, object, offset);
371 } else {
372 return null;
373 }
374 }
375
430 ValueNode positiveIndex = graph.maybeAddOrUnique(PiNode.create(index, POSITIVE_ARRAY_INDEX_STAMP, boundsCheck != null ? boundsCheck.asNode() : null));
431 return createArrayAddress(graph, array, elementKind, positiveIndex);
432 }
433
434 public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index) {
435 ValueNode wordIndex;
436 if (target.wordSize > 4) {
437 wordIndex = graph.unique(new SignExtendNode(index, target.wordSize * 8));
438 } else {
439 assert target.wordSize == 4 : "unsupported word size";
440 wordIndex = index;
441 }
442
443 int shift = CodeUtil.log2(metaAccess.getArrayIndexScale(elementKind));
444 ValueNode scaledIndex = graph.unique(new LeftShiftNode(wordIndex, ConstantNode.forInt(shift, graph)));
445
446 int base = metaAccess.getArrayBaseOffset(elementKind);
447 ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forIntegerKind(target.wordJavaKind, base, graph)));
448
449 return graph.unique(new OffsetAddressNode(array, offset));
450 }
451
452 protected void lowerIndexAddressNode(IndexAddressNode indexAddress) {
453 AddressNode lowered = createArrayAddress(indexAddress.graph(), indexAddress.getArray(), indexAddress.getElementKind(), indexAddress.getIndex());
454 indexAddress.replaceAndDelete(lowered);
455 }
456
457 protected void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) {
458 StructuredGraph graph = loadIndexed.graph();
459 ValueNode array = loadIndexed.array();
460 array = createNullCheckedValue(array, loadIndexed, tool);
461 JavaKind elementKind = loadIndexed.elementKind();
462 Stamp loadStamp = loadStamp(loadIndexed.stamp(NodeView.DEFAULT), elementKind);
463
464 GuardingNode boundsCheck = getBoundsCheck(loadIndexed, array, tool);
465 ValueNode index = loadIndexed.index();
466 if (UseIndexMasking.getValue(graph.getOptions())) {
467 index = proxyIndex(loadIndexed, index, array, tool);
468 }
469 AddressNode address = createArrayIndexAddress(graph, array, elementKind, index, boundsCheck);
470
471 ReadNode memoryRead = graph.add(new ReadNode(address, NamedLocationIdentity.getArrayLocation(elementKind), loadStamp, BarrierType.NONE));
472 memoryRead.setGuard(boundsCheck);
473 ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead);
474
|