Implement performance.measureMemory with per-frame sizes

This uses a new v8::Isolate::MeasureMemory API to compute the JS memory
footprint of each v8::Context that has the same security origin and
the same JS agent as the calling context does.

The V8 API takes a delegate with two methods that are implemented here:
1) ShouldMeasure(context) for selecting the contexts to measure.
   It fetches the security origin and the JS agent of a context by
   going through Context => ExecutionContext.

2) MeasurementComplete(context_sizes, unattributed_size) is called by
   V8 when the measurement is done. The function constructs an object
   representing the result and resolves the promise with it.

# Disable audit_non_blink_usage std::vector check per reviewer's comment
NOPRESUBMIT=True

Bug: 973627
Change-Id: Ibd0fb3463978184f1d467be306063d1f40105fda
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1986795
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#733300}
diff --git a/measure-memory/measure-memory.tentative.any.js b/measure-memory/measure-memory.tentative.any.js
index c4f47a0..cf42e2c 100644
--- a/measure-memory/measure-memory.tentative.any.js
+++ b/measure-memory/measure-memory.tentative.any.js
@@ -1,25 +1,62 @@
+function checkMeasureMemoryResultEntry(entry, checkUrl) {
+  assert_own_property(entry, "jsMemoryEstimate");
+  assert_own_property(entry, "jsMemoryRange");
+  assert_equals(entry.jsMemoryRange.length, 2);
+  assert_greater_than_equal(entry.jsMemoryRange[1], entry.jsMemoryRange[0]);
+  assert_greater_than_equal(entry.jsMemoryEstimate, entry.jsMemoryRange[0]);
+  assert_greater_than_equal(entry.jsMemoryRange[1], entry.jsMemoryEstimate);
+  if (checkUrl) {
+    assert_own_property(entry, "url");
+  }
+}
+
 function checkMeasureMemoryResultSummary(result) {
     assert_own_property(result, "total");
-    assert_own_property(result.total, "jsMemoryEstimate");
-    assert_own_property(result.total, "jsMemoryRange");
-    assert_equals(result.total.jsMemoryRange.length, 2);
-    assert_greater_than_equal(
-        result.total.jsMemoryRange[1],
-        result.total.jsMemoryRange[0]);
-    assert_greater_than_equal(
-        result.total.jsMemoryEstimate,
-        result.total.jsMemoryRange[0]);
-    assert_greater_than_equal(
-        result.total.jsMemoryRange[1],
-        result.total.jsMemoryEstimate);
+    checkMeasureMemoryResultEntry(result.total, false);
+}
+
+function checkMeasureMemoryResultDetails(result) {
+    assert_own_property(result, "current");
+    checkMeasureMemoryResultEntry(result.current, true);
+    assert_own_property(result, "other");
+    for (other of result.other) {
+      checkMeasureMemoryResultEntry(other, true);
+    }
 }
 
 promise_test(async testCase => {
-  let result = await performance.measureMemory();
-  checkMeasureMemoryResultSummary(result);
+  try {
+    let result = await performance.measureMemory();
+    checkMeasureMemoryResultSummary(result);
+  } catch (error) {
+    if (!(error instanceof DOMException)) {
+      throw error;
+    }
+    assert_equals(error.name, "SecurityError");
+  }
 }, 'Well-formed result of performance.measureMemory with default arguments.');
 
 promise_test(async testcase => {
-  let result = await performance.measureMemory({detailed: false});
-  checkMeasureMemoryResultSummary(result);
-}, 'well-formed result of performance.measurememory with detailed=false.');
+  try {
+    let result = await performance.measureMemory({detailed: false});
+    checkMeasureMemoryResultSummary(result);
+  } catch (error) {
+    if (!(error instanceof DOMException)) {
+      throw error;
+    }
+    assert_equals(error.name, "SecurityError");
+  }
+}, 'well-formed result of performance.measureMemory with detailed=false.');
+
+promise_test(async testcase => {
+  try {
+    let result = await performance.measureMemory({detailed: true});
+    checkMeasureMemoryResultSummary(result);
+    checkMeasureMemoryResultDetails(result);
+  } catch (error) {
+    if (!(error instanceof DOMException)) {
+      throw error;
+    }
+    assert_equals(error.name, "SecurityError");
+  }
+}, 'well-formed result of performance.measureMemory with detailed=true.');