changeset 8:8dc27cf89d58

Snapshot rendering.
author shade
date Wed, 14 Dec 2016 22:05:39 +0100
parents b846cd430ac5
children ea127a38d603
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
diffstat 4 files changed, 141 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/openjdk/shenandoah/DataProvider.java	Wed Dec 14 20:14:55 2016 +0100
+++ b/src/main/java/org/openjdk/shenandoah/DataProvider.java	Wed Dec 14 22:05:39 2016 +0100
@@ -2,6 +2,9 @@
 
 import sun.jvmstat.monitor.*;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class DataProvider {
 
     private final int maxRegions;
@@ -30,15 +33,15 @@
         }
     }
 
-    public int maxRegions() {
-        return maxRegions;
+    public Snapshot snapshot() {
+        List<RegionStat> stats = new ArrayList<>();
+        for (LongMonitor m : data) {
+            stats.add(new RegionStat(maxSize, m.longValue()));
+        }
+        boolean isMarking = (status.longValue() & 0x1) > 0;
+        boolean isEvacuating = (status.longValue() & 0x2) > 0;
+
+        return new Snapshot(System.currentTimeMillis(), stats, isMarking, isEvacuating);
     }
 
-    public long status() {
-        return status.longValue();
-    }
-
-    public RegionStat regionStat(int i) {
-        return new RegionStat(maxSize, data[i].longValue());
-    }
 }
--- a/src/main/java/org/openjdk/shenandoah/RegionStat.java	Wed Dec 14 20:14:55 2016 +0100
+++ b/src/main/java/org/openjdk/shenandoah/RegionStat.java	Wed Dec 14 22:05:39 2016 +0100
@@ -68,5 +68,31 @@
         g.drawRect(x, y, width, height);
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
 
+        RegionStat that = (RegionStat) o;
+
+        if (unused != that.unused) return false;
+        if (humongous != that.humongous) return false;
+        if (inCset != that.inCset) return false;
+        if (Double.compare(that.liveLvl, liveLvl) != 0) return false;
+        return Double.compare(that.usedLvl, usedLvl) == 0;
+    }
+
+    @Override
+    public int hashCode() {
+        int result;
+        long temp;
+        result = (unused ? 1 : 0);
+        result = 31 * result + (humongous ? 1 : 0);
+        result = 31 * result + (inCset ? 1 : 0);
+        temp = Double.doubleToLongBits(liveLvl);
+        result = 31 * result + (int) (temp ^ (temp >>> 32));
+        temp = Double.doubleToLongBits(usedLvl);
+        result = 31 * result + (int) (temp ^ (temp >>> 32));
+        return result;
+    }
 }
--- a/src/main/java/org/openjdk/shenandoah/ShenandoahVisualizer.java	Wed Dec 14 20:14:55 2016 +0100
+++ b/src/main/java/org/openjdk/shenandoah/ShenandoahVisualizer.java	Wed Dec 14 22:05:39 2016 +0100
@@ -50,38 +50,6 @@
         }
     }
 
-    static class StatusPanel extends JPanel {
-        private final DataProvider data;
-
-        public StatusPanel(DataProvider data) {
-            this.data = data;
-        }
-
-        public void paint(Graphics g) {
-            boolean isMarking = (data.status() & 0x1) > 0;
-            boolean isEvacuating = (data.status() & 0x2) > 0;
-
-            g.setColor(Color.BLACK);
-            g.drawString("marking:", 0, 15);
-            if (isMarking) {
-                g.setColor(Color.RED);
-            } else {
-                g.setColor(Color.GREEN);
-            }
-            g.fillRect(60, 0, 40, 20);
-
-            g.setColor(Color.BLACK);
-            g.drawString("evacuating:", 120, 15);
-            if (isEvacuating) {
-                g.setColor(Color.RED);
-            } else {
-                g.setColor(Color.GREEN);
-            }
-            g.fillRect(220, 0, 40, 20);
-
-        }
-    }
-
     static class VisPanelListener extends ComponentAdapter {
         public void componentResized(ComponentEvent ev) {
             width = ev.getComponent().getWidth();
@@ -97,22 +65,21 @@
 
         DataProvider data = new DataProvider(args[0]);
 
-
         VisPanel p = new VisPanel();
         p.addComponentListener(new VisPanelListener());
 
-        StatusPanel statusPanel = new StatusPanel(data);
-        statusPanel.setPreferredSize(new Dimension(220, 20));
-
         JFrame frame = new JFrame();
         frame.getContentPane().add(p, BorderLayout.CENTER);
-        frame.getContentPane().add(statusPanel, BorderLayout.SOUTH);
         frame.setSize(INITIAL_WIDTH, INITIAL_HEIGHT);
         frame.setVisible(true);
 
         ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
         service.scheduleAtFixedRate(() -> {
-            render(data);
+            Snapshot cur = data.snapshot();
+            if (!cur.equals(lastSnapshot)) {
+                render(cur);
+                lastSnapshot = cur;
+            }
             frame.repaint();
         }, 0, 100, TimeUnit.MILLISECONDS);
 
@@ -124,20 +91,51 @@
         });
     }
 
