use of org.graalvm.compiler.nodes.virtual.VirtualArrayNode in project graal by oracle.
the class ArrayLengthNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ValueNode alias = tool.getAlias(array());
if (alias instanceof VirtualArrayNode) {
VirtualArrayNode virtualArray = (VirtualArrayNode) alias;
tool.replaceWithValue(ConstantNode.forInt(virtualArray.entryCount(), graph()));
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualArrayNode in project graal by oracle.
the class BasicArrayCopyNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ValueNode sourcePosition = tool.getAlias(getSourcePosition());
ValueNode destinationPosition = tool.getAlias(getDestinationPosition());
ValueNode replacedLength = tool.getAlias(getLength());
if (sourcePosition.isConstant() && destinationPosition.isConstant() && replacedLength.isConstant()) {
int srcPosInt = sourcePosition.asJavaConstant().asInt();
int destPosInt = destinationPosition.asJavaConstant().asInt();
int len = replacedLength.asJavaConstant().asInt();
ValueNode destAlias = tool.getAlias(getDestination());
if (destAlias instanceof VirtualArrayNode) {
VirtualArrayNode destVirtual = (VirtualArrayNode) destAlias;
if (len < 0 || !checkBounds(destPosInt, len, destVirtual)) {
return;
}
ValueNode srcAlias = tool.getAlias(getSource());
if (srcAlias instanceof VirtualObjectNode) {
if (!(srcAlias instanceof VirtualArrayNode)) {
return;
}
VirtualArrayNode srcVirtual = (VirtualArrayNode) srcAlias;
if (destVirtual.componentType().getJavaKind() != srcVirtual.componentType().getJavaKind()) {
return;
}
if (!checkBounds(srcPosInt, len, srcVirtual)) {
return;
}
if (!checkEntryTypes(srcPosInt, len, srcVirtual, destVirtual.type().getComponentType(), tool)) {
return;
}
for (int i = 0; i < len; i++) {
tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i));
}
tool.delete();
DebugContext debug = getDebug();
if (debug.isLogEnabled()) {
debug.log("virtualized arraycopy(%s, %d, %s, %d, %d)", getSource(), srcPosInt, getDestination(), destPosInt, len);
}
} else {
ResolvedJavaType sourceType = StampTool.typeOrNull(srcAlias);
if (sourceType == null || !sourceType.isArray()) {
return;
}
ResolvedJavaType sourceComponentType = sourceType.getComponentType();
ResolvedJavaType destComponentType = destVirtual.type().getComponentType();
if (!sourceComponentType.equals(destComponentType)) {
return;
}
for (int i = 0; i < len; i++) {
LoadIndexedNode load = new LoadIndexedNode(graph().getAssumptions(), srcAlias, ConstantNode.forInt(i + srcPosInt, graph()), destComponentType.getJavaKind());
tool.addNode(load);
tool.setVirtualEntry(destVirtual, destPosInt + i, load);
}
tool.delete();
}
}
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualArrayNode 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);
int entryCount = virtual.entryCount();
AbstractNewObjectNode newObject;
try (DebugCloseable nsp = virtual.withNodeSourcePosition()) {
if (virtual instanceof VirtualInstanceNode) {
newObject = graph.add(createNewInstanceFromVirtual(virtual));
} else {
newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
}
}
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 entryKind = virtual.entryKind(i);
// Truffle requires some leniency in terms of what can be put where:
assert valueKind.getStackKind() == entryKind.getStackKind() || (valueKind == JavaKind.Long || valueKind == JavaKind.Double || (valueKind == JavaKind.Int && 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 = fieldInitializationBarrier(entryKind);
}
} else {
address = createOffsetAddress(graph, newObject, arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind));
barrierType = arrayInitializationBarrier(entryKind);
}
if (address != null) {
WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), 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);
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(i) == JavaKind.Object && allocValue.getStackKind() == JavaKind.Object;
AddressNode address;
BarrierType barrierType;
if (virtual instanceof VirtualInstanceNode) {
VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
address = createFieldAddress(graph, newObject, virtualInstance.field(i));
barrierType = BarrierType.IMPRECISE;
} else {
address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph));
barrierType = BarrierType.PRECISE;
}
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, allocations);
graph.removeFixed(commit);
for (AbstractNewObjectNode recursiveLowering : recursiveLowerings) {
recursiveLowering.lower(tool);
}
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualArrayNode in project graal by oracle.
the class GraphUtil method virtualizeArrayCopy.
/**
* Virtualize an array copy.
*
* @param tool the virtualization tool
* @param source the source array
* @param sourceLength the length of the source array
* @param newLength the length of the new array
* @param from the start index in the source array
* @param newComponentType the component type of the new array
* @param elementKind the kind of the new array elements
* @param graph the node graph
* @param virtualArrayProvider a functional provider that returns a new virtual array given the
* component type and length
*/
public static void virtualizeArrayCopy(VirtualizerTool tool, ValueNode source, ValueNode sourceLength, ValueNode newLength, ValueNode from, ResolvedJavaType newComponentType, JavaKind elementKind, StructuredGraph graph, BiFunction<ResolvedJavaType, Integer, VirtualArrayNode> virtualArrayProvider) {
ValueNode sourceAlias = tool.getAlias(source);
ValueNode replacedSourceLength = tool.getAlias(sourceLength);
ValueNode replacedNewLength = tool.getAlias(newLength);
ValueNode replacedFrom = tool.getAlias(from);
if (!replacedNewLength.isConstant() || !replacedFrom.isConstant() || !replacedSourceLength.isConstant()) {
return;
}
assert newComponentType != null : "An array copy can be virtualized only if the real type of the resulting array is known statically.";
int fromInt = replacedFrom.asJavaConstant().asInt();
int newLengthInt = replacedNewLength.asJavaConstant().asInt();
int sourceLengthInt = replacedSourceLength.asJavaConstant().asInt();
if (sourceAlias instanceof VirtualObjectNode) {
VirtualObjectNode sourceVirtual = (VirtualObjectNode) sourceAlias;
assert sourceLengthInt == sourceVirtual.entryCount();
}
if (fromInt < 0 || newLengthInt < 0 || fromInt > sourceLengthInt) {
/* Illegal values for either from index, the new length or the source length. */
return;
}
if (newLengthInt >= tool.getMaximumEntryCount()) {
/* The new array size is higher than maximum allowed size of virtualized objects. */
return;
}
ValueNode[] newEntryState = new ValueNode[newLengthInt];
int readLength = Math.min(newLengthInt, sourceLengthInt - fromInt);
if (sourceAlias instanceof VirtualObjectNode) {
/* The source array is virtualized, just copy over the values. */
VirtualObjectNode sourceVirtual = (VirtualObjectNode) sourceAlias;
for (int i = 0; i < readLength; i++) {
newEntryState[i] = tool.getEntry(sourceVirtual, fromInt + i);
}
} else {
/* The source array is not virtualized, emit index loads. */
for (int i = 0; i < readLength; i++) {
LoadIndexedNode load = new LoadIndexedNode(null, sourceAlias, ConstantNode.forInt(i + fromInt, graph), elementKind);
tool.addNode(load);
newEntryState[i] = load;
}
}
if (readLength < newLengthInt) {
/* Pad the copy with the default value of its elment kind. */
ValueNode defaultValue = ConstantNode.defaultForKind(elementKind, graph);
for (int i = readLength; i < newLengthInt; i++) {
newEntryState[i] = defaultValue;
}
}
/* Perform the replacement. */
VirtualArrayNode newVirtualArray = virtualArrayProvider.apply(newComponentType, newLengthInt);
tool.createVirtualObject(newVirtualArray, newEntryState, Collections.<MonitorIdNode>emptyList(), false);
tool.replaceWithVirtual(newVirtualArray);
}
use of org.graalvm.compiler.nodes.virtual.VirtualArrayNode in project graal by oracle.
the class LoadIndexedNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ValueNode alias = tool.getAlias(array());
if (alias instanceof VirtualObjectNode) {
VirtualArrayNode virtual = (VirtualArrayNode) alias;
ValueNode indexValue = tool.getAlias(index());
int idx = indexValue.isConstant() ? indexValue.asJavaConstant().asInt() : -1;
if (idx >= 0 && idx < virtual.entryCount()) {
ValueNode entry = tool.getEntry(virtual, idx);
if (stamp.isCompatible(entry.stamp(NodeView.DEFAULT))) {
tool.replaceWith(entry);
} else {
assert stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Int && (entry.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double || entry.getStackKind() == JavaKind.Illegal) : "Can only allow different stack kind two slot marker writes on one stot fields.";
}
}
}
}
Aggregations