changeset 23:82fe7737b8b1

Update to new binary protocol: update-refs and connection matrix.
author shade
date Fri, 14 Apr 2017 19:51:43 +0200
parents 237d9a00203a
children b3bcfd491862
files src/main/java/org/openjdk/shenandoah/DataProvider.java src/main/java/org/openjdk/shenandoah/RegionStat.java src/main/java/org/openjdk/shenandoah/ShenandoahVisualizer.java src/main/java/org/openjdk/shenandoah/Snapshot.java src/main/java/org/openjdk/shenandoah/SnapshotView.java
diffstat 5 files changed, 76 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/openjdk/shenandoah/DataProvider.java	Tue Feb 07 14:37:51 2017 +0100
+++ b/src/main/java/org/openjdk/shenandoah/DataProvider.java	Fri Apr 14 19:51:43 2017 +0200
@@ -10,6 +10,7 @@
     private final int maxRegions;
     private final long maxSize;
     private final LongMonitor[] data;
+    private final StringMonitor[] matrix;
     private final LongMonitor timestamp;
     private final LongMonitor status;
 
@@ -24,6 +25,7 @@
         status = (LongMonitor) vm.findByName("sun.gc.shenandoah.regions.status");
 
         data = new LongMonitor[maxRegions];
+        matrix = new StringMonitor[maxRegions];
         for (int i = 0; i < maxRegions; i++) {
             LongMonitor mon = (LongMonitor) vm.findByName("sun.gc.shenandoah.regions.region." + i + ".data");
             if (mon != null) {
@@ -32,19 +34,26 @@
                 throw new IllegalStateException("Insufficient shared memory for all region counters. " +
                         "Try -XX:PerfDataMemorySize=512K or higher when running the monitored program.");
             }
+
+            StringMonitor mtrx = (StringMonitor) vm.findByName("sun.gc.shenandoah.regions.region." + i + ".matrix");
+            if (mtrx != null) {
+                matrix[i] = mtrx;
+            }
         }
     }
 
     public Snapshot snapshot() {
         List<RegionStat> stats = new ArrayList<>();
-        for (LongMonitor m : data) {
-            stats.add(new RegionStat(maxSize, m.longValue()));
+        for (int c = 0; c < maxRegions; c++) {
+            StringMonitor mtrx = matrix[c];
+            stats.add(new RegionStat(maxSize, data[c].longValue(), (mtrx == null ? "" : mtrx.stringValue())));
         }
-        boolean isMarking = (status.longValue() & 0x1) > 0;
+        boolean isMarking    = (status.longValue() & 0x1) > 0;
         boolean isEvacuating = (status.longValue() & 0x2) > 0;
+        boolean isUpdateRefs = (status.longValue() & 0x4) > 0;
 
         long time = timestamp.longValue();
-        return new Snapshot(time, maxSize, stats, isMarking, isEvacuating);
+        return new Snapshot(time, maxSize, stats, isMarking, isEvacuating, isUpdateRefs);
     }
 
 }
--- a/src/main/java/org/openjdk/shenandoah/RegionStat.java	Tue Feb 07 14:37:51 2017 +0100
+++ b/src/main/java/org/openjdk/shenandoah/RegionStat.java	Fri Apr 14 19:51:43 2017 +0200
@@ -1,6 +1,7 @@
 package org.openjdk.shenandoah;
 
 import java.awt.*;
+import java.util.BitSet;
 import java.util.EnumSet;
 
 import static org.openjdk.shenandoah.Colors.*;
@@ -15,16 +16,18 @@
     private static final int FLAGS_SHIFT = 58;
 
     private final EnumSet<RegionFlag> flags;
+    private final BitSet incoming;
     private final double liveLvl;
     private final double usedLvl;
 
     public RegionStat(double usedLvl, double liveLvl, EnumSet<RegionFlag> flags) {
+        this.incoming = new BitSet();
         this.usedLvl = usedLvl;
         this.liveLvl = liveLvl;
         this.flags = flags;
     }
 
-    public RegionStat(long maxSize, long data) {
+    public RegionStat(long maxSize, long data, String matrix) {
         long used = (data >>> USED_SHIFT) & USED_MASK;
         usedLvl = Math.min(1D, 1D * used / maxSize);
 
@@ -40,6 +43,18 @@
         if ((stat & 4)  > 0) flags.add(RegionFlag.HUMONGOUS);
         if ((stat & 8)  > 0) flags.add(RegionFlag.RECENTLY_ALLOCATED);
         if ((stat & 16) > 0) flags.add(RegionFlag.PINNED);
+
+        this.incoming = new BitSet();
+        int idx = 0;
+        for (char c : matrix.toCharArray()) {
+            c = (char) (c - 32);
+            incoming.set(idx++, (c & (1 << 0)) > 0);
+            incoming.set(idx++, (c & (1 << 1)) > 0);
+            incoming.set(idx++, (c & (1 << 2)) > 0);
+            incoming.set(idx++, (c & (1 << 3)) > 0);
+            incoming.set(idx++, (c & (1 << 4)) > 0);
+            incoming.set(idx++, (c & (1 << 5)) > 0);
+        }
     }
 
     public void render(Graphics g, int x, int y, int width, int height) {
@@ -100,7 +115,8 @@
 
         if (Double.compare(that.liveLvl, liveLvl) != 0) return false;
         if (Double.compare(that.usedLvl, usedLvl) != 0) return false;
-        return flags.equals(that.flags);
+        if (!flags.equals(that.flags)) return false;
+        return incoming.equals(that.incoming);
     }
 
     @Override
@@ -108,6 +124,7 @@
         int result;
         long temp;
         result = flags.hashCode();
+        result = 31 * result + incoming.hashCode();
         temp = Double.doubleToLongBits(liveLvl);
         result = 31 * result + (int) (temp ^ (temp >>> 32));
         temp = Double.doubleToLongBits(usedLvl);
@@ -127,4 +144,7 @@
         return flags;
     }
 
