Bug 1633625 - Convert Graph and subclasses into JS classes r=jonco
authorSteve Fink <sfink@mozilla.com>
Tue, 19 May 2020 21:54:41 +0000
changeset 530903 51e3676256c70439959bb90afcba5f2f6ec5eb85
parent 530902 d7e1fb886446b09c104098c478aa5b408bb3653f
child 530904 e04b67a3ac24dbcff7958e5f86f5b3a4f6959fb7
push id37434
push userabutkovits@mozilla.com
push dateWed, 20 May 2020 10:05:10 +0000
treeherdermozilla-central@005ef1c25992 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1633625
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1633625 - Convert Graph and subclasses into JS classes r=jonco Differential Revision: https://phabricator.services.mozilla.com/D74153
js/src/devtools/gc-ubench/ui.js
--- a/js/src/devtools/gc-ubench/ui.js
+++ b/js/src/devtools/gc-ubench/ui.js
@@ -42,332 +42,321 @@ function parse_units(v) {
     return units * 1e6;
   }
   if (lastChar == "g") {
     return units * 1e9;
   }
   return NaN;
 }
 
-function Graph(ctx) {
-  this.ctx = ctx;
+class Graph {
+  constructor(ctx) {
+    this.ctx = ctx;
 
-  var { height } = ctx.canvas;
-  this.layout = {
-    xAxisLabel_Y: height - 20,
-  };
-}
-
-Graph.prototype.xpos = index => index * 2;
+    var { height } = ctx.canvas;
+    this.layout = {
+      xAxisLabel_Y: height - 20,
+    };
+  }
 
-Graph.prototype.clear = function() {
-  var { width, height } = this.ctx.canvas;
-  this.ctx.clearRect(0, 0, width, height);
-};
+  xpos(index) {
+    return index * 2;
+  }
 
-Graph.prototype.drawScale = function(delay) {
-  this.drawHBar(delay, `${delay}ms`, "rgb(150,150,150)");
-};
+  clear() {
+    const { width, height } = this.ctx.canvas;
+    this.ctx.clearRect(0, 0, width, height);
+  }
 
-Graph.prototype.draw60fps = function() {
-  this.drawHBar(1000 / 60, "60fps", "#00cf61", 25);
-};
+  drawScale(delay) {
+    this.drawHBar(delay, `${delay}ms`, "rgb(150,150,150)");
+  }
 
-Graph.prototype.draw30fps = function() {
-  this.drawHBar(1000 / 30, "30fps", "#cf0061", 25);
-};
+  draw60fps() {
+    this.drawHBar(1000 / 60, "60fps", "#00cf61", 25);
+  }
 
-Graph.prototype.drawAxisLabels = function(x_label, y_label) {
-  var ctx = this.ctx;
-  var { width, height } = ctx.canvas;
-
-  ctx.fillText(x_label, width / 2, this.layout.xAxisLabel_Y);
+  draw30fps() {
+    this.drawHBar(1000 / 30, "30fps", "#cf0061", 25);
+  }
 
-  ctx.save();
-  ctx.rotate(Math.PI / 2);
-  var start = height / 2 - ctx.measureText(y_label).width / 2;
-  ctx.fillText(y_label, start, -width + 20);
-  ctx.restore();
-};
+  drawAxisLabels(x_label, y_label) {
+    const ctx = this.ctx;
+    const { width, height } = ctx.canvas;
+
+    ctx.fillText(x_label, width / 2, this.layout.xAxisLabel_Y);
 
-Graph.prototype.drawFrame = function() {
-  var ctx = this.ctx;
-  var { width, height } = ctx.canvas;
+    ctx.save();
+    ctx.rotate(Math.PI / 2);
+    var start = height / 2 - ctx.measureText(y_label).width / 2;
+    ctx.fillText(y_label, start, -width + 20);
+    ctx.restore();
+  }
+
+  drawFrame() {
+    const ctx = this.ctx;
+    const { width, height } = ctx.canvas;
 
-  // Draw frame to show size
-  ctx.strokeStyle = "rgb(0,0,0)";
-  ctx.fillStyle = "rgb(0,0,0)";
-  ctx.beginPath();
-  ctx.moveTo(0, 0);
-  ctx.lineTo(width, 0);
-  ctx.lineTo(width, height);
-  ctx.lineTo(0, height);
-  ctx.closePath();
-  ctx.stroke();
-};
-
-function LatencyGraph(ctx) {
-  Graph.call(this, ctx);
-  console.log(this.ctx);
+    // Draw frame to show size
+    ctx.strokeStyle = "rgb(0,0,0)";
+    ctx.fillStyle = "rgb(0,0,0)";
+    ctx.beginPath();
+    ctx.moveTo(0, 0);
+    ctx.lineTo(width, 0);
+    ctx.lineTo(width, height);
+    ctx.lineTo(0, height);
+    ctx.closePath();
+    ctx.stroke();
+  }
 }
 
-LatencyGraph.prototype = Object.create(Graph.prototype);
+class LatencyGraph extends Graph {
+  constructor(ctx) {
+    super(ctx);
+    console.log(this.ctx);
+  }
 
-Object.defineProperty(LatencyGraph.prototype, "constructor", {
-  enumerable: false,
-  value: LatencyGraph,
-});
+  ypos(delay) {
+    const { height } = this.ctx.canvas;
 
-LatencyGraph.prototype.ypos = function(delay) {
-  var { height } = this.ctx.canvas;
+    const r = height + 100 - Math.log(delay) * 64;
+    if (r < 5) {
+      return 5;
+    }
+    return r;
+  }
 
-  var r = height + 100 - Math.log(delay) * 64;
-  if (r < 5) {
-    return 5;
-  }
-  return r;
-};
+  drawHBar(delay, label, color = "rgb(0,0,0)", label_offset = 0) {
+    const ctx = this.ctx;
 
-LatencyGraph.prototype.drawHBar = function(
-  delay,
-  label,
-  color = "rgb(0,0,0)",
-  label_offset = 0
-) {
-  var ctx = this.ctx;
+    ctx.fillStyle = color;
+    ctx.strokeStyle = color;
+    ctx.fillText(
+      label,
+      this.xpos(numSamples) + 4 + label_offset,
+      this.ypos(delay) + 3
+    );
 
-  ctx.fillStyle = color;
-  ctx.strokeStyle = color;
-  ctx.fillText(
-    label,
-    this.xpos(numSamples) + 4 + label_offset,
-    this.ypos(delay) + 3
-  );
+    ctx.beginPath();
+    ctx.moveTo(this.xpos(0), this.ypos(delay));
+    ctx.lineTo(this.xpos(numSamples) + label_offset, this.ypos(delay));
+    ctx.stroke();
+    ctx.strokeStyle = "rgb(0,0,0)";
+    ctx.fillStyle = "rgb(0,0,0)";
+  }
 
-  ctx.beginPath();
-  ctx.moveTo(this.xpos(0), this.ypos(delay));
-  ctx.lineTo(this.xpos(numSamples) + label_offset, this.ypos(delay));
-  ctx.stroke();
-  ctx.strokeStyle = "rgb(0,0,0)";
-  ctx.fillStyle = "rgb(0,0,0)";
-};
+  draw() {
+    const ctx = this.ctx;
+
+    this.clear();
+    this.drawFrame();
 
-LatencyGraph.prototype.draw = function() {
-  let ctx = this.ctx;
+    for (var delay of [10, 20, 30, 50, 100, 200, 400, 800]) {
+      this.drawScale(delay);
+    }
+    this.draw60fps();
+    this.draw30fps();
 
-  this.clear();
-  this.drawFrame();
-
-  for (const delay of [10, 20, 30, 50, 100, 200, 400, 800]) {
-    this.drawScale(delay);
-  }
-  this.draw60fps();
-  this.draw30fps();
-
-  var worst = 0,
-    worstpos = 0;
-  ctx.beginPath();
-  for (let i = 0; i < numSamples; i++) {
-    ctx.lineTo(this.xpos(i), this.ypos(gPerf.delays[i]));
-    if (gPerf.delays[i] >= worst) {
-      worst = gPerf.delays[i];
-      worstpos = i;
+    var worst = 0,
+      worstpos = 0;
+    ctx.beginPath();
+    for (let i = 0; i < numSamples; i++) {
+      ctx.lineTo(this.xpos(i), this.ypos(gPerf.delays[i]));
+      if (gPerf.delays[i] >= worst) {
+        worst = gPerf.delays[i];
+        worstpos = i;
+      }
     }
-  }
-  ctx.stroke();
+    ctx.stroke();
 
-  // Draw vertical lines marking minor and major GCs
-  if (features.showingGCs) {
-    ctx.strokeStyle = stroke.gcslice;
-    let idx = sampleIndex % numSamples;
-    const count = {
-      major: gPerf.majorGCs[idx],
-      minor: 0,
-      slice: gPerf.slices[idx],
-    };
-    for (let i = 0; i < numSamples; i++) {
-      idx = (sampleIndex + i) % numSamples;
-      const isMajorStart = count.major < gPerf.majorGCs[idx];
-      if (count.slice < gPerf.slices[idx]) {
-        if (isMajorStart) {
-          ctx.strokeStyle = stroke.initialMajor;
+    // Draw vertical lines marking minor and major GCs
+    if (features.showingGCs) {
+      ctx.strokeStyle = stroke.gcslice;
+      let idx = sampleIndex % numSamples;
+      const count = {
+        major: gPerf.majorGCs[idx],
+        minor: 0,
+        slice: gPerf.slices[idx],
+      };
+      for (let i = 0; i < numSamples; i++) {
+        idx = (sampleIndex + i) % numSamples;
+        const isMajorStart = count.major < gPerf.majorGCs[idx];
+        if (count.slice < gPerf.slices[idx]) {
+          if (isMajorStart) {
+            ctx.strokeStyle = stroke.initialMajor;
+          }
+          ctx.beginPath();
+          ctx.moveTo(this.xpos(idx), 0);
+          ctx.lineTo(this.xpos(idx), this.layout.xAxisLabel_Y);
+          ctx.stroke();
+          if (isMajorStart) {
+            ctx.strokeStyle = stroke.gcslice;
+          }
         }
-        ctx.beginPath();
-        ctx.moveTo(this.xpos(idx), 0);
-        ctx.lineTo(this.xpos(idx), this.layout.xAxisLabel_Y);
-        ctx.stroke();
-        if (isMajorStart) {
-          ctx.strokeStyle = stroke.gcslice;
+        count.major = gPerf.majorGCs[idx];
+        count.slice = gPerf.slices[idx];
+      }
+
+      ctx.strokeStyle = stroke.minor;
+      idx = sampleIndex % numSamples;
+      count.minor = gPerf.minorGCs[idx];
+      for (let i = 0; i < numSamples; i++) {
+        idx = (sampleIndex + i) % numSamples;
+        if (count.minor < gPerf.minorGCs[idx]) {
+          ctx.beginPath();
+          ctx.moveTo(this.xpos(idx), 0);
+          ctx.lineTo(this.xpos(idx), 20);
+          ctx.stroke();
         }
+        count.minor = gPerf.minorGCs[idx];
       }
-      count.major = gPerf.majorGCs[idx];
-      count.slice = gPerf.slices[idx];
     }
 
-    ctx.strokeStyle = stroke.minor;
-    idx = sampleIndex % numSamples;
-    count.minor = gPerf.gcs[idx];
-    for (let i = 0; i < numSamples; i++) {
-      idx = (sampleIndex + i) % numSamples;
-      if (count.minor < gPerf.minorGCs[idx]) {
-        ctx.beginPath();
-        ctx.moveTo(this.xpos(idx), 0);
-        ctx.lineTo(this.xpos(idx), 20);
-        ctx.stroke();
-      }
-      count.minor = gPerf.minorGCs[idx];
+    ctx.fillStyle = "rgb(255,0,0)";
+    if (worst) {
+      ctx.fillText(
+        `${worst.toFixed(2)}ms`,
+        this.xpos(worstpos) - 10,
+        this.ypos(worst) - 14
+      );
     }
-  }
 
-  ctx.fillStyle = "rgb(255,0,0)";
-  if (worst) {
-    ctx.fillText(
-      `${worst.toFixed(2)}ms`,
-      this.xpos(worstpos) - 10,
-      this.ypos(worst) - 14
+    // Mark and label the slowest frame
+    ctx.beginPath();
+    var where = sampleIndex % numSamples;
+    ctx.arc(
+      this.xpos(where),
+      this.ypos(gPerf.delays[where]),
+      5,
+      0,
+      Math.PI * 2,
+      true
+    );
+    ctx.fill();
+    ctx.fillStyle = "rgb(0,0,0)";
+
+    this.drawAxisLabels("Time", "Pause between frames (log scale)");
+  }
+}
+
+class MemoryGraph extends Graph {
+  constructor(ctx) {
+    super(ctx);
+    this.worstEver = this.bestEver = performance.mozMemory.zone.gcBytes;
+    this.limit = Math.max(
+      this.worstEver,
+      performance.mozMemory.zone.gcAllocTrigger
     );
   }
 
-  // Mark and label the slowest frame
-  ctx.beginPath();
-  var where = sampleIndex % numSamples;
-  ctx.arc(
-    this.xpos(where),
-    this.ypos(gPerf.delays[where]),
-    5,
-    0,
-    Math.PI * 2,
-    true
-  );
-  ctx.fill();
-  ctx.fillStyle = "rgb(0,0,0)";
+  ypos(size) {
+    const { height } = this.ctx.canvas;
 
-  this.drawAxisLabels("Time", "Pause between frames (log scale)");
-};
+    const range = this.limit - this.bestEver;
+    const percent = (size - this.bestEver) / range;
 
-function MemoryGraph(ctx) {
-  Graph.call(this, ctx);
-  this.worstEver = this.bestEver = performance.mozMemory.gc.zone.gcBytes;
-  this.limit = Math.max(
-    this.worstEver,
-    performance.mozMemory.gc.zone.gcAllocTrigger
-  );
-}
-
-MemoryGraph.prototype = Object.create(Graph.prototype);
+    return (1 - percent) * height * 0.9 + 20;
+  }
 
-Object.defineProperty(MemoryGraph.prototype, "constructor", {
-  enumerable: false,
-  value: MemoryGraph,
-});
-
-MemoryGraph.prototype.ypos = function(size) {
-  var { height } = this.ctx.canvas;
-
-  var range = this.limit - this.bestEver;
-  var percent = (size - this.bestEver) / range;
+  drawHBar(size, label, color = "rgb(150,150,150)") {
+    const ctx = this.ctx;
 
-  return (1 - percent) * height * 0.9 + 20;
-};
+    const y = this.ypos(size);
 
-MemoryGraph.prototype.drawHBar = function(
-  size,
-  label,
-  color = "rgb(150,150,150)"
-) {
-  var ctx = this.ctx;
-
-  var y = this.ypos(size);
-
-  ctx.fillStyle = color;
-  ctx.strokeStyle = color;
-  ctx.fillText(label, this.xpos(numSamples) + 4, y + 3);
+    ctx.fillStyle = color;
+    ctx.strokeStyle = color;
+    ctx.fillText(label, this.xpos(numSamples) + 4, y + 3);
 
-  ctx.beginPath();
-  ctx.moveTo(this.xpos(0), y);
-  ctx.lineTo(this.xpos(numSamples), y);
-  ctx.stroke();
-  ctx.strokeStyle = "rgb(0,0,0)";
-  ctx.fillStyle = "rgb(0,0,0)";
-};
-
-MemoryGraph.prototype.draw = function() {
-  var ctx = this.ctx;
-
-  this.clear();
-  this.drawFrame();
-
-  var worst = 0,
-    worstpos = 0;
-  for (let i = 0; i < numSamples; i++) {
-    if (gPerf.gcBytes[i] >= worst) {
-      worst = gPerf.gcBytes[i];
-      worstpos = i;
-    }
-    if (gPerf.gcBytes[i] < this.bestEver) {
-      this.bestEver = gPerf.gcBytes[i];
-    }
+    ctx.beginPath();
+    ctx.moveTo(this.xpos(0), y);
+    ctx.lineTo(this.xpos(numSamples), y);
+    ctx.stroke();
+    ctx.strokeStyle = "rgb(0,0,0)";
+    ctx.fillStyle = "rgb(0,0,0)";
   }
 
-  if (this.worstEver < worst) {
-    this.worstEver = worst;
-    this.limit = Math.max(
-      this.worstEver,
-      performance.mozMemory.gc.zone.gcAllocTrigger
-    );
-  }
+  draw() {
+    const ctx = this.ctx;
+
+    this.clear();
+    this.drawFrame();
+
+    var worst = 0,
+      worstpos = 0;
+    for (let i = 0; i < numSamples; i++) {
+      if (gPerf.gcBytes[i] >= worst) {
+        worst = gPerf.gcBytes[i];
+        worstpos = i;
+      }
+      if (gPerf.gcBytes[i] < this.bestEver) {
+        this.bestEver = gPerf.gcBytes[i];
+      }
+    }
+
+    if (this.worstEver < worst) {
+      this.worstEver = worst;
+      this.limit = Math.max(
+        this.worstEver,
+        performance.mozMemory.zone.gcAllocTrigger
+      );
+    }
 
-  this.drawHBar(this.bestEver, `${format_bytes(this.bestEver)} min`, "#00cf61");
-  this.drawHBar(
-    this.worstEver,
-    `${format_bytes(this.worstEver)} max`,
-    "#cc1111"
-  );
-  this.drawHBar(
-    performance.mozMemory.gc.zone.gcAllocTrigger,
-    `${format_bytes(performance.mozMemory.gc.zone.gcAllocTrigger)} trigger`,
-    "#cc11cc"
-  );
+    this.drawHBar(
+      this.bestEver,
+      `${format_bytes(this.bestEver)} min`,
+      "#00cf61"
+    );
+    this.drawHBar(
+      this.worstEver,
+      `${format_bytes(this.worstEver)} max`,
+      "#cc1111"
+    );
+    this.drawHBar(
+      performance.mozMemory.zone.gcAllocTrigger,
+      `${format_bytes(performance.mozMemory.zone.gcAllocTrigger)} trigger`,
+      "#cc11cc"
+    );
+
+    ctx.fillStyle = "rgb(255,0,0)";
+    if (worst) {
+      ctx.fillText(
+        format_bytes(worst),
+        this.xpos(worstpos) - 10,
+        this.ypos(worst) - 14
+      );
+    }
 
-  ctx.fillStyle = "rgb(255,0,0)";
-  if (worst) {
-    ctx.fillText(
-      format_bytes(worst),
-      this.xpos(worstpos) - 10,
-      this.ypos(worst) - 14
+    ctx.beginPath();
+    var where = sampleIndex % numSamples;
+    ctx.arc(
+      this.xpos(where),
+      this.ypos(gPerf.gcBytes[where]),
+      5,
+      0,
+      Math.PI * 2,
+      true
     );
+    ctx.fill();
+
+    ctx.beginPath();
+    for (let i = 0; i < numSamples; i++) {
+      if (i == (sampleIndex + 1) % numSamples) {
+        ctx.moveTo(this.xpos(i), this.ypos(gPerf.gcBytes[i]));
+      } else {
+        ctx.lineTo(this.xpos(i), this.ypos(gPerf.gcBytes[i]));
+      }
+      if (i == where) {
+        ctx.stroke();
+      }
+    }
+    ctx.stroke();
+
+    this.drawAxisLabels("Time", "Heap Memory Usage");
   }
-
-  ctx.beginPath();
-  var where = sampleIndex % numSamples;
-  ctx.arc(
-    this.xpos(where),
-    this.ypos(gPerf.gcBytes[where]),
-    5,
-    0,
-    Math.PI * 2,
-    true
-  );
-  ctx.fill();
-
-  ctx.beginPath();
-  for (var i = 0; i < numSamples; i++) {
-    if (i == (sampleIndex + 1) % numSamples) {
-      ctx.moveTo(this.xpos(i), this.ypos(gPerf.gcBytes[i]));
-    } else {
-      ctx.lineTo(this.xpos(i), this.ypos(gPerf.gcBytes[i]));
-    }
-    if (i == where) {
-      ctx.stroke();
-    }
-  }
-  ctx.stroke();
-
-  this.drawAxisLabels("Time", "Heap Memory Usage");
-};
+}
 
 function onUpdateDisplayChanged() {
   const do_graph = document.getElementById("do-graph");
   if (do_graph.checked) {
     window.requestAnimationFrame(handler);
     gPerf.resume();
   } else {
     gPerf.pause();
@@ -420,17 +409,17 @@ function handler(timestamp) {
 function summarize(arr) {
   if (!arr.length) {
     return [];
   }
 
   var result = [];
   var run_start = 0;
   var prev = arr[0];
-  for (var i = 1; i <= arr.length; i++) {
+  for (let i = 1; i <= arr.length; i++) {
     if (i == arr.length || arr[i] != prev) {
       if (i == run_start + 1) {
         result.push(arr[i]);
       } else {
         result.push(prev + " x " + (i - run_start));
       }
       run_start = i;
     }