src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Fri Jul 7 09:31:27 2017
--- new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Fri Jul 7 09:31:27 2017
*** 23,40 ****
--- 23,42 ----
package org.graalvm.compiler.nodes.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+ import java.util.function.BiFunction;
import org.graalvm.compiler.bytecode.Bytecode;
import org.graalvm.compiler.code.SourceStackTraceBailoutException;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.ObjectStamp;
! import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeBitMap;
import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.graph.NodeStack;
*** 42,51 ****
--- 44,54 ----
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.graph.spi.SimplifierTool;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractEndNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
+ import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.ControlSplitNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.GuardNode;
*** 56,70 ****
--- 59,78 ----
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.ProxyNode;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
+ import org.graalvm.compiler.nodes.java.LoadIndexedNode;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+ import org.graalvm.compiler.nodes.java.MonitorIdNode;
import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
import org.graalvm.compiler.nodes.spi.LimitedValueProxy;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.nodes.spi.ValueProxy;
+ import org.graalvm.compiler.nodes.spi.VirtualizerTool;
+ import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
+ import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
*** 75,86 ****
--- 83,96 ----
import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.BytecodePosition;
import jdk.vm.ci.meta.Assumptions;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
+ import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+ import jdk.vm.ci.meta.ResolvedJavaType;
public class GraphUtil {
public static class Options {
@Option(help = "Verify that there are no new unused nodes when performing killCFG", type = OptionType.Debug)//
*** 96,106 ****
--- 106,117 ----
markFixedNodes(node, markedNodes, unmarkedMerges);
fixSurvivingAffectedMerges(markedNodes, unmarkedMerges);
! Debug.dump(Debug.DETAILED_LEVEL, node.graph(), "After fixing merges (killCFG %s)", node);
! DebugContext debug = node.getDebug();
+ debug.dump(DebugContext.DETAILED_LEVEL, node.graph(), "After fixing merges (killCFG %s)", node);
// Mark non-fixed nodes
markUsages(markedNodes);
// Detach marked nodes from non-marked nodes
*** 110,120 ****
--- 121,131 ----
marked.replaceFirstInput(input, null);
tryKillUnused(input);
}
}
}
! Debug.dump(Debug.VERY_DETAILED_LEVEL, node.graph(), "After disconnecting non-marked inputs (killCFG %s)", node);
! debug.dump(DebugContext.VERY_DETAILED_LEVEL, node.graph(), "After disconnecting non-marked inputs (killCFG %s)", node);
// Kill marked nodes
for (Node marked : markedNodes) {
if (marked.isAlive()) {
marked.markDeleted();
}
*** 216,226 ****
--- 227,238 ----
}
}
@SuppressWarnings("try")
public static void killCFG(FixedNode node) {
try (Debug.Scope scope = Debug.scope("KillCFG", node)) {
+ DebugContext debug = node.getDebug();
+ try (DebugContext.Scope scope = debug.scope("KillCFG", node)) {
EconomicSet<Node> unusedNodes = null;
EconomicSet<Node> unsafeNodes = null;
Graph.NodeEventScope nodeEventScope = null;
OptionValues options = node.getOptions();
if (Graph.Options.VerifyGraalGraphEdges.getValue(options)) {
*** 235,247 ****
--- 247,259 ----
collectedUnusedNodes.add(n);
}
}
});
}
! Debug.dump(Debug.VERY_DETAILED_LEVEL, node.graph(), "Before killCFG %s", node);
! debug.dump(DebugContext.VERY_DETAILED_LEVEL, node.graph(), "Before killCFG %s", node);
killCFGInner(node);
! Debug.dump(Debug.VERY_DETAILED_LEVEL, node.graph(), "After killCFG %s", node);
! debug.dump(DebugContext.VERY_DETAILED_LEVEL, node.graph(), "After killCFG %s", node);
if (Graph.Options.VerifyGraalGraphEdges.getValue(options)) {
EconomicSet<Node> newUnsafeNodes = collectUnsafeNodes(node.graph());
newUnsafeNodes.removeAll(unsafeNodes);
assert newUnsafeNodes.isEmpty() : "New unsafe nodes: " + newUnsafeNodes;
}
*** 255,265 ****
--- 267,277 ----
}
}
assert unusedNodes.isEmpty() : "New unused nodes: " + unusedNodes;
}
} catch (Throwable t) {
! throw Debug.handle(t);
! throw debug.handle(t);
}
}
/**
* Collects all node in the graph which have non-optional inputs that are null.
*** 933,938 ****
--- 945,1025 ----
tryKillUnused(constant);
return result;
}
return null;
}
+
+ /**
+ * 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);
+ }
}
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File