--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Thu Oct 17 20:27:44 2019 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Thu Oct 17 20:53:35 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,12 +43,13 @@
import java.util.BitSet;
import java.util.List;
+import jdk.vm.ci.meta.JavaConstant;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
-import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
+import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
@@ -61,14 +62,20 @@
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.EndNode;
import org.graalvm.compiler.nodes.FieldLocationIdentity;
import org.graalvm.compiler.nodes.FixedNode;
+import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.calc.ConditionalNode;
import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
@@ -92,6 +99,7 @@
import org.graalvm.compiler.nodes.extended.JavaWriteNode;
import org.graalvm.compiler.nodes.extended.LoadArrayComponentHubNode;
import org.graalvm.compiler.nodes.extended.LoadHubNode;
+import org.graalvm.compiler.nodes.extended.LoadHubOrNullNode;
import org.graalvm.compiler.nodes.extended.MembarNode;
import org.graalvm.compiler.nodes.extended.RawLoadNode;
import org.graalvm.compiler.nodes.extended.RawStoreNode;
@@ -140,7 +148,6 @@
import org.graalvm.compiler.replacements.SnippetLowerableMemoryNode.SnippetLowering;
import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
-import org.graalvm.compiler.word.WordTypes;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.code.CodeUtil;
@@ -166,7 +173,6 @@
protected final TargetDescription target;
private final boolean useCompressedOops;
private final ResolvedJavaType objectArrayType;
- private final WordTypes wordTypes;
private BoxingSnippets.Templates boxingSnippets;
private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
@@ -177,7 +183,6 @@
this.target = target;
this.useCompressedOops = useCompressedOops;
this.objectArrayType = metaAccess.lookupJavaType(Object[].class);
- this.wordTypes = new WordTypes(metaAccess, target.wordJavaKind);
}
public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
@@ -214,6 +219,8 @@
lowerArrayLengthNode((ArrayLengthNode) n, tool);
} else if (n instanceof LoadHubNode) {
lowerLoadHubNode((LoadHubNode) n, tool);
+ } else if (n instanceof LoadHubOrNullNode) {
+ lowerLoadHubOrNullNode((LoadHubOrNullNode) n, tool);
} else if (n instanceof LoadArrayComponentHubNode) {
lowerLoadArrayComponentHubNode((LoadArrayComponentHubNode) n);
} else if (n instanceof MonitorEnterNode) {
@@ -436,6 +443,10 @@
}
public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index) {
+ return createArrayAddress(graph, array, elementKind, elementKind, index);
+ }
+
+ public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind arrayKind, JavaKind elementKind, ValueNode index) {
ValueNode wordIndex;
if (target.wordSize > 4) {
wordIndex = graph.unique(new SignExtendNode(index, target.wordSize * 8));
@@ -447,14 +458,14 @@
int shift = CodeUtil.log2(metaAccess.getArrayIndexScale(elementKind));
ValueNode scaledIndex = graph.unique(new LeftShiftNode(wordIndex, ConstantNode.forInt(shift, graph)));
- int base = metaAccess.getArrayBaseOffset(elementKind);
+ int base = metaAccess.getArrayBaseOffset(arrayKind);
ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forIntegerKind(target.wordJavaKind, base, graph)));
return graph.unique(new OffsetAddressNode(array, offset));
}
protected void lowerIndexAddressNode(IndexAddressNode indexAddress) {
- AddressNode lowered = createArrayAddress(indexAddress.graph(), indexAddress.getArray(), indexAddress.getElementKind(), indexAddress.getIndex());
+ AddressNode lowered = createArrayAddress(indexAddress.graph(), indexAddress.getArray(), indexAddress.getArrayKind(), indexAddress.getElementKind(), indexAddress.getIndex());
indexAddress.replaceAndDelete(lowered);
}
@@ -517,7 +528,7 @@
AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value),
- arrayStoreBarrierType(array, storeIndexed.elementKind())));
+ arrayStoreBarrierType(storeIndexed.elementKind())));
memoryWrite.setGuard(boundsCheck);
if (condition != null) {
tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
@@ -558,6 +569,36 @@
loadHub.replaceAtUsagesAndDelete(hub);
}
+ protected void lowerLoadHubOrNullNode(LoadHubOrNullNode loadHubOrNullNode, LoweringTool tool) {
+ StructuredGraph graph = loadHubOrNullNode.graph();
+ if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
+ return;
+ }
+ if (graph.getGuardsStage().allowsFloatingGuards()) {
+ return;
+ }
+ final FixedWithNextNode predecessor = tool.lastFixedNode();
+ final ValueNode value = loadHubOrNullNode.getValue();
+ AbstractPointerStamp stamp = (AbstractPointerStamp) value.stamp(NodeView.DEFAULT);
+ final LogicNode isNull = graph.addOrUniqueWithInputs(IsNullNode.create(value));
+ final EndNode trueEnd = graph.add(new EndNode());
+ final EndNode falseEnd = graph.add(new EndNode());
+ final IfNode ifNode = graph.add(new IfNode(isNull, trueEnd, falseEnd, 0.5));
+ final MergeNode merge = graph.add(new MergeNode());
+ merge.addForwardEnd(trueEnd);
+ merge.addForwardEnd(falseEnd);
+ final AbstractPointerStamp hubStamp = (AbstractPointerStamp) loadHubOrNullNode.stamp(NodeView.DEFAULT);
+ ValueNode nullHub = ConstantNode.forConstant(hubStamp.asAlwaysNull(), JavaConstant.NULL_POINTER, tool.getMetaAccess(), graph);
+ final ValueNode nonNullValue = graph.addOrUniqueWithInputs(PiNode.create(value, stamp.asNonNull(), ifNode.falseSuccessor()));
+ ValueNode hub = createReadHub(graph, nonNullValue, tool);
+ ValueNode[] values = new ValueNode[]{nullHub, hub};
+ final PhiNode hubPhi = graph.unique(new ValuePhiNode(hubStamp, merge, values));
+ final FixedNode oldNext = predecessor.next();
+ predecessor.setNext(ifNode);
+ merge.setNext(oldNext);
+ loadHubOrNullNode.replaceAtUsagesAndDelete(hubPhi);
+ }
+
protected void lowerLoadArrayComponentHubNode(LoadArrayComponentHubNode loadHub) {
StructuredGraph graph = loadHub.graph();
ValueNode hub = createReadArrayComponentHub(graph, loadHub.getValue(), loadHub);
@@ -766,6 +807,8 @@
} else {
newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
}
+ // The final STORE_STORE barrier will be emitted by finishAllocatedObjects
+ newObject.clearEmitMemoryBarrier();
recursiveLowerings.add(newObject);
graph.addBeforeFixed(commit, newObject);
@@ -792,11 +835,11 @@
long offset = fieldOffset(field);
if (offset >= 0) {
address = createOffsetAddress(graph, newObject, offset);
- barrierType = fieldInitializationBarrier(field);
+ barrierType = fieldInitializationBarrier(entryKind);
}
} else {
address = createOffsetAddress(graph, newObject, metaAccess.getArrayBaseOffset(entryKind) + i * metaAccess.getArrayIndexScale(entryKind));
- barrierType = arrayInitializationBarrier(newObject, entryKind);
+ barrierType = arrayInitializationBarrier(entryKind);
}
if (address != null) {
WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
@@ -829,7 +872,7 @@
barrierType = fieldStoreBarrierType(virtualInstance.field(i));
} else {
address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph));
- barrierType = arrayStoreBarrierType(newObject, virtual.entryKind(i));
+ barrierType = arrayStoreBarrierType(virtual.entryKind(i));
}
if (address != null) {
WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
@@ -943,50 +986,25 @@
}
protected BarrierType fieldStoreBarrierType(ResolvedJavaField field) {
- JavaKind fieldKind = wordTypes.asKind(field.getType());
- if (fieldKind == JavaKind.Object) {
+ if (getStorageKind(field) == JavaKind.Object) {
return BarrierType.FIELD;
}
return BarrierType.NONE;
}
- /**
- * If the given value is indeed an array, and its elements are of a word type, return the
- * correct word kind; in all other cases, return the defaultElementKind. This is needed for
- * determining the correct write barrier type.
- *
- * @param array a value that is expected to have an array stamp
- * @param defaultElementKind the array's element kind without taking word types into account
- * @return the element kind of the array taking word types into account
- */
- protected JavaKind maybeWordArrayElementKind(ValueNode array, JavaKind defaultElementKind) {
- JavaKind elementKind = defaultElementKind;
- Stamp arrayStamp = array.stamp(NodeView.DEFAULT);
- if (arrayStamp instanceof AbstractObjectStamp && arrayStamp.hasValues()) {
- ResolvedJavaType arrayType = ((AbstractObjectStamp) arrayStamp).type();
- if (arrayType != null && arrayType.getComponentType() != null) {
- elementKind = wordTypes.asKind(arrayType.getComponentType());
- }
- }
- return elementKind;
- }
-
- protected BarrierType arrayStoreBarrierType(ValueNode array, JavaKind elementKind) {
- JavaKind kind = maybeWordArrayElementKind(array, elementKind);
- if (kind == JavaKind.Object) {
+ protected BarrierType arrayStoreBarrierType(JavaKind elementKind) {
+ if (elementKind == JavaKind.Object) {
return BarrierType.ARRAY;
}
return BarrierType.NONE;
}
- public BarrierType fieldInitializationBarrier(ResolvedJavaField field) {
- JavaKind fieldKind = wordTypes.asKind(field.getType());
- return fieldKind == JavaKind.Object ? BarrierType.FIELD : BarrierType.NONE;
+ public BarrierType fieldInitializationBarrier(JavaKind entryKind) {
+ return entryKind == JavaKind.Object ? BarrierType.FIELD : BarrierType.NONE;
}
- public BarrierType arrayInitializationBarrier(ValueNode array, JavaKind entryKind) {
- JavaKind kind = maybeWordArrayElementKind(array, entryKind);
- return kind == JavaKind.Object ? BarrierType.ARRAY : BarrierType.NONE;
+ public BarrierType arrayInitializationBarrier(JavaKind entryKind) {
+ return entryKind == JavaKind.Object ? BarrierType.ARRAY : BarrierType.NONE;
}
private BarrierType unsafeStoreBarrierType(RawStoreNode store) {
@@ -1002,9 +1020,7 @@
// Array types must use a precise barrier, so if the type is unknown or is a supertype
// of Object[] then treat it as an array.
if (type != null && type.isArray()) {
- return arrayStoreBarrierType(object, JavaKind.Object);
- } else if (type != null && wordTypes.isWord(type)) {
- return BarrierType.NONE;
+ return BarrierType.ARRAY;
} else if (type == null || type.isAssignableFrom(objectArrayType)) {
return BarrierType.UNKNOWN;
} else {