changeset 13989:aaba5b41c953

Merge.
author Christian Humer <christian.humer@gmail.com>
date Thu, 20 Feb 2014 13:44:39 +0100
parents 83b20e343f73 (current diff) a1b71ebfdf5f (diff)
children fcc40370f78d
files
diffstat 11 files changed, 98 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- 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<? extends SubstitutionGuard> defaultGuard() default SubstitutionGuard.class;
 }
--- 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);
                 }
             }
         }
--- 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;
--- 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)
--- 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> T piCast(Object object, @ConstantNodeParameter Stamp stamp, GuardingNode anchor);
 
+    public static <T> T piCastExactNonNull(Object object, @ConstantNodeParameter Class<T> toType) {
+        return piCast(object, toType, true, true);
+    }
+
+    public static <T> T piCast(Object object, @ConstantNodeParameter Class<T> toType) {
+        return piCast(object, toType, false, false);
+    }
+
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static <T> T piCast(Object object, @ConstantNodeParameter Class<T> toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) {
+    private static <T> T piCast(Object object, @ConstantNodeParameter Class<T> toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) {
         return toType.cast(object);
     }
 }
--- 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
--- 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;
--- 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<InputEdge, WeakReference<InputEdge>> 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<InputEdge> 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
--- 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<Integer, InputNode> nodes;
-    private Set<InputEdge> edges;
+    private List<InputEdge> edges;
     private Folder parent;
     private Group parentGroup;
     private Map<String, InputBlock> blocks;
-    private Set<InputBlockEdge> blockEdges;
+    private List<InputBlockEdge> blockEdges;
     private Map<Integer, InputBlock> 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<InputEdge> getEdges() {
-        return Collections.unmodifiableSet(edges);
+        return Collections.unmodifiableList(edges);
     }
 
     public void removeEdge(InputEdge c) {
@@ -283,7 +283,7 @@
     }
 
     public Collection<InputBlockEdge> getBlockEdges() {
-        return Collections.unmodifiableSet(blockEdges);
+        return Collections.unmodifiableList(blockEdges);
     }
 
     @Override
--- 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());
         }
     }
 
--- 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> T readPoolObject(Class<T> 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;
         }