# HG changeset patch # User Christian Humer # Date 1392900279 -3600 # Node ID aaba5b41c953cf8e8ca02ed3c15dc67eceef4e15 # Parent 83b20e343f73f0abe0d1a68ff6948ae389c1d7f2# Parent a1b71ebfdf5f65b521a249b5b2b9f89cd34b38ef Merge. diff -r 83b20e343f73 -r aaba5b41c953 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/ClassSubstitution.java --- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/ClassSubstitution.java Thu Feb 20 13:44:06 2014 +0100 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/ClassSubstitution.java Thu Feb 20 13:44:39 2014 +0100 @@ -61,6 +61,5 @@ * Determines if the substitutions in a class are globally enabled. Individual * MethodSubstitutions can also have guards and those override this guard. */ - Class defaultGuard() default SubstitutionGuard.class; } diff -r 83b20e343f73 -r aaba5b41c953 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Thu Feb 20 13:44:06 2014 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Thu Feb 20 13:44:39 2014 +0100 @@ -467,17 +467,11 @@ } if (newInput != null) { if (newInput.recordsUsages()) { - NodeChangedListener listener = graph.inputChangedListener; - if (listener != null) { - listener.nodeChanged(this); - } + maybeNotifyChanged(this); newInput.addUsage(this); } } else if (oldInput != null && oldInput.recordsUsages() && oldInput.usages().isEmpty()) { - NodeChangedListener listener = graph.usagesDroppedToZeroListener; - if (listener != null) { - listener.nodeChanged(oldInput); - } + maybeNotifyZeroInputs(oldInput); } } } @@ -531,10 +525,7 @@ boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other); assert assertTrue(result, "not found in inputs, usage: %s", usage); if (other != null) { - NodeChangedListener listener = graph.inputChangedListener; - if (listener != null) { - listener.nodeChanged(usage); - } + maybeNotifyChanged(usage); if (other.recordsUsages()) { other.addUsage(usage); } @@ -543,6 +534,22 @@ clearUsages(); } + private void maybeNotifyChanged(Node usage) { + assert graph == null || !graph.isFrozen(); + NodeChangedListener listener = graph.inputChangedListener; + if (listener != null) { + listener.nodeChanged(usage); + } + } + + private void maybeNotifyZeroInputs(Node oldInput) { + assert graph == null || !graph.isFrozen(); + NodeChangedListener listener = graph.usagesDroppedToZeroListener; + if (listener != null) { + listener.nodeChanged(oldInput); + } + } + public void replaceAtPredecessor(Node other) { assert checkReplaceWith(other); if (predecessor != null) { @@ -576,16 +583,12 @@ public void clearInputs() { assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); - assert graph == null || !graph.isFrozen(); for (Node input : inputs()) { if (input.recordsUsages()) { removeThisFromUsages(input); if (input.usages().isEmpty()) { - NodeChangedListener listener = graph.usagesDroppedToZeroListener; - if (listener != null) { - listener.nodeChanged(input); - } + maybeNotifyZeroInputs(input); } } } diff -r 83b20e343f73 -r aaba5b41c953 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java Thu Feb 20 13:44:06 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java Thu Feb 20 13:44:39 2014 +0100 @@ -96,7 +96,7 @@ if (superKlass.equal(0)) { return null; } else { - return piCast(superKlass.readObject(classMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class, true, true); + return piCastExactNonNull(superKlass.readObject(classMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class); } } } @@ -110,7 +110,7 @@ Word klass = loadWordFromObject(thisObj, klassOffset()); if (klass.notEqual(0)) { if (klassIsArray(klass)) { - return piCast(klass.readObject(arrayKlassComponentMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class, true, true); + return piCastExactNonNull(klass.readObject(arrayKlassComponentMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class); } } return null; diff -r 83b20e343f73 -r aaba5b41c953 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java Thu Feb 20 13:44:06 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java Thu Feb 20 13:44:39 2014 +0100 @@ -41,7 +41,7 @@ @MethodSubstitution(isStatic = false, forced = true) public static Class getClass(final Object thisObj) { Word hub = loadHub(thisObj); - return piCast(hub.readObject(Word.signed(classMirrorOffset()), LocationIdentity.FINAL_LOCATION), Class.class, true, true); + return piCastExactNonNull(hub.readObject(Word.signed(classMirrorOffset()), LocationIdentity.FINAL_LOCATION), Class.class); } @MethodSubstitution(isStatic = false) diff -r 83b20e343f73 -r aaba5b41c953 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Feb 20 13:44:06 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Feb 20 13:44:39 2014 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +//JaCoCo Exclude + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -102,9 +104,17 @@ @NodeIntrinsic public static native T piCast(Object object, @ConstantNodeParameter Stamp stamp, GuardingNode anchor); + public static T piCastExactNonNull(Object object, @ConstantNodeParameter Class toType) { + return piCast(object, toType, true, true); + } + + public static T piCast(Object object, @ConstantNodeParameter Class toType) { + return piCast(object, toType, false, false); + } + @SuppressWarnings("unused") @NodeIntrinsic - public static T piCast(Object object, @ConstantNodeParameter Class toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) { + private static T piCast(Object object, @ConstantNodeParameter Class toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) { return toType.cast(object); } } diff -r 83b20e343f73 -r aaba5b41c953 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Thu Feb 20 13:44:06 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Thu Feb 20 13:44:39 2014 +0100 @@ -64,12 +64,12 @@ @MethodSubstitution private static Node getNode(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class); } @MethodSubstitution private static NodeList getNodeList(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), NodeList.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), NodeList.class); } @MethodSubstitution diff -r 83b20e343f73 -r aaba5b41c953 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Thu Feb 20 13:44:06 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Thu Feb 20 13:44:39 2014 +0100 @@ -133,9 +133,10 @@ } StructuredGraph graph = graphs.get(substitute); if (graph == null) { - graphs.putIfAbsent(substitute, makeGraph(substitute, original, substitute, inliningPolicy(substitute), FrameStateProcessing.None)); + graph = makeGraph(substitute, original, substitute, inliningPolicy(substitute), FrameStateProcessing.None); + graph.freeze(); + graphs.putIfAbsent(substitute, graph); graph = graphs.get(substitute); - graph.freeze(); } assert graph.isFrozen(); return graph; diff -r 83b20e343f73 -r aaba5b41c953 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java Thu Feb 20 13:44:06 2014 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java Thu Feb 20 13:44:39 2014 +0100 @@ -24,6 +24,8 @@ package com.sun.hotspot.igv.data; import java.util.Comparator; +import java.util.WeakHashMap; +import java.lang.ref.WeakReference; /** * @@ -32,7 +34,7 @@ public class InputEdge { public enum State { - + IMMUTABLE, SAME, NEW, DELETED @@ -61,12 +63,12 @@ } }; - private char toIndex; - private char fromIndex; - private int from; - private int to; + private final char toIndex; + private final char fromIndex; + private final int from; + private final int to; + private final String label; private State state; - private String label; public InputEdge(char toIndex, int from, int to) { this((char) 0, toIndex, from, to, null); @@ -85,11 +87,38 @@ this.label = label; } + static WeakHashMap> immutableCache = new WeakHashMap<>(); + + public static synchronized InputEdge createImmutable(char fromIndex, char toIndex, int from, int to, String label) { + InputEdge edge = new InputEdge(fromIndex, toIndex, from, to, label, State.IMMUTABLE); + WeakReference result = immutableCache.get(edge); + if (result != null) { + InputEdge edge2 = result.get(); + if (edge2 != null) { + return edge2; + } + } + immutableCache.put(edge, new WeakReference<>(edge)); + return edge; + } + + public InputEdge(char fromIndex, char toIndex, int from, int to, String label, State state) { + this.toIndex = toIndex; + this.fromIndex = fromIndex; + this.from = from; + this.to = to; + this.state = state; + this.label = label; + } + public State getState() { return state; } public void setState(State x) { + if (state == State.IMMUTABLE) { + throw new InternalError("Can't change immutable instances"); + } this.state = x; } @@ -123,7 +152,12 @@ return false; } InputEdge conn2 = (InputEdge) o; - return conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to; + boolean result = conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to; + if (result && (state == State.IMMUTABLE || conn2.state == State.IMMUTABLE)) { + // Immutable instances must be exactly the same + return conn2.label == label && conn2.state == state; + } + return result; } @Override diff -r 83b20e343f73 -r aaba5b41c953 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java Thu Feb 20 13:44:06 2014 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java Thu Feb 20 13:44:39 2014 +0100 @@ -32,19 +32,19 @@ public class InputGraph extends Properties.Entity implements FolderElement { private Map nodes; - private Set edges; + private List edges; private Folder parent; private Group parentGroup; private Map blocks; - private Set blockEdges; + private List blockEdges; private Map nodeToBlock; public InputGraph(String name) { setName(name); nodes = new LinkedHashMap<>(); - edges = new LinkedHashSet<>(); + edges = new ArrayList<>(); blocks = new LinkedHashMap<>(); - blockEdges = new LinkedHashSet<>(); + blockEdges = new ArrayList<>(); nodeToBlock = new LinkedHashMap<>(); } @@ -234,7 +234,7 @@ } public Collection getEdges() { - return Collections.unmodifiableSet(edges); + return Collections.unmodifiableList(edges); } public void removeEdge(InputEdge c) { @@ -283,7 +283,7 @@ } public Collection getBlockEdges() { - return Collections.unmodifiableSet(blockEdges); + return Collections.unmodifiableList(blockEdges); } @Override diff -r 83b20e343f73 -r aaba5b41c953 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Thu Feb 20 13:44:06 2014 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Thu Feb 20 13:44:39 2014 +0100 @@ -320,6 +320,9 @@ } public void setProperty(String name, String value) { + setPropertyInternal(name.intern(), value.intern()); + } + private void setPropertyInternal(String name, String value) { for (int i = 0; i < map.length; i += 2) { if (map[i] != null && map[i].equals(name)) { @@ -353,7 +356,8 @@ public void add(Properties properties) { for (Property p : properties) { - setProperty(p.getName(), p.getValue()); + // Already interned + setPropertyInternal(p.getName(), p.getValue()); } } diff -r 83b20e343f73 -r aaba5b41c953 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Thu Feb 20 13:44:06 2014 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Thu Feb 20 13:44:39 2014 +0100 @@ -327,7 +327,7 @@ char[] chars = new char[len]; buffer.asCharBuffer().get(chars); buffer.position(buffer.position() + len * 2); - return new String(chars); + return new String(chars).intern(); } private byte[] readBytes() throws IOException { @@ -355,7 +355,7 @@ } } sb.append(']'); - return sb.toString(); + return sb.toString().intern(); } private String readDoublesToString() throws IOException { @@ -372,7 +372,7 @@ } } sb.append(']'); - return sb.toString(); + return sb.toString().intern(); } private String readPoolObjectsToString() throws IOException { @@ -388,7 +388,7 @@ } } sb.append(']'); - return sb.toString(); + return sb.toString().intern(); } private T readPoolObject(Class klass) throws IOException { @@ -780,7 +780,7 @@ for (Edge e : edges) { char fromIndex = e.input ? 1 : e.num; char toIndex = e.input ? e.num : 0; - graph.addEdge(new InputEdge(fromIndex, toIndex, e.from, e.to, e.label)); + graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label)); } } @@ -837,7 +837,7 @@ m.appendReplacement(sb, result); } m.appendTail(sb); - return sb.toString(); + return sb.toString().intern(); } private static class Edge { @@ -852,7 +852,7 @@ public Edge(int from, int to, char num, String label, boolean input) { this.from = from; this.to = to; - this.label = label; + this.label = label != null ? label.intern() : label; this.num = num; this.input = input; }