Skip to content

Commit

Permalink
perf_hooks: fix performance timeline wpt failures
Browse files Browse the repository at this point in the history
PR-URL: nodejs#39532
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Khaidi Chu <[email protected]>
  • Loading branch information
legendecas authored and jasnell committed Jul 30, 2021
1 parent 317e71b commit a27d245
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 10 deletions.
37 changes: 30 additions & 7 deletions lib/internal/perf/observe.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const {
const {
customInspectSymbol: kInspect,
deprecate,
lazyDOMException,
} = require('internal/util');

const {
Expand Down Expand Up @@ -106,9 +107,10 @@ function queuePending() {
isPending = true;
setImmediate(() => {
isPending = false;
for (const pending of kPending)
pending[kDispatch]();
const pendings = ArrayFrom(kPending.values());
kPending.clear();
for (const pending of pendings)
pending[kDispatch]();
});
}

Expand Down Expand Up @@ -168,8 +170,13 @@ class PerformanceObserverEntryList {
(entry) => entry.entryType === type);
}

getEntriesByName(name) {
getEntriesByName(name, type) {
name = `${name}`;
if (type != null /** not nullish */) {
return ArrayPrototypeFilter(
this[kBuffer],
(entry) => entry.name === name && entry.entryType === type);
}
return ArrayPrototypeFilter(
this[kBuffer],
(entry) => entry.name === name);
Expand Down Expand Up @@ -208,6 +215,11 @@ class PerformanceObserver {
} = { ...options };
if (entryTypes === undefined && type === undefined)
throw new ERR_MISSING_ARGS('options.entryTypes', 'options.type');
if (entryTypes != null && type != null)
throw new ERR_INVALID_ARG_VALUE('options.entryTypes',
entryTypes,
'options.entryTypes can not set with ' +
'options.type together');

switch (this[kType]) {
case undefined:
Expand All @@ -216,11 +228,15 @@ class PerformanceObserver {
break;
case kTypeSingle:
if (entryTypes !== undefined)
throw new ERR_INVALID_ARG_VALUE('options.entryTypes', entryTypes);
throw lazyDOMException(
'PerformanceObserver can not change to multiple observations',
'InvalidModificationError');
break;
case kTypeMultiple:
if (type !== undefined)
throw new ERR_INVALID_ARG_VALUE('options.type', type);
throw lazyDOMException(
'PerformanceObserver can not change to single observation',
'InvalidModificationError');
break;
}

Expand Down Expand Up @@ -271,7 +287,7 @@ class PerformanceObserver {
takeRecords() {
const list = this[kBuffer];
this[kBuffer] = [];
return new PerformanceObserverEntryList(list);
return list;
}

static get supportedEntryTypes() {
Expand All @@ -287,7 +303,10 @@ class PerformanceObserver {
queuePending();
}

[kDispatch]() { this[kCallback](this.takeRecords(), this); }
[kDispatch]() {
this[kCallback](new PerformanceObserverEntryList(this.takeRecords()),
this);
}

[kInspect](depth, options) {
if (depth < 0) return this;
Expand Down Expand Up @@ -367,6 +386,7 @@ function clearEntriesFromBuffer(type, name) {

let head = null;
let tail = null;
let count = 0;
for (let entry = buffer.head; entry !== null; entry = entry[kBufferNext]) {
if (entry.name !== name) {
head = head ?? entry;
Expand All @@ -377,9 +397,11 @@ function clearEntriesFromBuffer(type, name) {
continue;
}
tail[kBufferNext] = entry[kBufferNext];
count++;
}
buffer.head = head;
buffer.tail = tail;
buffer.count = count;
}

function filterBufferMapByNameAndType(name, type) {
Expand Down Expand Up @@ -469,6 +491,7 @@ function resetBuffer(buffer) {

module.exports = {
PerformanceObserver,
PerformanceObserverEntryList,
enqueue,
hasObserver,
clearEntriesFromBuffer,
Expand Down
6 changes: 5 additions & 1 deletion lib/perf_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ const {
} = internalBinding('performance');

const { PerformanceEntry } = require('internal/perf/performance_entry');
const { PerformanceObserver } = require('internal/perf/observe');
const {
PerformanceObserver,
PerformanceObserverEntryList,
} = require('internal/perf/observe');
const {
PerformanceMark,
PerformanceMeasure,
Expand All @@ -27,6 +30,7 @@ module.exports = {
PerformanceMark,
PerformanceMeasure,
PerformanceObserver,
PerformanceObserverEntryList,
monitorEventLoopDelay,
createHistogram,
performance: new InternalPerformance(),
Expand Down
12 changes: 11 additions & 1 deletion test/wpt/status/performance-timeline.json
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
{}
{
"case-sensitivity.any.js": {
"fail": "resource entry type not supported"
},
"idlharness.any.js": {
"skip": "idlharness cannot recognize Node.js environment"
},
"webtiming-resolution.any.js": {
"skip": "flaky"
}
}
4 changes: 3 additions & 1 deletion test/wpt/test-performance-timeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require('../common');
const { WPTRunner } = require('../common/wpt');

const runner = new WPTRunner('user-timing');
const runner = new WPTRunner('performance-timeline');

// Needed to access to DOMException.
runner.setFlags(['--expose-internals']);
Expand All @@ -12,11 +12,13 @@ runner.setInitScript(`
PerformanceMark,
PerformanceMeasure,
PerformanceObserver,
PerformanceObserverEntryList,
performance,
} = require('perf_hooks');
global.PerformanceMark = performance;
global.PerformanceMeasure = performance;
global.PerformanceObserver = PerformanceObserver;
global.PerformanceObserverEntryList = PerformanceObserverEntryList;
global.performance = performance;
const { internalBinding } = require('internal/test/binding');
Expand Down

0 comments on commit a27d245

Please sign in to comment.