< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java

Print this page
rev 52509 : [mq]: graal2


  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 
  25 package org.graalvm.compiler.replacements;
  26 
  27 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_READ;
  28 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_WRITE;
  29 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_READ;
  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.nodes.NamedLocationIdentity.ARRAY_LENGTH_LOCATION;


  35 import static org.graalvm.compiler.nodes.java.ArrayLengthNode.readArrayLength;
  36 import static org.graalvm.compiler.nodes.util.GraphUtil.skipPiWhileNonNull;
  37 
  38 import java.nio.ByteOrder;
  39 import java.util.ArrayList;
  40 import java.util.BitSet;
  41 import java.util.List;
  42 
  43 import org.graalvm.compiler.api.directives.GraalDirectives;
  44 import org.graalvm.compiler.api.replacements.Snippet;
  45 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  46 import org.graalvm.compiler.core.common.LIRKind;
  47 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
  48 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
  49 import org.graalvm.compiler.core.common.type.IntegerStamp;
  50 import org.graalvm.compiler.core.common.type.ObjectStamp;
  51 import org.graalvm.compiler.core.common.type.Stamp;
  52 import org.graalvm.compiler.core.common.type.StampFactory;
  53 import org.graalvm.compiler.core.common.type.TypeReference;
  54 import org.graalvm.compiler.debug.DebugCloseable;


 168     private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
 169 
 170     public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target, boolean useCompressedOops) {
 171         this.metaAccess = metaAccess;
 172         this.foreignCalls = foreignCalls;
 173         this.target = target;
 174         this.useCompressedOops = useCompressedOops;
 175         this.objectArrayType = metaAccess.lookupJavaType(Object[].class);
 176     }
 177 
 178     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
 179         boxingSnippets = new BoxingSnippets.Templates(options, factories, factory, providers, snippetReflection, target);
 180         indexOfSnippets = new ConstantStringIndexOfSnippets.Templates(options, factories, providers, snippetReflection, target);
 181         providers.getReplacements().registerSnippetTemplateCache(new SnippetCounterNode.SnippetCounterSnippets.Templates(options, factories, providers, snippetReflection, target));
 182     }
 183 
 184     public final TargetDescription getTarget() {
 185         return target;
 186     }
 187 




 188     @Override
 189     @SuppressWarnings("try")
 190     public void lower(Node n, LoweringTool tool) {
 191         assert n instanceof Lowerable;
 192         StructuredGraph graph = (StructuredGraph) n.graph();
 193         try (DebugCloseable context = n.withNodeSourcePosition()) {
 194             if (n instanceof LoadFieldNode) {
 195                 lowerLoadFieldNode((LoadFieldNode) n, tool);
 196             } else if (n instanceof StoreFieldNode) {
 197                 lowerStoreFieldNode((StoreFieldNode) n, tool);
 198             } else if (n instanceof LoadIndexedNode) {
 199                 lowerLoadIndexedNode((LoadIndexedNode) n, tool);
 200             } else if (n instanceof StoreIndexedNode) {
 201                 lowerStoreIndexedNode((StoreIndexedNode) n, tool);
 202             } else if (n instanceof ArrayLengthNode) {
 203                 lowerArrayLengthNode((ArrayLengthNode) n, tool);
 204             } else if (n instanceof LoadHubNode) {
 205                 lowerLoadHubNode((LoadHubNode) n, tool);
 206             } else if (n instanceof LoadArrayComponentHubNode) {
 207                 lowerLoadArrayComponentHubNode((LoadArrayComponentHubNode) n);


 423         StructuredGraph graph = storeField.graph();
 424         ResolvedJavaField field = storeField.field();
 425         ValueNode object = storeField.isStatic() ? staticFieldBase(graph, field) : storeField.object();
 426         object = createNullCheckedValue(object, storeField, tool);
 427         ValueNode value = implicitStoreConvert(graph, getStorageKind(storeField.field()), storeField.value());
 428         AddressNode address = createFieldAddress(graph, object, field);
 429         assert address != null;
 430 
 431         WriteNode memoryWrite = graph.add(new WriteNode(address, fieldLocationIdentity(field), value, fieldStoreBarrierType(storeField.field())));
 432         memoryWrite.setStateAfter(storeField.stateAfter());
 433         graph.replaceFixedWithFixed(storeField, memoryWrite);
 434 
 435         if (storeField.isVolatile()) {
 436             MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
 437             graph.addBeforeFixed(memoryWrite, preMembar);
 438             MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
 439             graph.addAfterFixed(memoryWrite, postMembar);
 440         }
 441     }
 442 


 443     /**
 444      * Create a PiNode on the index proving that the index is positive. On some platforms this is
 445      * important to allow the index to be used as an int in the address mode.
 446      */
 447     public AddressNode createArrayIndexAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index, GuardingNode boundsCheck) {
 448         IntegerStamp indexStamp = StampFactory.forInteger(32, 0, Integer.MAX_VALUE - 1);
 449         ValueNode positiveIndex = graph.maybeAddOrUnique(PiNode.create(index, indexStamp, boundsCheck != null ? boundsCheck.asNode() : null));
 450         return createArrayAddress(graph, array, elementKind, positiveIndex);
 451     }
 452 
 453     public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index) {
 454         ValueNode wordIndex;
 455         if (target.wordSize > 4) {
 456             wordIndex = graph.unique(new SignExtendNode(index, target.wordSize * 8));
 457         } else {
 458             assert target.wordSize == 4 : "unsupported word size";
 459             wordIndex = index;
 460         }
 461 
 462         int shift = CodeUtil.log2(arrayScalingFactor(elementKind));
 463         ValueNode scaledIndex = graph.unique(new LeftShiftNode(wordIndex, ConstantNode.forInt(shift, graph)));
 464 
 465         int base = arrayBaseOffset(elementKind);
 466         ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forIntegerKind(target.wordJavaKind, base, graph)));
 467 
 468         return graph.unique(new OffsetAddressNode(array, offset));
 469     }
 470 
 471     protected void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) {
 472         StructuredGraph graph = loadIndexed.graph();
 473         ValueNode array = loadIndexed.array();
 474         array = createNullCheckedValue(array, loadIndexed, tool);
 475         JavaKind elementKind = loadIndexed.elementKind();
 476         Stamp loadStamp = loadStamp(loadIndexed.stamp(NodeView.DEFAULT), elementKind);
 477 
 478         GuardingNode boundsCheck = getBoundsCheck(loadIndexed, array, tool);
 479         AddressNode address = createArrayIndexAddress(graph, array, elementKind, loadIndexed.index(), boundsCheck);





 480         ReadNode memoryRead = graph.add(new ReadNode(address, NamedLocationIdentity.getArrayLocation(elementKind), loadStamp, BarrierType.NONE));
 481         memoryRead.setGuard(boundsCheck);
 482         ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead);
 483 
 484         loadIndexed.replaceAtUsages(readValue);
 485         graph.replaceFixed(loadIndexed, memoryRead);
 486     }
 487 
 488     protected void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool) {
 489         StructuredGraph graph = storeIndexed.graph();
 490 
 491         ValueNode value = storeIndexed.value();
 492         ValueNode array = storeIndexed.array();
 493 
 494         array = this.createNullCheckedValue(array, storeIndexed, tool);
 495 
 496         GuardingNode boundsCheck = getBoundsCheck(storeIndexed, array, tool);
 497 
 498         JavaKind elementKind = storeIndexed.elementKind();
 499 


 783                         if (value == null) {
 784                             omittedValues.set(valuePos);
 785                         } else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
 786                             // Constant.illegal is always the defaultForKind, so it is skipped
 787                             JavaKind valueKind = value.getStackKind();
 788                             JavaKind entryKind = virtual.entryKind(i);
 789 
 790                             // Truffle requires some leniency in terms of what can be put where:
 791                             assert valueKind.getStackKind() == entryKind.getStackKind() ||
 792                                             (valueKind == JavaKind.Long || valueKind == JavaKind.Double || (valueKind == JavaKind.Int && virtual instanceof VirtualArrayNode));
 793                             AddressNode address = null;
 794                             BarrierType barrierType = null;
 795                             if (virtual instanceof VirtualInstanceNode) {
 796                                 ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
 797                                 long offset = fieldOffset(field);
 798                                 if (offset >= 0) {
 799                                     address = createOffsetAddress(graph, newObject, offset);
 800                                     barrierType = fieldInitializationBarrier(entryKind);
 801                                 }
 802                             } else {
 803                                 address = createOffsetAddress(graph, newObject, arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind));
 804                                 barrierType = arrayInitializationBarrier(entryKind);
 805                             }
 806                             if (address != null) {
 807                                 WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
 808                                 graph.addAfterFixed(newObject, graph.add(write));
 809                             }
 810                         }
 811                         valuePos++;
 812                     }
 813                 }
 814             }
 815             valuePos = 0;
 816 
 817             for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
 818                 VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
 819                 try (DebugCloseable nsp = graph.withNodeSourcePosition(virtual)) {
 820                     int entryCount = virtual.entryCount();
 821                     ValueNode newObject = allocations[objIndex];
 822                     for (int i = 0; i < entryCount; i++) {
 823                         if (omittedValues.get(valuePos)) {


 983             // of Object[] then treat it as an array.
 984             if (type == null || type.isArray() || type.isAssignableFrom(objectArrayType)) {
 985                 return BarrierType.PRECISE;
 986             } else {
 987                 return BarrierType.IMPRECISE;
 988             }
 989         }
 990         return BarrierType.NONE;
 991     }
 992 
 993     public abstract int fieldOffset(ResolvedJavaField field);
 994 
 995     public FieldLocationIdentity fieldLocationIdentity(ResolvedJavaField field) {
 996         return new FieldLocationIdentity(field);
 997     }
 998 
 999     public abstract ValueNode staticFieldBase(StructuredGraph graph, ResolvedJavaField field);
1000 
1001     public abstract int arrayLengthOffset();
1002 
1003     @Override
1004     public int arrayScalingFactor(JavaKind elementKind) {
1005         return target.arch.getPlatformKind(elementKind).getSizeInBytes();
1006     }
1007 
1008     public Stamp loadStamp(Stamp stamp, JavaKind kind) {
1009         return loadStamp(stamp, kind, true);
1010     }
1011 
1012     private boolean useCompressedOops(JavaKind kind, boolean compressible) {
1013         return kind == JavaKind.Object && compressible && useCompressedOops;
1014     }
1015 
1016     protected abstract Stamp loadCompressedStamp(ObjectStamp stamp);
1017 
1018     /**
1019      * @param compressible whether the stamp should be compressible
1020      */
1021     protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
1022         if (useCompressedOops(kind, compressible)) {
1023             return loadCompressedStamp((ObjectStamp) stamp);
1024         }
1025 
1026         switch (kind) {
1027             case Boolean:


1093     protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
1094         if (useCompressedOops(kind, compressible)) {
1095             return newCompressionNode(CompressionOp.Compress, value);
1096         }
1097 
1098         switch (kind) {
1099             case Boolean:
1100             case Byte:
1101                 return new NarrowNode(value, 8);
1102             case Char:
1103             case Short:
1104                 return new NarrowNode(value, 16);
1105         }
1106         return value;
1107     }
1108 
1109     protected abstract ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool);
1110 
1111     protected abstract ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor);
1112 







