# HG changeset patch # User Tom Rodriguez # Date 1392850249 28800 # Node ID a1b71ebfdf5f65b521a249b5b2b9f89cd34b38ef # Parent 68ae6fae9d2e4c01d6ec9dbd81bc8b1eb4be6e71 reduce IGV memory usage, intern strings, eliminate some LinkedHashMaps, cache InputEdges diff -r 68ae6fae9d2e -r a1b71ebfdf5f 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 Wed Feb 19 14:41:51 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java Wed Feb 19 14:50:49 2014 -0800 @@ -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 68ae6fae9d2e -r a1b71ebfdf5f 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 Wed Feb 19 14:41:51 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java Wed Feb 19 14:50:49 2014 -0800 @@ -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 68ae6fae9d2e -r a1b71ebfdf5f 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 Wed Feb 19 14:41:51 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Wed Feb 19 14:50:49 2014 -0800 @@ -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 68ae6fae9d2e -r a1b71ebfdf5f 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 Wed Feb 19 14:41:51 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Wed Feb 19 14:50:49 2014 -0800 @@ -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; }