# HG changeset patch # User shade # Date 1492192303 -7200 # Node ID 82fe7737b8b17e270fc16867844274ee8fd296b1 # Parent 237d9a00203a91a83fa1fbf224d42dbca2172049 Update to new binary protocol: update-refs and connection matrix. diff -r 237d9a00203a -r 82fe7737b8b1 src/main/java/org/openjdk/shenandoah/DataProvider.java --- 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 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); } } diff -r 237d9a00203a -r 82fe7737b8b1 src/main/java/org/openjdk/shenandoah/RegionStat.java --- 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 flags; + private final BitSet incoming; private final double liveLvl; private final double usedLvl; public RegionStat(double usedLvl, double liveLvl, EnumSet 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; + } } diff -r 237d9a00203a -r 82fe7737b8b1 src/main/java/org/openjdk/shenandoah/ShenandoahVisualizer.java --- 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)"; } diff -r 237d9a00203a -r 82fe7737b8b1 src/main/java/org/openjdk/shenandoah/Snapshot.java --- 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 stats; private final boolean isMarking; private final boolean isEvacuating; + private final boolean isUpdateRefs; - public Snapshot(long time, long regionSize, List stats, boolean isMarking, boolean isEvacuating) { + public Snapshot(long time, long regionSize, List 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; } diff -r 237d9a00203a -r 82fe7737b8b1 src/main/java/org/openjdk/shenandoah/SnapshotView.java --- 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; }