1113     protected GuardingNode getBoundsCheck(AccessIndexedNode n, ValueNode array, LoweringTool tool) {
1114         if (n.getBoundsCheck() != null) {
1115             return n.getBoundsCheck();
1116         }
1117 
1118         StructuredGraph graph = n.graph();
1119         ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection());
1120         if (arrayLength == null) {
1121             arrayLength = createReadArrayLength(array, n, tool);
1122         } else {
1123             arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength);
1124         }
1125 
1126         LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength, NodeView.DEFAULT);
1127         if (boundsCheck.isTautology()) {
1128             return null;
1129         }
1130         return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
1131     }
1132 










1133     protected GuardingNode createNullCheck(ValueNode object, FixedNode before, LoweringTool tool) {
1134         if (StampTool.isPointerNonNull(object)) {
1135             return null;
1136         }
1137         return tool.createGuard(before, before.graph().unique(IsNullNode.create(object)), NullCheckException, InvalidateReprofile, SpeculationLog.NO_SPECULATION, true, null);
1138     }
1139 
1140     protected ValueNode createNullCheckedValue(ValueNode object, FixedNode before, LoweringTool tool) {
1141         GuardingNode nullCheck = createNullCheck(object, before, tool);
1142         if (nullCheck == null) {
1143             return object;
1144         }
1145         return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp(NodeView.DEFAULT)).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
1146     }
1147 
1148     @Override
1149     public ValueNode reconstructArrayIndex(JavaKind elementKind, AddressNode address) {
1150         StructuredGraph graph = address.graph();
1151         ValueNode offset = ((OffsetAddressNode) address).getOffset();
1152 
1153         int base = arrayBaseOffset(elementKind);
1154         ValueNode scaledIndex = graph.unique(new SubNode(offset, ConstantNode.forIntegerStamp(offset.stamp(NodeView.DEFAULT), base, graph)));
1155 
1156         int shift = CodeUtil.log2(arrayScalingFactor(elementKind));
1157         ValueNode ret = graph.unique(new RightShiftNode(scaledIndex, ConstantNode.forInt(shift, graph)));
1158         return IntegerConvertNode.convert(ret, StampFactory.forKind(JavaKind.Int), graph, NodeView.DEFAULT);
1159     }
1160 }


  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 
  25 package org.graalvm.compiler.replacements;
  26 
  27 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_READ;
  28 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_WRITE;
  29 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_READ;
  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;


 171     private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
 172 
 173     public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target, boolean useCompressedOops) {
 174         this.metaAccess = metaAccess;
 175         this.foreignCalls = foreignCalls;
 176         this.target = target;
 177         this.useCompressedOops = useCompressedOops;
 178         this.objectArrayType = metaAccess.lookupJavaType(Object[].class);
 179     }
 180 
 181     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
 182         boxingSnippets = new BoxingSnippets.Templates(options, factories, factory, providers, snippetReflection, target);
 183         indexOfSnippets = new ConstantStringIndexOfSnippets.Templates(options, factories, providers, snippetReflection, target);
 184         providers.getReplacements().registerSnippetTemplateCache(new SnippetCounterNode.SnippetCounterSnippets.Templates(options, factories, providers, snippetReflection, target));
 185     }
 186 
 187     public final TargetDescription getTarget() {
 188         return target;
 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);


 430         StructuredGraph graph = storeField.graph();
 431         ResolvedJavaField field = storeField.field();
 432         ValueNode object = storeField.isStatic() ? staticFieldBase(graph, field) : storeField.object();
 433         object = createNullCheckedValue(object, storeField, tool);
 434         ValueNode value = implicitStoreConvert(graph, getStorageKind(storeField.field()), storeField.value());
 435         AddressNode address = createFieldAddress(graph, object, field);
 436         assert address != null;
 437 
 438         WriteNode memoryWrite = graph.add(new WriteNode(address, fieldLocationIdentity(field), value, fieldStoreBarrierType(storeField.field())));
 439         memoryWrite.setStateAfter(storeField.stateAfter());
 440         graph.replaceFixedWithFixed(storeField, memoryWrite);
 441 
 442         if (storeField.isVolatile()) {
 443             MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
 444             graph.addBeforeFixed(memoryWrite, preMembar);
 445             MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
 446             graph.addAfterFixed(memoryWrite, postMembar);
 447         }
 448     }
 449 
 450     public static final IntegerStamp POSITIVE_ARRAY_INDEX_STAMP = StampFactory.forInteger(32, 0, Integer.MAX_VALUE - 1);
 451 
 452     /**
 453      * Create a PiNode on the index proving that the index is positive. On some platforms this is
 454      * important to allow the index to be used as an int in the address mode.
 455      */
 456     public AddressNode createArrayIndexAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index, GuardingNode boundsCheck) {
 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 
 497         loadIndexed.replaceAtUsages(readValue);
 498         graph.replaceFixed(loadIndexed, memoryRead);
 499     }
 500 
 501     protected void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool) {
 502         StructuredGraph graph = storeIndexed.graph();
 503 
 504         ValueNode value = storeIndexed.value();
 505         ValueNode array = storeIndexed.array();
 506 
 507         array = this.createNullCheckedValue(array, storeIndexed, tool);
 508 
 509         GuardingNode boundsCheck = getBoundsCheck(storeIndexed, array, tool);
 510 
 511         JavaKind elementKind = storeIndexed.elementKind();
 512 


 796                         if (value == null) {
 797                             omittedValues.set(valuePos);
 798                         } else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
 799                             // Constant.illegal is always the defaultForKind, so it is skipped
 800                             JavaKind valueKind = value.getStackKind();
 801                             JavaKind entryKind = virtual.entryKind(i);
 802 
 803                             // Truffle requires some leniency in terms of what can be put where:
 804                             assert valueKind.getStackKind() == entryKind.getStackKind() ||
 805                                             (valueKind == JavaKind.Long || valueKind == JavaKind.Double || (valueKind == JavaKind.Int && virtual instanceof VirtualArrayNode));
 806                             AddressNode address = null;
 807                             BarrierType barrierType = null;
 808                             if (virtual instanceof VirtualInstanceNode) {
 809                                 ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
 810                                 long offset = fieldOffset(field);
 811                                 if (offset >= 0) {
 812                                     address = createOffsetAddress(graph, newObject, offset);
 813                                     barrierType = fieldInitializationBarrier(entryKind);
 814                                 }
 815                             } else {
 816                                 address = createOffsetAddress(graph, newObject, metaAccess.getArrayBaseOffset(entryKind) + i * metaAccess.getArrayIndexScale(entryKind));
 817                                 barrierType = arrayInitializationBarrier(entryKind);
 818                             }
 819                             if (address != null) {
 820                                 WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
 821                                 graph.addAfterFixed(newObject, graph.add(write));
 822                             }
 823                         }
 824                         valuePos++;
 825                     }
 826                 }
 827             }
 828             valuePos = 0;
 829 
 830             for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
 831                 VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
 832                 try (DebugCloseable nsp = graph.withNodeSourcePosition(virtual)) {
 833                     int entryCount = virtual.entryCount();
 834                     ValueNode newObject = allocations[objIndex];
 835                     for (int i = 0; i < entryCount; i++) {
 836                         if (omittedValues.get(valuePos)) {


 996             // of Object[] then treat it as an array.
 997             if (type == null || type.isArray() || type.isAssignableFrom(objectArrayType)) {
 998                 return BarrierType.PRECISE;
 999             } else {
1000                 return BarrierType.IMPRECISE;
1001             }
1002         }
1003         return BarrierType.NONE;
1004     }
1005 
1006     public abstract int fieldOffset(ResolvedJavaField field);
1007 
1008     public FieldLocationIdentity fieldLocationIdentity(ResolvedJavaField field) {
1009         return new FieldLocationIdentity(field);
1010     }
1011 
1012     public abstract ValueNode staticFieldBase(StructuredGraph graph, ResolvedJavaField field);
1013 
1014     public abstract int arrayLengthOffset();
1015 





1016     public Stamp loadStamp(Stamp stamp, JavaKind kind) {
1017         return loadStamp(stamp, kind, true);
1018     }
1019 
1020     private boolean useCompressedOops(JavaKind kind, boolean compressible) {
1021         return kind == JavaKind.Object && compressible && useCompressedOops;
1022     }
1023 
1024     protected abstract Stamp loadCompressedStamp(ObjectStamp stamp);
1025 
1026     /**
1027      * @param compressible whether the stamp should be compressible
1028      */
1029     protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
1030         if (useCompressedOops(kind, compressible)) {
1031             return loadCompressedStamp((ObjectStamp) stamp);
1032         }
1033 
1034         switch (kind) {
1035             case Boolean:


1101     protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
1102         if (useCompressedOops(kind, compressible)) {
1103             return newCompressionNode(CompressionOp.Compress, value);
1104         }
1105 
1106         switch (kind) {
1107             case Boolean:
1108             case Byte:
1109                 return new NarrowNode(value, 8);
1110             case Char:
1111             case Short:
1112                 return new NarrowNode(value, 16);
1113         }
1114         return value;
1115     }
1116 
1117     protected abstract ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool);
1118 
1119     protected abstract ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor);
1120 
1121     protected ValueNode proxyIndex(AccessIndexedNode n, ValueNode index, ValueNode array, LoweringTool tool) {
1122         StructuredGraph graph = index.graph();
1123         ValueNode arrayLength = readOrCreateArrayLength(n, array, tool, graph);
1124         ValueNode lengthMinusOne = SubNode.create(arrayLength, ConstantNode.forInt(1), NodeView.DEFAULT);
1125         return branchlessMax(branchlessMin(index, lengthMinusOne, NodeView.DEFAULT), ConstantNode.forInt(0), NodeView.DEFAULT);
1126     }
1127 
1128     protected GuardingNode getBoundsCheck(AccessIndexedNode n, ValueNode array, LoweringTool tool) {
1129         if (n.getBoundsCheck() != null) {
1130             return n.getBoundsCheck();
1131         }
1132 
1133         StructuredGraph graph = n.graph();
1134         ValueNode arrayLength = readOrCreateArrayLength(n, array, tool, graph);





1135 
1136         LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength, NodeView.DEFAULT);
1137         if (boundsCheck.isTautology()) {
1138             return null;
1139         }
1140         return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
1141     }
1142 
1143     private ValueNode readOrCreateArrayLength(AccessIndexedNode n, ValueNode array, LoweringTool tool, StructuredGraph graph) {
1144         ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection());
1145         if (arrayLength == null) {
1146             arrayLength = createReadArrayLength(array, n, tool);
1147         } else {
1148             arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength);
1149         }
1150         return arrayLength;
1151     }
1152 
1153     protected GuardingNode createNullCheck(ValueNode object, FixedNode before, LoweringTool tool) {
1154         if (StampTool.isPointerNonNull(object)) {
1155             return null;
1156         }
1157         return tool.createGuard(before, before.graph().unique(IsNullNode.create(object)), NullCheckException, InvalidateReprofile, SpeculationLog.NO_SPECULATION, true, null);
1158     }
1159 
1160     protected ValueNode createNullCheckedValue(ValueNode object, FixedNode before, LoweringTool tool) {
1161         GuardingNode nullCheck = createNullCheck(object, before, tool);
1162         if (nullCheck == null) {
1163             return object;
1164         }
1165         return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp(NodeView.DEFAULT)).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
1166     }
1167 
1168     @Override
1169     public ValueNode reconstructArrayIndex(JavaKind elementKind, AddressNode address) {
1170         StructuredGraph graph = address.graph();
1171         ValueNode offset = ((OffsetAddressNode) address).getOffset();
1172 
1173         int base = metaAccess.getArrayBaseOffset(elementKind);
1174         ValueNode scaledIndex = graph.unique(new SubNode(offset, ConstantNode.forIntegerStamp(offset.stamp(NodeView.DEFAULT), base, graph)));
1175 
1176         int shift = CodeUtil.log2(metaAccess.getArrayIndexScale(elementKind));
1177         ValueNode ret = graph.unique(new RightShiftNode(scaledIndex, ConstantNode.forInt(shift, graph)));
1178         return IntegerConvertNode.convert(ret, StampFactory.forKind(JavaKind.Int), graph, NodeView.DEFAULT);
1179     }
1180 }
< prev index next >