use of org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType in project graal by oracle.
the class DefaultJavaLoweringProvider method lowerCommitAllocationNode.
@SuppressWarnings("try")
protected void lowerCommitAllocationNode(CommitAllocationNode commit, LoweringTool tool) {
StructuredGraph graph = commit.graph();
if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
List<AbstractNewObjectNode> recursiveLowerings = new ArrayList<>();
ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
BitSet omittedValues = new BitSet();
int valuePos = 0;
for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
try (DebugCloseable nsp = graph.withNodeSourcePosition(virtual)) {
int entryCount = virtual.entryCount();
AbstractNewObjectNode newObject;
if (virtual instanceof VirtualInstanceNode) {
newObject = graph.add(new NewInstanceNode(virtual.type(), true));
} else {
assert virtual instanceof VirtualArrayNode;
newObject = graph.add(new NewArrayNode(((VirtualArrayNode) virtual).componentType(), ConstantNode.forInt(entryCount, graph), true));
}
// The final STORE_STORE barrier will be emitted by finishAllocatedObjects
newObject.clearEmitMemoryBarrier();
recursiveLowerings.add(newObject);
graph.addBeforeFixed(commit, newObject);
allocations[objIndex] = newObject;
for (int i = 0; i < entryCount; i++) {
ValueNode value = commit.getValues().get(valuePos);
if (value instanceof VirtualObjectNode) {
value = allocations[commit.getVirtualObjects().indexOf(value)];
}
if (value == null) {
omittedValues.set(valuePos);
} else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
// Constant.illegal is always the defaultForKind, so it is skipped
JavaKind valueKind = value.getStackKind();
JavaKind storageKind = virtual.entryKind(tool.getMetaAccessExtensionProvider(), i);
// Truffle requires some leniency in terms of what can be put where:
assert valueKind.getStackKind() == storageKind.getStackKind() || (valueKind == JavaKind.Long || valueKind == JavaKind.Double || (valueKind == JavaKind.Int && virtual instanceof VirtualArrayNode) || (valueKind == JavaKind.Float && virtual instanceof VirtualArrayNode));
AddressNode address = null;
BarrierType barrierType = null;
if (virtual instanceof VirtualInstanceNode) {
ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
long offset = fieldOffset(field);
if (offset >= 0) {
address = createOffsetAddress(graph, newObject, offset);
barrierType = barrierSet.fieldStoreBarrierType(field, getStorageKind(field));
}
} else {
assert virtual instanceof VirtualArrayNode;
address = createOffsetAddress(graph, newObject, metaAccess.getArrayBaseOffset(storageKind) + i * metaAccess.getArrayIndexScale(storageKind));
barrierType = barrierSet.arrayStoreBarrierType(storageKind);
}
if (address != null) {
WriteNode write = new WriteNode(address, LocationIdentity.init(), arrayImplicitStoreConvert(graph, storageKind, value, commit, virtual, valuePos), barrierType);
graph.addAfterFixed(newObject, graph.add(write));
}
}
valuePos++;
}
}
}
valuePos = 0;
for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
try (DebugCloseable nsp = graph.withNodeSourcePosition(virtual)) {
int entryCount = virtual.entryCount();
ValueNode newObject = allocations[objIndex];
for (int i = 0; i < entryCount; i++) {
if (omittedValues.get(valuePos)) {
ValueNode value = commit.getValues().get(valuePos);
assert value instanceof VirtualObjectNode;
ValueNode allocValue = allocations[commit.getVirtualObjects().indexOf(value)];
if (!(allocValue.isConstant() && allocValue.asConstant().isDefaultForKind())) {
assert virtual.entryKind(metaAccessExtensionProvider, i) == JavaKind.Object && allocValue.getStackKind() == JavaKind.Object;
AddressNode address;
BarrierType barrierType;
if (virtual instanceof VirtualInstanceNode) {
VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
ResolvedJavaField field = virtualInstance.field(i);
address = createFieldAddress(graph, newObject, field);
barrierType = barrierSet.fieldStoreBarrierType(field, getStorageKind(field));
} else {
assert virtual instanceof VirtualArrayNode;
address = createArrayAddress(graph, newObject, virtual.entryKind(metaAccessExtensionProvider, i), ConstantNode.forInt(i, graph));
barrierType = barrierSet.arrayStoreBarrierType(virtual.entryKind(metaAccessExtensionProvider, i));
}
if (address != null) {
WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
graph.addBeforeFixed(commit, graph.add(write));
}
}
}
valuePos++;
}
}
}
finishAllocatedObjects(tool, commit, commit, allocations);
graph.removeFixed(commit);
for (AbstractNewObjectNode recursiveLowering : recursiveLowerings) {
recursiveLowering.lower(tool);
}
}
}
use of org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType in project graal by oracle.
the class DefaultJavaLoweringProvider method lowerCompareAndExchangeNode.
protected void lowerCompareAndExchangeNode(UnsafeCompareAndExchangeNode cas) {
StructuredGraph graph = cas.graph();
JavaKind valueKind = cas.getValueKind();
ValueNode expectedValue = implicitStoreConvert(graph, valueKind, cas.expected());
ValueNode newValue = implicitStoreConvert(graph, valueKind, cas.newValue());
AddressNode address = graph.unique(new OffsetAddressNode(cas.object(), cas.offset()));
BarrierType barrierType = barrierSet.guessStoreBarrierType(cas.object(), newValue);
ValueCompareAndSwapNode atomicNode = graph.add(new ValueCompareAndSwapNode(address, expectedValue, newValue, cas.getKilledLocationIdentity(), barrierType, cas.getMemoryOrder()));
ValueNode coercedNode = implicitLoadConvert(graph, valueKind, atomicNode, true);
atomicNode.setStateAfter(cas.stateAfter());
cas.replaceAtUsages(coercedNode);
graph.replaceFixedWithFixed(cas, atomicNode);
}
use of org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType in project graal by oracle.
the class DefaultJavaLoweringProvider method lowerStoreIndexedNode.
public void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool, int arrayBaseOffset) {
StructuredGraph graph = storeIndexed.graph();
ValueNode value = storeIndexed.value();
ValueNode array = storeIndexed.array();
array = this.createNullCheckedValue(array, storeIndexed, tool);
GuardingNode boundsCheck = getBoundsCheck(storeIndexed, array, tool);
JavaKind storageKind = storeIndexed.elementKind();
LogicNode condition = null;
if (storeIndexed.getStoreCheck() == null && storageKind == JavaKind.Object && !StampTool.isPointerAlwaysNull(value)) {
/* Array store check. */
TypeReference arrayType = StampTool.typeReferenceOrNull(array);
if (arrayType != null && arrayType.isExact()) {
ResolvedJavaType elementType = arrayType.getType().getComponentType();
if (!elementType.isJavaLangObject()) {
TypeReference typeReference = TypeReference.createTrusted(storeIndexed.graph().getAssumptions(), elementType);
LogicNode typeTest = graph.addOrUniqueWithInputs(InstanceOfNode.create(typeReference, value));
condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, BranchProbabilityNode.NOT_LIKELY_PROFILE);
}
} else {
/*
* The guard on the read hub should be the null check of the array that was
* introduced earlier.
*/
ValueNode arrayClass = createReadHub(graph, array, tool);
boolean isKnownObjectArray = arrayType != null && !arrayType.getType().getComponentType().isPrimitive();
ValueNode componentHub = createReadArrayComponentHub(graph, arrayClass, isKnownObjectArray, storeIndexed);
LogicNode typeTest = graph.unique(InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), componentHub, value, false));
condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, BranchProbabilityNode.NOT_LIKELY_PROFILE);
}
if (condition != null && condition.isTautology()) {
// Skip unnecessary guards
condition = null;
}
}
BarrierType barrierType = barrierSet.arrayStoreBarrierType(storageKind);
ValueNode positiveIndex = createPositiveIndex(graph, storeIndexed.index(), boundsCheck);
AddressNode address = createArrayAddress(graph, array, arrayBaseOffset, storageKind, positiveIndex);
WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(storageKind), implicitStoreConvert(graph, storageKind, value), barrierType));
memoryWrite.setGuard(boundsCheck);
if (condition != null) {
tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
}
memoryWrite.setStateAfter(storeIndexed.stateAfter());
graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
}
Aggregations