summaryrefslogtreecommitdiff
path: root/lib/perf_hooks.js
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2018-03-23 11:23:22 -0700
committerJames M Snell <jasnell@gmail.com>2018-04-03 13:57:41 -0700
commit2ec69955556bf92f49355659b6126e08fa2c3298 (patch)
tree3164620ed2a629f083119f58fe75856b2ed401c3 /lib/perf_hooks.js
parentd54f651910ffca2e50fad42dfec825d2339b1b6b (diff)
downloadandroid-node-v8-2ec69955556bf92f49355659b6126e08fa2c3298.tar.gz
android-node-v8-2ec69955556bf92f49355659b6126e08fa2c3298.tar.bz2
android-node-v8-2ec69955556bf92f49355659b6126e08fa2c3298.zip
perf_hooks: simplify perf_hooks
Remove the `performance.getEntries()` and `performance.clear*()` variants and eliminate the accumulation of the global timeline entries. The design of this particular bit of the API is a memory leak and performance footgun. The `PerformanceObserver` API is a better approach to consuming the data in a more transient way. PR-URL: https://github.com/nodejs/node/pull/19563 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'lib/perf_hooks.js')
-rw-r--r--lib/perf_hooks.js101
1 files changed, 7 insertions, 94 deletions
diff --git a/lib/perf_hooks.js b/lib/perf_hooks.js
index 7fa5501b28..9080cc7f26 100644
--- a/lib/perf_hooks.js
+++ b/lib/perf_hooks.js
@@ -3,6 +3,7 @@
const {
PerformanceEntry,
mark: _mark,
+ clearMark: _clearMark,
measure: _measure,
milestones,
observerCounts,
@@ -50,17 +51,11 @@ const kBuffering = Symbol('buffering');
const kQueued = Symbol('queued');
const kTimerified = Symbol('timerified');
const kInsertEntry = Symbol('insert-entry');
-const kIndexEntry = Symbol('index-entry');
-const kClearEntry = Symbol('clear-entry');
const kGetEntries = Symbol('get-entries');
const kIndex = Symbol('index');
const kMarks = Symbol('marks');
const kCount = Symbol('count');
-const kMaxCount = Symbol('max-count');
-const kDefaultMaxCount = 150;
-observerCounts[NODE_PERFORMANCE_ENTRY_TYPE_MARK] = 1;
-observerCounts[NODE_PERFORMANCE_ENTRY_TYPE_MEASURE] = 1;
const observers = {};
const observerableTypes = [
'node',
@@ -286,17 +281,12 @@ class PerformanceObserverEntryList {
const item = { entry };
L.append(this[kEntries], item);
this[kCount]++;
- this[kIndexEntry](item);
}
get length() {
return this[kCount];
}
- [kIndexEntry](entry) {
- // Default implementation does nothing
- }
-
[kGetEntries](name, type) {
const ret = [];
const list = this[kEntries];
@@ -407,72 +397,11 @@ class PerformanceObserver extends AsyncResource {
}
}
-class Performance extends PerformanceObserverEntryList {
+class Performance {
constructor() {
- super();
this[kIndex] = {
[kMarks]: new Set()
};
- this[kMaxCount] = kDefaultMaxCount;
- this[kInsertEntry](nodeTiming);
- }
-
- set maxEntries(val) {
- if (typeof val !== 'number' || val >>> 0 !== val) {
- const errors = lazyErrors();
- throw new errors.ERR_INVALID_ARG_TYPE('val', 'number', val);
- }
- this[kMaxCount] = Math.max(1, val >>> 0);
- }
-
- get maxEntries() {
- return this[kMaxCount];
- }
-
- [kIndexEntry](item) {
- const index = this[kIndex];
- const type = item.entry.entryType;
- let items = index[type];
- if (!items) {
- items = index[type] = {};
- L.init(items);
- }
- const entry = item.entry;
- L.append(items, { entry, item });
- const count = this[kCount];
- if (count > this[kMaxCount]) {
- const text = count === 1 ? 'is 1 entry' : `are ${count} entries`;
- process.emitWarning('Possible perf_hooks memory leak detected. ' +
- `There ${text} in the ` +
- 'Performance Timeline. Use the clear methods ' +
- 'to remove entries that are no longer needed or ' +
- 'set performance.maxEntries equal to a higher ' +
- 'value (currently the maxEntries is ' +
- `${this[kMaxCount]}).`);
- }
- }
-
- [kClearEntry](type, name) {
- const index = this[kIndex];
- const items = index[type];
- if (!items) return;
- let item = L.peek(items);
- while (item && item !== items) {
- const entry = item.entry;
- const next = item._idlePrev;
- if (name !== undefined) {
- if (entry.name === `${name}`) {
- L.remove(item); // remove from the index
- L.remove(item.item); // remove from the master
- this[kCount]--;
- }
- } else {
- L.remove(item); // remove from the index
- L.remove(item.item); // remove from the master
- this[kCount]--;
- }
- item = next;
- }
}
get nodeTiming() {
@@ -507,27 +436,13 @@ class Performance extends PerformanceObserverEntryList {
clearMarks(name) {
name = name !== undefined ? `${name}` : name;
- this[kClearEntry]('mark', name);
- if (name !== undefined)
+ if (name !== undefined) {
this[kIndex][kMarks].delete(name);
- else
+ _clearMark(name);
+ } else {
this[kIndex][kMarks].clear();
- }
-
- clearMeasures(name) {
- this[kClearEntry]('measure', name);
- }
-
- clearGC() {
- this[kClearEntry]('gc');
- }
-
- clearFunctions(name) {
- this[kClearEntry]('function', name);
- }
-
- clearEntries(name) {
- this[kClearEntry](name);
+ _clearMark();
+ }
}
timerify(fn) {
@@ -563,7 +478,6 @@ class Performance extends PerformanceObserverEntryList {
[kInspect]() {
return {
- maxEntries: this.maxEntries,
nodeTiming: this.nodeTiming,
timeOrigin: this.timeOrigin
};
@@ -595,7 +509,6 @@ function observersCallback(entry) {
if (type === NODE_PERFORMANCE_ENTRY_TYPE_HTTP2)
collectHttp2Stats(entry);
- performance[kInsertEntry](entry);
const list = getObserversList(type);
let current = L.peek(list);