+    public BitSet incoming() {
+        return incoming;
+    }
 }
--- a/src/main/java/org/openjdk/shenandoah/ShenandoahVisualizer.java	Tue Feb 07 14:37:51 2017 +0100
+++ b/src/main/java/org/openjdk/shenandoah/ShenandoahVisualizer.java	Fri Apr 14 19:51:43 2017 +0200
@@ -145,7 +145,7 @@
 
         ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
         ScheduledFuture<?> f = service.scheduleAtFixedRate(render,
-                0, 10, TimeUnit.MILLISECONDS);
+                0, 100, TimeUnit.MILLISECONDS);
 
         frame.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
@@ -212,6 +212,11 @@
                     g.drawRect(x, 0, 1, graphHeight);
                 }
 
+                if (s.isUpdatingRefs()) {
+                    g.setColor(new Color(0, 100, 100));
+                    g.drawRect(x, 0, 1, graphHeight);
+                }
+
                 g.setColor(Colors.USED);
                 g.drawRect(x, (int) Math.round(graphHeight - s.used() * stepY), 1, 1);
                 g.setColor(Colors.USED_ALLOC);
@@ -281,6 +286,24 @@
                 RegionStat s = snapshot.get(i);
                 s.render(g, rectx, recty, sqSize, sqSize);
             }
+
+            Color BASE = new Color(0, 0, 0, 20);
+
+            for (int f = 0; f < snapshot.regionCount(); f++) {
+                RegionStat s = snapshot.get(f);
+                BitSet bs = s.incoming();
+                for (int t = 0; t < snapshot.regionCount(); t++) {
+                    if (bs.get(t)) {
+                        int f_rectx = (int) ((f % cols + 0.5) * sqSize);
+                        int f_recty = (int) ((f / cols + 0.5) * sqSize);
+                        int t_rectx = (int) ((t % cols + 0.5) * sqSize);
+                        int t_recty = (int) ((t / cols + 0.5) * sqSize);
+
+                        g.setColor(BASE);
+                        g.drawLine(f_rectx, f_recty, t_rectx, t_recty);
+                    }
+                }
+            }
         }
 
         public synchronized void renderStats(Graphics g) {
@@ -291,6 +314,9 @@
             if (snapshot.isEvacuating()) {
                 status += " (evacuating)";
             }
+            if (snapshot.isUpdateRefs()) {
+                status += " (updating refs)";
+            }
             if (status.isEmpty()) {
                 status = " (idle)";
             }
--- a/src/main/java/org/openjdk/shenandoah/Snapshot.java	Tue Feb 07 14:37:51 2017 +0100
+++ b/src/main/java/org/openjdk/shenandoah/Snapshot.java	Fri Apr 14 19:51:43 2017 +0200
@@ -9,13 +9,15 @@
     private final List<RegionStat> stats;
     private final boolean isMarking;
     private final boolean isEvacuating;
+    private final boolean isUpdateRefs;
 
-    public Snapshot(long time, long regionSize, List<RegionStat> stats, boolean isMarking, boolean isEvacuating) {
+    public Snapshot(long time, long regionSize, List<RegionStat> stats, boolean isMarking, boolean isEvacuating, boolean isUpdateRefs) {
         this.time = time;
         this.regionSize = regionSize;
         this.stats = stats;
         this.isMarking = isMarking;
         this.isEvacuating = isEvacuating;
+        this.isUpdateRefs = isUpdateRefs;
     }
 
     public boolean isMarking() {
@@ -26,6 +28,10 @@
         return isEvacuating;
     }
 
+    public boolean isUpdateRefs() {
+        return isUpdateRefs;
+    }
+
     public RegionStat get(int i) {
         return stats.get(i);
     }
@@ -44,6 +50,7 @@
         if (time != snapshot.time) return false;
         if (isMarking != snapshot.isMarking) return false;
         if (isEvacuating != snapshot.isEvacuating) return false;
+        if (isUpdateRefs != snapshot.isUpdateRefs) return false;
         return stats != null ? stats.equals(snapshot.stats) : snapshot.stats == null;
     }
 
--- a/src/main/java/org/openjdk/shenandoah/SnapshotView.java	Tue Feb 07 14:37:51 2017 +0100
+++ b/src/main/java/org/openjdk/shenandoah/SnapshotView.java	Fri Apr 14 19:51:43 2017 +0200
@@ -7,6 +7,7 @@
     private final long time;
     private final boolean isMarking;
     private final boolean isEvacuating;
+    private final boolean isUpdatingRefs;
     private final long total;
     private final long used;
     private final long live;
@@ -18,6 +19,7 @@
         this.time = s.time();
         this.isEvacuating = s.isEvacuating();
         this.isMarking = s.isMarking();
+        this.isUpdatingRefs = s.isUpdateRefs();
         total = total();
         used = s.used();
         live = s.live();
@@ -34,6 +36,10 @@
         return isEvacuating;
     }
 
+    public boolean isUpdatingRefs() {
+        return isUpdatingRefs;
+    }
+
     public long time() {
         return time;
     }