-    public static void render(DataProvider data) {
-        int cols = (int) Math.floor(Math.sqrt(data.maxRegions()));
-        int rows = (int) Math.floor(data.maxRegions() / cols);
+    static volatile Snapshot lastSnapshot;
+
+    public static void render(Snapshot snapshot) {
+        int cols = (int) Math.floor(Math.sqrt(snapshot.regionCount()));
+        int rows = (int) Math.floor(snapshot.regionCount() / cols);
 
         BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 
-        int rectWidth = img.getWidth() / cols;
-        int rectHeight = img.getHeight() / rows;
         Graphics g = img.getGraphics();
-        for (int i = 0; i < data.maxRegions(); i++) {
-            int rectx = (i % cols) * rectWidth;
-            int recty = (i / rows) * rectHeight;
+
+        final int PAD = 20;
+        final int LINE = 30;
+        final int PAD_TOP = 100;
+
+        // Draw white background
+        g.setColor(Color.WHITE);
+        g.fillRect(0, 0, width, height);
+
+        // Draw time
+        g.setColor(Color.BLACK);
+        g.drawString(String.valueOf(snapshot.time()), PAD, PAD);
 
-            RegionStat s = data.regionStat(i);
+        // Draw status
+        g.setColor(Color.BLACK);
+        String status = "";
+        if (snapshot.isMarking()) {
+            status += " (marking)";
+        }
+        if (snapshot.isEvacuating()) {
+            status += " (evacuating)";
+        }
+        if (status.isEmpty()) {
+            status = " (idle)";
+        }
+        g.drawString("Status: " + status, PAD, PAD + 1 * LINE);
+
+        // Draw region field
+        int rectWidth = (img.getWidth() - 2*PAD) / cols;
+        int rectHeight = (img.getHeight() - (PAD + PAD_TOP)) / rows;
+
+        for (int i = 0; i < snapshot.regionCount(); i++) {
+            int rectx = PAD + (i % cols) * rectWidth;
+            int recty = PAD + PAD_TOP + (i / rows) * rectHeight;
+
+            RegionStat s = snapshot.get(i);
             s.render(g, rectx, recty, rectWidth, rectHeight);
         }
         g.dispose();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/openjdk/shenandoah/Snapshot.java	Wed Dec 14 22:05:39 2016 +0100
@@ -0,0 +1,58 @@
+package org.openjdk.shenandoah;
+
+import java.util.List;
+
+public class Snapshot {
+
+    private final long time;
+    private final List<RegionStat> stats;
+    private final boolean isMarking;
+    private final boolean isEvacuating;
+
+    public Snapshot(long time, List<RegionStat> stats, boolean isMarking, boolean isEvacuating) {
+        this.time = time;
+        this.stats = stats;
+        this.isMarking = isMarking;
+        this.isEvacuating = isEvacuating;
+    }
+
+    public boolean isMarking() {
+        return isMarking;
+    }
+
+    public boolean isEvacuating() {
+        return isEvacuating;
+    }
+
+    public RegionStat get(int i) {
+        return stats.get(i);
+    }
+
+    public long time() {
+        return time;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Snapshot snapshot = (Snapshot) o;
+
+        if (isMarking != snapshot.isMarking) return false;
+        if (isEvacuating != snapshot.isEvacuating) return false;
+        return stats != null ? stats.equals(snapshot.stats) : snapshot.stats == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = stats.hashCode();
+        result = 31 * result + (isMarking ? 1 : 0);
+        result = 31 * result + (isEvacuating ? 1 : 0);
+        return result;
+    }
+
+    public int regionCount() {
+        return stats.size();
+    }
+}