Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
lib: use class fields in observe.js
https://bugs.chromium.org/p/v8/issues/detail?id=10704 is already
fixed, so switch back to class fields instead of using
symbol properties.
  • Loading branch information
joyeecheung committed Mar 16, 2022
commit ccbb05fe61de1bf944af4dd3e3778de55be2aee6
75 changes: 36 additions & 39 deletions lib/internal/perf/observe.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,9 @@ const {

const { inspect } = require('util');

const kBuffer = Symbol('kBuffer');
const kCallback = Symbol('kCallback');
const kDispatch = Symbol('kDispatch');
const kEntryTypes = Symbol('kEntryTypes');
const kMaybeBuffer = Symbol('kMaybeBuffer');
const kDeprecatedFields = Symbol('kDeprecatedFields');
const kType = Symbol('kType');

const kDeprecationMessage =
'Custom PerformanceEntry accessors are deprecated. ' +
Expand Down Expand Up @@ -151,32 +147,34 @@ function maybeIncrementObserverCount(type) {
}

class PerformanceObserverEntryList {
#buffer = [];
Comment thread
joyeecheung marked this conversation as resolved.

constructor(entries) {
this[kBuffer] = ArrayPrototypeSort(entries, (first, second) => {
this.#buffer = ArrayPrototypeSort(entries, (first, second) => {
return first.startTime - second.startTime;
});
}

getEntries() {
return ArrayPrototypeSlice(this[kBuffer]);
return ArrayPrototypeSlice(this.#buffer);
}

getEntriesByType(type) {
type = `${type}`;
return ArrayPrototypeFilter(
this[kBuffer],
this.#buffer,
(entry) => entry.entryType === type);
}

getEntriesByName(name, type) {
name = `${name}`;
if (type != null /** not nullish */) {
return ArrayPrototypeFilter(
this[kBuffer],
this.#buffer,
(entry) => entry.name === name && entry.entryType === type);
}
return ArrayPrototypeFilter(
this[kBuffer],
this.#buffer,
(entry) => entry.name === name);
}

Expand All @@ -188,20 +186,19 @@ class PerformanceObserverEntryList {
depth: options.depth == null ? null : options.depth - 1
};

return `PerformanceObserverEntryList ${inspect(this[kBuffer], opts)}`;
return `PerformanceObserverEntryList ${inspect(this.#buffer, opts)}`;
}
}

class PerformanceObserver {
#buffer = [];
#entryTypes = new SafeSet();
#type;
#callback;

constructor(callback) {
// TODO(joyeecheung): V8 snapshot does not support instance member
// initializers for now:
// https://bugs.chromium.org/p/v8/issues/detail?id=10704
this[kBuffer] = [];
this[kEntryTypes] = new SafeSet();
this[kType] = undefined;
validateFunction(callback, 'callback');
this[kCallback] = callback;
this.#callback = callback;
}

observe(options = {}) {
Expand All @@ -219,10 +216,10 @@ class PerformanceObserver {
'options.entryTypes can not set with ' +
'options.type together');

switch (this[kType]) {
switch (this.#type) {
case undefined:
if (entryTypes !== undefined) this[kType] = kTypeMultiple;
if (type !== undefined) this[kType] = kTypeSingle;
if (entryTypes !== undefined) this.#type = kTypeMultiple;
if (type !== undefined) this.#type = kTypeSingle;
break;
case kTypeSingle:
if (entryTypes !== undefined)
Expand All @@ -238,53 +235,53 @@ class PerformanceObserver {
break;
}

if (this[kType] === kTypeMultiple) {
if (this.#type === kTypeMultiple) {
if (!ArrayIsArray(entryTypes)) {
throw new ERR_INVALID_ARG_TYPE(
'options.entryTypes',
'string[]',
entryTypes);
}
maybeDecrementObserverCounts(this[kEntryTypes]);
this[kEntryTypes].clear();
maybeDecrementObserverCounts(this.#entryTypes);
this.#entryTypes.clear();
for (let n = 0; n < entryTypes.length; n++) {
if (ArrayPrototypeIncludes(kSupportedEntryTypes, entryTypes[n])) {
this[kEntryTypes].add(entryTypes[n]);
this.#entryTypes.add(entryTypes[n]);
maybeIncrementObserverCount(entryTypes[n]);
}
}
} else {
if (!ArrayPrototypeIncludes(kSupportedEntryTypes, type))
return;
this[kEntryTypes].add(type);
this.#entryTypes.add(type);
maybeIncrementObserverCount(type);
if (buffered) {
const entries = filterBufferMapByNameAndType(undefined, type);
ArrayPrototypePushApply(this[kBuffer], entries);
ArrayPrototypePushApply(this.#buffer, entries);
kPending.add(this);
if (kPending.size)
queuePending();
}
}

if (this[kEntryTypes].size)
if (this.#entryTypes.size)
kObservers.add(this);
else
this.disconnect();
}

disconnect() {
maybeDecrementObserverCounts(this[kEntryTypes]);
maybeDecrementObserverCounts(this.#entryTypes);
kObservers.delete(this);
kPending.delete(this);
this[kBuffer] = [];
this[kEntryTypes].clear();
this[kType] = undefined;
this.#buffer = [];
this.#entryTypes.clear();
this.#type = undefined;
}

takeRecords() {
const list = this[kBuffer];
this[kBuffer] = [];
const list = this.#buffer;
this.#buffer = [];
return list;
}

Expand All @@ -293,17 +290,17 @@ class PerformanceObserver {
}

[kMaybeBuffer](entry) {
if (!this[kEntryTypes].has(entry.entryType))
if (!this.#entryTypes.has(entry.entryType))
return;
ArrayPrototypePush(this[kBuffer], entry);
ArrayPrototypePush(this.#buffer, entry);
kPending.add(this);
if (kPending.size)
queuePending();
}

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

[kInspect](depth, options) {
Expand All @@ -317,8 +314,8 @@ class PerformanceObserver {
return `PerformanceObserver ${inspect({
connected: kObservers.has(this),
pending: kPending.has(this),
entryTypes: ArrayFrom(this[kEntryTypes]),
buffer: this[kBuffer],
entryTypes: ArrayFrom(this.#entryTypes),
buffer: this.#buffer,
}, opts)}`;
}
}
Expand Down