Created
September 25, 2024 19:20
-
-
Save IanButterworth/9fb742180ee6e682e04d34819fd9d500 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## unminified version of devtools/bundled/devtools-frontend/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker.js | |
import * as e from "../../models/heap_snapshot_model/heap_snapshot_model.js"; | |
import * as t from "../../core/i18n/i18n.js"; | |
import * as s from "../../core/platform/platform.js"; | |
import * as n from "../../models/text_utils/text_utils.js"; | |
class i { | |
#e; | |
#t; | |
#s; | |
#n; | |
#i; | |
#o; | |
#r; | |
constructor(e, t) { | |
(this.#e = e.strings), (this.#t = 1), (this.#s = []), (this.#n = {}), (this.#i = {}), (this.#o = {}), (this.#r = null), this.#a(e), this.#d(e, t); | |
} | |
#a(e) { | |
const t = this.#e, | |
s = e.snapshot.meta.trace_function_info_fields, | |
n = s.indexOf("name"), | |
i = s.indexOf("script_name"), | |
o = s.indexOf("script_id"), | |
r = s.indexOf("line"), | |
d = s.indexOf("column"), | |
h = s.length, | |
l = e.trace_function_infos, | |
c = l.length, | |
u = (this.#s = new Array(c / h)); | |
let g = 0; | |
for (let e = 0; e < c; e += h) u[g++] = new a(t[l[e + n]], t[l[e + i]], l[e + o], l[e + r], l[e + d]); | |
} | |
#d(e, t) { | |
const s = e.trace_tree, | |
n = this.#s, | |
i = this.#i, | |
r = e.snapshot.meta.trace_node_fields, | |
a = r.indexOf("id"), | |
d = r.indexOf("function_info_index"), | |
h = r.indexOf("count"), | |
l = r.indexOf("size"), | |
c = r.indexOf("children"), | |
u = r.length; | |
return (function e(s, r, g) { | |
const p = n[s[r + d]], | |
f = s[r + a], | |
I = t[f], | |
x = I ? I.count : 0, | |
m = I ? I.size : 0, | |
N = new o(f, p, s[r + h], s[r + l], x, m, g); | |
(i[f] = N), p.addTraceTopNode(N); | |
const y = s[r + c]; | |
for (let t = 0; t < y.length; t += u) N.children.push(e(y, t, N)); | |
return N; | |
})(s, 0, null); | |
} | |
serializeTraceTops() { | |
if (this.#r) return this.#r; | |
const e = (this.#r = []), | |
t = this.#s; | |
for (let s = 0; s < t.length; s++) { | |
const n = t[s]; | |
if (0 === n.totalCount) continue; | |
const i = this.#t++, | |
o = 0 === s; | |
e.push(this.#h(i, n, n.totalCount, n.totalSize, n.totalLiveCount, n.totalLiveSize, !o)), (this.#o[i] = n); | |
} | |
return ( | |
e.sort(function (e, t) { | |
return t.size - e.size; | |
}), | |
e | |
); | |
} | |
serializeCallers(t) { | |
let s = this.#l(t); | |
const n = []; | |
for (; 1 === s.callers().length; ) (s = s.callers()[0]), n.push(this.#c(s)); | |
const i = [], | |
o = s.callers(); | |
for (let e = 0; e < o.length; e++) i.push(this.#c(o[e])); | |
return new e.HeapSnapshotModel.AllocationNodeCallers(n, i); | |
} | |
serializeAllocationStack(t) { | |
let s = this.#i[t]; | |
const n = []; | |
for (; s; ) { | |
const t = s.functionInfo; | |
n.push(new e.HeapSnapshotModel.AllocationStackFrame(t.functionName, t.scriptName, t.scriptId, t.line, t.column)), (s = s.parent); | |
} | |
return n; | |
} | |
traceIds(e) { | |
return this.#l(e).traceTopIds; | |
} | |
#l(e) { | |
let t = this.#n[e]; | |
if (!t) { | |
(t = this.#o[e].bottomUpRoot()), delete this.#o[e], (this.#n[e] = t); | |
} | |
return t; | |
} | |
#c(e) { | |
const t = this.#t++; | |
return (this.#n[t] = e), this.#h(t, e.functionInfo, e.allocationCount, e.allocationSize, e.liveCount, e.liveSize, e.hasCallers()); | |
} | |
#h(t, s, n, i, o, r, a) { | |
return new e.HeapSnapshotModel.SerializedAllocationNode(t, s.functionName, s.scriptName, s.scriptId, s.line, s.column, n, i, o, r, a); | |
} | |
} | |
class o { | |
id; | |
functionInfo; | |
allocationCount; | |
allocationSize; | |
liveCount; | |
liveSize; | |
parent; | |
children; | |
constructor(e, t, s, n, i, o, r) { | |
(this.id = e), (this.functionInfo = t), (this.allocationCount = s), (this.allocationSize = n), (this.liveCount = i), (this.liveSize = o), (this.parent = r), (this.children = []); | |
} | |
} | |
class r { | |
functionInfo; | |
allocationCount; | |
allocationSize; | |
liveCount; | |
liveSize; | |
traceTopIds; | |
#u; | |
constructor(e) { | |
(this.functionInfo = e), (this.allocationCount = 0), (this.allocationSize = 0), (this.liveCount = 0), (this.liveSize = 0), (this.traceTopIds = []), (this.#u = []); | |
} | |
addCaller(e) { | |
const t = e.functionInfo; | |
let s; | |
for (let e = 0; e < this.#u.length; e++) { | |
const n = this.#u[e]; | |
if (n.functionInfo === t) { | |
s = n; | |
break; | |
} | |
} | |
return s || ((s = new r(t)), this.#u.push(s)), s; | |
} | |
callers() { | |
return this.#u; | |
} | |
hasCallers() { | |
return this.#u.length > 0; | |
} | |
} | |
class a { | |
functionName; | |
scriptName; | |
scriptId; | |
line; | |
column; | |
totalCount; | |
totalSize; | |
totalLiveCount; | |
totalLiveSize; | |
#r; | |
#g; | |
constructor(e, t, s, n, i) { | |
(this.functionName = e), (this.scriptName = t), (this.scriptId = s), (this.line = n), (this.column = i), (this.totalCount = 0), (this.totalSize = 0), (this.totalLiveCount = 0), (this.totalLiveSize = 0), (this.#r = []); | |
} | |
addTraceTopNode(e) { | |
0 !== e.allocationCount && (this.#r.push(e), (this.totalCount += e.allocationCount), (this.totalSize += e.allocationSize), (this.totalLiveCount += e.liveCount), (this.totalLiveSize += e.liveSize)); | |
} | |
bottomUpRoot() { | |
return this.#r.length ? (this.#g || this.#p(), this.#g) : null; | |
} | |
#p() { | |
this.#g = new r(this); | |
for (let e = 0; e < this.#r.length; e++) { | |
let t = this.#r[e], | |
s = this.#g; | |
const n = t.allocationCount, | |
i = t.allocationSize, | |
o = t.liveCount, | |
r = t.liveSize, | |
a = t.id; | |
for (; (s.allocationCount += n), (s.allocationSize += i), (s.liveCount += o), (s.liveSize += r), s.traceTopIds.push(a), (t = t.parent), null !== t; ) s = s.addCaller(t); | |
} | |
} | |
} | |
var d = Object.freeze({ __proto__: null, AllocationProfile: i, TopDownAllocationNode: o, BottomUpAllocationNode: r, FunctionAllocationInfo: a }); | |
class h { | |
snapshot; | |
edges; | |
edgeIndex; | |
constructor(e, t) { | |
(this.snapshot = e), (this.edges = e.containmentEdges), (this.edgeIndex = t || 0); | |
} | |
clone() { | |
return new h(this.snapshot, this.edgeIndex); | |
} | |
hasStringName() { | |
throw new Error("Not implemented"); | |
} | |
name() { | |
throw new Error("Not implemented"); | |
} | |
node() { | |
return this.snapshot.createNode(this.nodeIndex()); | |
} | |
nodeIndex() { | |
if (void 0 === this.snapshot.edgeToNodeOffset) throw new Error("edgeToNodeOffset is undefined"); | |
return this.edges.getValue(this.edgeIndex + this.snapshot.edgeToNodeOffset); | |
} | |
toString() { | |
return "HeapSnapshotEdge: " + this.name(); | |
} | |
type() { | |
return this.snapshot.edgeTypes[this.rawType()]; | |
} | |
itemIndex() { | |
return this.edgeIndex; | |
} | |
serialize() { | |
return new e.HeapSnapshotModel.Edge(this.name(), this.node().serialize(), this.type(), this.edgeIndex); | |
} | |
rawType() { | |
if (void 0 === this.snapshot.edgeTypeOffset) throw new Error("edgeTypeOffset is undefined"); | |
return this.edges.getValue(this.edgeIndex + this.snapshot.edgeTypeOffset); | |
} | |
isInternal() { | |
throw new Error("Not implemented"); | |
} | |
isInvisible() { | |
throw new Error("Not implemented"); | |
} | |
isWeak() { | |
throw new Error("Not implemented"); | |
} | |
getValueForSorting(e) { | |
throw new Error("Not implemented"); | |
} | |
nameIndex() { | |
throw new Error("Not implemented"); | |
} | |
} | |
class l { | |
#f; | |
constructor(e) { | |
this.#f = e.createNode(); | |
} | |
itemForIndex(e) { | |
return (this.#f.nodeIndex = e), this.#f; | |
} | |
} | |
class c { | |
#I; | |
constructor(e) { | |
this.#I = e.createEdge(0); | |
} | |
itemForIndex(e) { | |
return (this.#I.edgeIndex = e), this.#I; | |
} | |
} | |
class u { | |
#x; | |
constructor(e) { | |
this.#x = e.createRetainingEdge(0); | |
} | |
itemForIndex(e) { | |
return this.#x.setRetainerIndex(e), this.#x; | |
} | |
} | |
class g { | |
#m; | |
edge; | |
constructor(e) { | |
(this.#m = e), (this.edge = e.snapshot.createEdge(e.edgeIndexesStart())); | |
} | |
hasNext() { | |
return this.edge.edgeIndex < this.#m.edgeIndexesEnd(); | |
} | |
item() { | |
return this.edge; | |
} | |
next() { | |
if (void 0 === this.edge.snapshot.edgeFieldsCount) throw new Error("edgeFieldsCount is undefined"); | |
this.edge.edgeIndex += this.edge.snapshot.edgeFieldsCount; | |
} | |
} | |
class p { | |
snapshot; | |
#N; | |
#y; | |
#S; | |
#w; | |
#T; | |
constructor(e, t) { | |
(this.snapshot = e), this.setRetainerIndex(t); | |
} | |
clone() { | |
return new p(this.snapshot, this.retainerIndex()); | |
} | |
hasStringName() { | |
return this.edge().hasStringName(); | |
} | |
name() { | |
return this.edge().name(); | |
} | |
nameIndex() { | |
return this.edge().nameIndex(); | |
} | |
node() { | |
return this.nodeInternal(); | |
} | |
nodeIndex() { | |
if (void 0 === this.#S) throw new Error("retainingNodeIndex is undefined"); | |
return this.#S; | |
} | |
retainerIndex() { | |
return this.#N; | |
} | |
setRetainerIndex(e) { | |
if (e !== this.#N) { | |
if (!this.snapshot.retainingEdges || !this.snapshot.retainingNodes) throw new Error("Snapshot does not contain retaining edges or retaining nodes"); | |
(this.#N = e), (this.#y = this.snapshot.retainingEdges[e]), (this.#S = this.snapshot.retainingNodes[e]), (this.#w = null), (this.#T = null); | |
} | |
} | |
set edgeIndex(e) { | |
this.setRetainerIndex(e); | |
} | |
nodeInternal() { | |
return this.#T || (this.#T = this.snapshot.createNode(this.#S)), this.#T; | |
} | |
edge() { | |
return this.#w || (this.#w = this.snapshot.createEdge(this.#y)), this.#w; | |
} | |
toString() { | |
return this.edge().toString(); | |
} | |
itemIndex() { | |
return this.#N; | |
} | |
serialize() { | |
const t = this.node(), | |
s = t.serialize(); | |
return (s.distance = this.#O()), (s.ignored = this.snapshot.isNodeIgnoredInRetainersView(t.nodeIndex)), new e.HeapSnapshotModel.Edge(this.name(), s, this.type(), this.#y); | |
} | |
type() { | |
return this.edge().type(); | |
} | |
isInternal() { | |
return this.edge().isInternal(); | |
} | |
getValueForSorting(e) { | |
if ("!edgeDistance" === e) return this.#O(); | |
throw new Error("Invalid field name"); | |
} | |
#O() { | |
return this.snapshot.isEdgeIgnoredInRetainersView(this.#y) ? e.HeapSnapshotModel.baseUnreachableDistance : this.node().distanceForRetainersView(); | |
} | |
} | |
class f { | |
#C; | |
retainer; | |
constructor(e) { | |
const t = e.snapshot, | |
s = e.ordinal(); | |
if (!t.firstRetainerIndex) throw new Error("Snapshot does not contain firstRetainerIndex"); | |
const n = t.firstRetainerIndex[s]; | |
(this.#C = t.firstRetainerIndex[s + 1]), (this.retainer = t.createRetainingEdge(n)); | |
} | |
hasNext() { | |
return this.retainer.retainerIndex() < this.#C; | |
} | |
item() { | |
return this.retainer; | |
} | |
next() { | |
this.retainer.setRetainerIndex(this.retainer.retainerIndex() + 1); | |
} | |
} | |
class I { | |
snapshot; | |
nodeIndex; | |
constructor(e, t) { | |
(this.snapshot = e), (this.nodeIndex = t || 0); | |
} | |
distance() { | |
return this.snapshot.nodeDistances[this.nodeIndex / this.snapshot.nodeFieldCount]; | |
} | |
distanceForRetainersView() { | |
return this.snapshot.getDistanceForRetainersView(this.nodeIndex); | |
} | |
className() { | |
return this.snapshot.strings[this.classIndex()]; | |
} | |
classIndex() { | |
return this.#E() >>> T; | |
} | |
setClassIndex(e) { | |
let t = this.#E(); | |
if (((t &= w), (t |= e << T), this.#F(t), this.classIndex() !== e)) throw new Error("String index overflow"); | |
} | |
dominatorIndex() { | |
const e = this.snapshot.nodeFieldCount; | |
return this.snapshot.dominatorsTree[this.nodeIndex / this.snapshot.nodeFieldCount] * e; | |
} | |
edges() { | |
return new g(this); | |
} | |
edgesCount() { | |
return (this.edgeIndexesEnd() - this.edgeIndexesStart()) / this.snapshot.edgeFieldsCount; | |
} | |
id() { | |
throw new Error("Not implemented"); | |
} | |
rawName() { | |
return this.snapshot.strings[this.nameInternal()]; | |
} | |
isRoot() { | |
return this.nodeIndex === this.snapshot.rootNodeIndex; | |
} | |
isUserRoot() { | |
throw new Error("Not implemented"); | |
} | |
isHidden() { | |
throw new Error("Not implemented"); | |
} | |
isArray() { | |
throw new Error("Not implemented"); | |
} | |
isSynthetic() { | |
throw new Error("Not implemented"); | |
} | |
isDocumentDOMTreesRoot() { | |
throw new Error("Not implemented"); | |
} | |
name() { | |
return this.rawName(); | |
} | |
retainedSize() { | |
return this.snapshot.retainedSizes[this.ordinal()]; | |
} | |
retainers() { | |
return new f(this); | |
} | |
retainersCount() { | |
const e = this.snapshot, | |
t = this.ordinal(); | |
return e.firstRetainerIndex[t + 1] - e.firstRetainerIndex[t]; | |
} | |
selfSize() { | |
const e = this.snapshot; | |
return e.nodes.getValue(this.nodeIndex + e.nodeSelfSizeOffset); | |
} | |
type() { | |
return this.snapshot.nodeTypes[this.rawType()]; | |
} | |
traceNodeId() { | |
const e = this.snapshot; | |
return e.nodes.getValue(this.nodeIndex + e.nodeTraceNodeIdOffset); | |
} | |
itemIndex() { | |
return this.nodeIndex; | |
} | |
serialize() { | |
return new e.HeapSnapshotModel.Node(this.id(), this.name(), this.distance(), this.nodeIndex, this.retainedSize(), this.selfSize(), this.type()); | |
} | |
nameInternal() { | |
const e = this.snapshot; | |
return e.nodes.getValue(this.nodeIndex + e.nodeNameOffset); | |
} | |
edgeIndexesStart() { | |
return this.snapshot.firstEdgeIndexes[this.ordinal()]; | |
} | |
edgeIndexesEnd() { | |
return this.snapshot.firstEdgeIndexes[this.ordinal() + 1]; | |
} | |
ordinal() { | |
return this.nodeIndex / this.snapshot.nodeFieldCount; | |
} | |
nextNodeIndex() { | |
return this.nodeIndex + this.snapshot.nodeFieldCount; | |
} | |
rawType() { | |
const e = this.snapshot; | |
return e.nodes.getValue(this.nodeIndex + e.nodeTypeOffset); | |
} | |
isFlatConsString() { | |
if (this.rawType() !== this.snapshot.nodeConsStringType) return !1; | |
for (let e = this.edges(); e.hasNext(); e.next()) { | |
const t = e.edge; | |
if (!t.isInternal()) continue; | |
const s = t.name(); | |
if (("first" === s || "second" === s) && "" === t.node().name()) return !0; | |
} | |
return !1; | |
} | |
#E() { | |
const { snapshot: e, nodeIndex: t } = this, | |
s = e.nodeDetachednessAndClassIndexOffset; | |
return -1 !== s ? e.nodes.getValue(t + s) : e.detachednessAndClassIndexArray[t / e.nodeFieldCount]; | |
} | |
#F(e) { | |
const { snapshot: t, nodeIndex: s } = this, | |
n = t.nodeDetachednessAndClassIndexOffset; | |
-1 !== n ? t.nodes.setValue(s + n, e) : (t.detachednessAndClassIndexArray[s / t.nodeFieldCount] = e); | |
} | |
detachedness() { | |
return this.#E() & w; | |
} | |
setDetachedness(e) { | |
let t = this.#E(); | |
(t &= ~w), (t |= e), this.#F(t); | |
} | |
} | |
class x { | |
node; | |
#b; | |
constructor(e) { | |
(this.node = e), (this.#b = e.snapshot.nodes.length); | |
} | |
hasNext() { | |
return this.node.nodeIndex < this.#b; | |
} | |
item() { | |
return this.node; | |
} | |
next() { | |
this.node.nodeIndex = this.node.nextNodeIndex(); | |
} | |
} | |
class m { | |
#A; | |
#v; | |
#_; | |
constructor(e, t) { | |
(this.#A = e), (this.#v = t), (this.#_ = 0); | |
} | |
hasNext() { | |
return this.#_ < this.#v.length; | |
} | |
item() { | |
const e = this.#v[this.#_]; | |
return this.#A.itemForIndex(e); | |
} | |
next() { | |
++this.#_; | |
} | |
} | |
class N { | |
#z; | |
#D; | |
constructor(e, t) { | |
(this.#z = e), (this.#D = t), this.skipFilteredItems(); | |
} | |
hasNext() { | |
return this.#z.hasNext(); | |
} | |
item() { | |
return this.#z.item(); | |
} | |
next() { | |
this.#z.next(), this.skipFilteredItems(); | |
} | |
skipFilteredItems() { | |
for (; this.#z.hasNext() && this.#D && !this.#D(this.#z.item()); ) this.#z.next(); | |
} | |
} | |
class y { | |
#R; | |
constructor(e) { | |
this.#R = e; | |
} | |
updateStatus(e) { | |
this.sendUpdateEvent(t.i18n.serializeUIString(e)); | |
} | |
updateProgress(e, s, n) { | |
const i = (100 * (n ? s / n : 0)).toFixed(0); | |
this.sendUpdateEvent(t.i18n.serializeUIString(e, { PH1: i })); | |
} | |
reportProblem(t) { | |
this.#R && this.#R.sendEvent(e.HeapSnapshotModel.HeapSnapshotProgressEvent.BrokenSnapshot, t); | |
} | |
sendUpdateEvent(t) { | |
this.#R && this.#R.sendEvent(e.HeapSnapshotModel.HeapSnapshotProgressEvent.Update, t); | |
} | |
} | |
class S { | |
#V; | |
constructor(e) { | |
this.#V = [e]; | |
} | |
addError(e) { | |
this.#V.length > 100 || this.#V.push(e); | |
} | |
toString() { | |
return this.#V.join("\n "); | |
} | |
} | |
const w = 3, | |
T = 2; | |
class O { | |
nodes; | |
containmentEdges; | |
#k; | |
#j; | |
#H; | |
strings; | |
#P; | |
#M; | |
#U; | |
rootNodeIndexInternal; | |
#B; | |
#L; | |
#W; | |
#J; | |
#Q; | |
nodeTypeOffset; | |
nodeNameOffset; | |
nodeIdOffset; | |
nodeSelfSizeOffset; | |
#$; | |
nodeTraceNodeIdOffset; | |
nodeFieldCount; | |
nodeTypes; | |
nodeArrayType; | |
nodeHiddenType; | |
nodeObjectType; | |
nodeNativeType; | |
nodeStringType; | |
nodeConsStringType; | |
nodeSlicedStringType; | |
nodeCodeType; | |
nodeSyntheticType; | |
nodeClosureType; | |
nodeRegExpType; | |
edgeFieldsCount; | |
edgeTypeOffset; | |
edgeNameOffset; | |
edgeToNodeOffset; | |
edgeTypes; | |
edgeElementType; | |
edgeHiddenType; | |
edgeInternalType; | |
edgeShortcutType; | |
edgeWeakType; | |
edgeInvisibleType; | |
edgePropertyType; | |
#q; | |
#G; | |
#K; | |
#X; | |
#Y; | |
nodeCount; | |
#Z; | |
retainedSizes; | |
firstEdgeIndexes; | |
retainingNodes; | |
retainingEdges; | |
firstRetainerIndex; | |
nodeDistances; | |
firstDominatedNodeIndex; | |
dominatedNodes; | |
dominatorsTree; | |
#ee; | |
nodeDetachednessAndClassIndexOffset; | |
#te; | |
lazyStringCache; | |
#se; | |
#ne; | |
#ie; | |
#oe; | |
detachednessAndClassIndexArray; | |
constructor(e, t) { | |
(this.nodes = e.nodes), | |
(this.containmentEdges = e.edges), | |
(this.#k = e.snapshot.meta), | |
(this.#j = e.samples), | |
(this.#H = null), | |
(this.strings = e.strings), | |
(this.#P = e.locations), | |
(this.#M = t), | |
(this.#U = -5), | |
(this.rootNodeIndexInternal = 0), | |
e.snapshot.root_index && (this.rootNodeIndexInternal = e.snapshot.root_index), | |
(this.#B = {}), | |
(this.#W = {}), | |
(this.#J = {}), | |
(this.#Q = e), | |
(this.#se = new Set()), | |
(this.#ne = new Set()), | |
(this.#oe = s.TypedArrayUtilities.createBitVector(this.strings.length)); | |
} | |
initialize() { | |
const e = this.#k; | |
(this.nodeTypeOffset = e.node_fields.indexOf("type")), | |
(this.nodeNameOffset = e.node_fields.indexOf("name")), | |
(this.nodeIdOffset = e.node_fields.indexOf("id")), | |
(this.nodeSelfSizeOffset = e.node_fields.indexOf("self_size")), | |
(this.#$ = e.node_fields.indexOf("edge_count")), | |
(this.nodeTraceNodeIdOffset = e.node_fields.indexOf("trace_node_id")), | |
(this.nodeDetachednessAndClassIndexOffset = e.node_fields.indexOf("detachedness")), | |
(this.nodeFieldCount = e.node_fields.length), | |
(this.nodeTypes = e.node_types[this.nodeTypeOffset]), | |
(this.nodeArrayType = this.nodeTypes.indexOf("array")), | |
(this.nodeHiddenType = this.nodeTypes.indexOf("hidden")), | |
(this.nodeObjectType = this.nodeTypes.indexOf("object")), | |
(this.nodeNativeType = this.nodeTypes.indexOf("native")), | |
(this.nodeStringType = this.nodeTypes.indexOf("string")), | |
(this.nodeConsStringType = this.nodeTypes.indexOf("concatenated string")), | |
(this.nodeSlicedStringType = this.nodeTypes.indexOf("sliced string")), | |
(this.nodeCodeType = this.nodeTypes.indexOf("code")), | |
(this.nodeSyntheticType = this.nodeTypes.indexOf("synthetic")), | |
(this.nodeClosureType = this.nodeTypes.indexOf("closure")), | |
(this.nodeRegExpType = this.nodeTypes.indexOf("regexp")), | |
(this.edgeFieldsCount = e.edge_fields.length), | |
(this.edgeTypeOffset = e.edge_fields.indexOf("type")), | |
(this.edgeNameOffset = e.edge_fields.indexOf("name_or_index")), | |
(this.edgeToNodeOffset = e.edge_fields.indexOf("to_node")), | |
(this.edgeTypes = e.edge_types[this.edgeTypeOffset]), | |
this.edgeTypes.push("invisible"), | |
(this.edgeElementType = this.edgeTypes.indexOf("element")), | |
(this.edgeHiddenType = this.edgeTypes.indexOf("hidden")), | |
(this.edgeInternalType = this.edgeTypes.indexOf("internal")), | |
(this.edgeShortcutType = this.edgeTypes.indexOf("shortcut")), | |
(this.edgeWeakType = this.edgeTypes.indexOf("weak")), | |
(this.edgeInvisibleType = this.edgeTypes.indexOf("invisible")), | |
(this.edgePropertyType = this.edgeTypes.indexOf("property")); | |
const t = e.location_fields || []; | |
(this.#q = t.indexOf("object_index")), | |
(this.#G = t.indexOf("script_id")), | |
(this.#K = t.indexOf("line")), | |
(this.#X = t.indexOf("column")), | |
(this.#Y = t.length), | |
(this.nodeCount = this.nodes.length / this.nodeFieldCount), | |
(this.#Z = this.containmentEdges.length / this.edgeFieldsCount), | |
(this.retainedSizes = new Float64Array(this.nodeCount)), | |
(this.firstEdgeIndexes = new Uint32Array(this.nodeCount + 1)), | |
(this.retainingNodes = new Uint32Array(this.#Z)), | |
(this.retainingEdges = new Uint32Array(this.#Z)), | |
(this.firstRetainerIndex = new Uint32Array(this.nodeCount + 1)), | |
(this.nodeDistances = new Int32Array(this.nodeCount)), | |
(this.firstDominatedNodeIndex = new Uint32Array(this.nodeCount + 1)), | |
(this.dominatedNodes = new Uint32Array(this.nodeCount - 1)), | |
this.#M.updateStatus("Building edge indexes…"), | |
this.buildEdgeIndexes(), | |
this.#M.updateStatus("Building retainers…"), | |
this.buildRetainers(), | |
this.#M.updateStatus("Propagating DOM state…"), | |
this.propagateDOMState(), | |
this.#M.updateStatus("Calculating node flags…"), | |
this.calculateFlags(), | |
this.#M.updateStatus("Calculating distances…"), | |
this.calculateDistances(!1), | |
this.#M.updateStatus("Building postorder index…"); | |
const s = this.buildPostOrderIndex(); | |
if ( | |
(this.#M.updateStatus("Building dominator tree…"), | |
(this.dominatorsTree = this.buildDominatorTree(s.postOrderIndex2NodeOrdinal, s.nodeOrdinal2PostOrderIndex)), | |
this.#M.updateStatus("Calculating shallow sizes…"), | |
this.calculateShallowSizes(), | |
this.#M.updateStatus("Calculating retained sizes…"), | |
this.calculateRetainedSizes(s.postOrderIndex2NodeOrdinal), | |
this.#M.updateStatus("Building dominated nodes…"), | |
this.buildDominatedNodes(), | |
this.#M.updateStatus("Calculating object names…"), | |
this.calculateObjectNames(), | |
this.#M.updateStatus("Calculating statistics…"), | |
this.calculateStatistics(), | |
this.#M.updateStatus("Calculating samples…"), | |
this.buildSamples(), | |
this.#M.updateStatus("Building locations…"), | |
this.buildLocationMap(), | |
this.#M.updateStatus("Finished processing."), | |
this.#Q.snapshot.trace_function_count) | |
) { | |
this.#M.updateStatus("Building allocation statistics…"); | |
const e = this.nodes.length, | |
t = this.nodeFieldCount, | |
s = this.rootNode(), | |
n = {}; | |
for (let i = 0; i < e; i += t) { | |
s.nodeIndex = i; | |
const e = s.traceNodeId(); | |
let t = n[e]; | |
t || (n[e] = t = { count: 0, size: 0, ids: [] }), t.count++, (t.size += s.selfSize()), t.ids.push(s.id()); | |
} | |
(this.#ee = new i(this.#Q, n)), this.#M.updateStatus("done"); | |
} | |
} | |
buildEdgeIndexes() { | |
const e = this.nodes, | |
t = this.nodeCount, | |
s = this.firstEdgeIndexes, | |
n = this.nodeFieldCount, | |
i = this.edgeFieldsCount, | |
o = this.#$; | |
s[t] = this.containmentEdges.length; | |
for (let r = 0, a = 0; r < t; ++r) (s[r] = a), (a += e.getValue(r * n + o) * i); | |
} | |
buildRetainers() { | |
const e = this.retainingNodes, | |
t = this.retainingEdges, | |
s = this.firstRetainerIndex, | |
n = this.containmentEdges, | |
i = this.edgeFieldsCount, | |
o = this.nodeFieldCount, | |
r = this.edgeToNodeOffset, | |
a = this.firstEdgeIndexes, | |
d = this.nodeCount; | |
for (let e = r, t = n.length; e < t; e += i) { | |
const t = n.getValue(e); | |
if (t % o) throw new Error("Invalid toNodeIndex " + t); | |
++s[t / o]; | |
} | |
for (let t = 0, n = 0; t < d; t++) { | |
const i = s[t]; | |
(s[t] = n), (e[n] = i), (n += i); | |
} | |
s[d] = e.length; | |
let h = a[0]; | |
for (let l = 0; l < d; ++l) { | |
const d = h; | |
h = a[l + 1]; | |
const c = l * o; | |
for (let a = d; a < h; a += i) { | |
const i = n.getValue(a + r); | |
if (i % o) throw new Error("Invalid toNodeIndex " + i); | |
const d = s[i / o], | |
h = d + --e[d]; | |
(e[h] = c), (t[h] = a); | |
} | |
} | |
} | |
allNodes() { | |
return new x(this.rootNode()); | |
} | |
rootNode() { | |
return this.createNode(this.rootNodeIndexInternal); | |
} | |
get rootNodeIndex() { | |
return this.rootNodeIndexInternal; | |
} | |
get totalSize() { | |
return this.rootNode().retainedSize(); | |
} | |
getDominatedIndex(e) { | |
if (e % this.nodeFieldCount) throw new Error("Invalid nodeIndex: " + e); | |
return this.firstDominatedNodeIndex[e / this.nodeFieldCount]; | |
} | |
createFilter(e) { | |
const { minNodeId: t, maxNodeId: s, allocationNodeId: n, filterName: i } = e; | |
let o; | |
if ("number" == typeof n) { | |
if (((o = this.createAllocationStackFilter(n)), !o)) throw new Error("Unable to create filter"); | |
o.key = "AllocationNodeId: " + n; | |
} else "number" == typeof t && "number" == typeof s ? ((o = this.createNodeIdFilter(t, s)), (o.key = "NodeIdRange: " + t + ".." + s)) : void 0 !== i && ((o = this.createNamedFilter(i)), (o.key = "NamedFilter: " + i)); | |
return o; | |
} | |
search(e, t) { | |
const n = e.query; | |
const i = e.isRegex ? new RegExp(n) : s.StringUtilities.createPlainTextSearchRegex(n, "i"); | |
const o = | |
e.isRegex || !e.caseSensitive | |
? function (e, t, s) { | |
return i.test(t) && e.add(s), e; | |
} | |
: function (e, t, s) { | |
return -1 !== t.indexOf(n) && e.add(s), e; | |
}, | |
r = this.strings.reduce(o, new Set()); | |
if (!r.size) return []; | |
const a = this.createFilter(t), | |
d = [], | |
h = this.nodes.length, | |
l = this.nodes, | |
c = this.nodeNameOffset, | |
u = this.nodeIdOffset, | |
g = this.nodeFieldCount, | |
p = this.rootNode(); | |
for (let e = 0; e < h; e += g) (p.nodeIndex = e), (a && !a(p)) || (r.has(l.getValue(e + c)) && d.push(l.getValue(e + u))); | |
return d; | |
} | |
aggregatesWithFilter(e) { | |
const t = this.createFilter(e), | |
s = t ? t.key : "allObjects"; | |
return this.getAggregatesByClassName(!1, s, t); | |
} | |
createNodeIdFilter(e, t) { | |
return function (s) { | |
const n = s.id(); | |
return n > e && n <= t; | |
}; | |
} | |
createAllocationStackFilter(e) { | |
if (!this.#ee) throw new Error("No Allocation Profile provided"); | |
const t = this.#ee.traceIds(e); | |
if (!t.length) return; | |
const s = {}; | |
for (let e = 0; e < t.length; e++) s[t[e]] = !0; | |
return function (e) { | |
return Boolean(s[e.traceNodeId()]); | |
}; | |
} | |
createNamedFilter(e) { | |
const t = s.TypedArrayUtilities.createBitVector(this.nodeCount), | |
n = (e) => { | |
const s = e.nodeIndex / this.nodeFieldCount; | |
return t.getBit(s); | |
}, | |
i = (e) => { | |
const s = new Int32Array(this.nodeCount); | |
for (let e = 0; e < this.nodeCount; ++e) s[e] = this.#U; | |
const n = new Uint32Array(this.nodeCount); | |
(s[this.rootNode().ordinal()] = 0), (n[0] = this.rootNode().nodeIndex); | |
this.bfs(n, 1, s, e); | |
for (let e = 0; e < this.nodeCount; ++e) s[e] !== this.#U && t.setBit(e); | |
}, | |
o = () => { | |
for (let e = 0; e < this.nodeCount; ++e) this.nodeDistances[e] === this.#U && t.setBit(e); | |
}; | |
switch (e) { | |
case "objectsRetainedByDetachedDomNodes": | |
return i((e, t) => 2 !== t.node().detachedness()), o(), (e) => !n(e); | |
case "objectsRetainedByConsole": | |
return i((e, t) => !(e.isSynthetic() && t.hasStringName() && t.name().endsWith(" / DevTools console"))), o(), (e) => !n(e); | |
case "duplicatedStrings": { | |
const e = new Map(), | |
s = this.createNode(0); | |
for (let n = 0; n < this.nodeCount; ++n) { | |
s.nodeIndex = n * this.nodeFieldCount; | |
const i = s.rawType(); | |
if (i === this.nodeStringType || i === this.nodeConsStringType) { | |
if (s.isFlatConsString()) continue; | |
const n = s.name(), | |
i = e.get(n); | |
void 0 === i ? e.set(n, s.nodeIndex) : (t.setBit(i / this.nodeFieldCount), t.setBit(s.nodeIndex / this.nodeFieldCount)); | |
} | |
} | |
return n; | |
} | |
} | |
throw new Error("Invalid filter name"); | |
} | |
getAggregatesByClassName(e, t, s) { | |
const n = this.buildAggregates(s); | |
let i; | |
return ( | |
t && this.#W[t] ? (i = this.#W[t]) : (this.calculateClassesRetainedSize(n.aggregatesByClassIndex, s), (i = n.aggregatesByClassName), t && (this.#W[t] = i)), | |
!e || (t && this.#J[t]) || (this.sortAggregateIndexes(i), t && (this.#J[t] = e)), | |
i | |
); | |
} | |
allocationTracesTops() { | |
return this.#ee.serializeTraceTops(); | |
} | |
allocationNodeCallers(e) { | |
return this.#ee.serializeCallers(e); | |
} | |
allocationStack(e) { | |
const t = this.createNode(e).traceNodeId(); | |
return t ? this.#ee.serializeAllocationStack(t) : null; | |
} | |
aggregatesForDiff() { | |
if (this.#L) return this.#L; | |
const e = this.getAggregatesByClassName(!0, "allObjects"); | |
this.#L = {}; | |
const t = this.createNode(); | |
for (const s in e) { | |
const n = e[s].idxs, | |
i = new Array(n.length), | |
o = new Array(n.length); | |
for (let e = 0; e < n.length; e++) (t.nodeIndex = n[e]), (i[e] = t.id()), (o[e] = t.selfSize()); | |
this.#L[s] = { indexes: n, ids: i, selfSizes: o }; | |
} | |
return this.#L; | |
} | |
isUserRoot(e) { | |
return !0; | |
} | |
calculateShallowSizes() {} | |
calculateDistances(t, s) { | |
const n = this.nodeCount; | |
if (t) { | |
const e = s; | |
(s = (t, s) => !this.#se.has(s.nodeIndex()) && (!e || e(t, s))), void 0 === this.#ie && (this.#ie = new Int32Array(n)); | |
} | |
const i = t ? this.#ie : this.nodeDistances, | |
o = this.#U; | |
for (let e = 0; e < n; ++e) i[e] = o; | |
const r = new Uint32Array(this.nodeCount); | |
let a = 0; | |
for (let e = this.rootNode().edges(); e.hasNext(); e.next()) { | |
const t = e.edge.node(); | |
this.isUserRoot(t) && ((i[t.ordinal()] = 1), (r[a++] = t.nodeIndex)); | |
} | |
this.bfs(r, a, i, s), (i[this.rootNode().ordinal()] = a > 0 ? e.HeapSnapshotModel.baseSystemDistance : 0), (r[0] = this.rootNode().nodeIndex), (a = 1), this.bfs(r, a, i, s); | |
} | |
bfs(e, t, s, n) { | |
const i = this.edgeFieldsCount, | |
o = this.nodeFieldCount, | |
r = this.containmentEdges, | |
a = this.firstEdgeIndexes, | |
d = this.edgeToNodeOffset, | |
h = this.edgeTypeOffset, | |
l = this.nodeCount, | |
c = this.edgeWeakType, | |
u = this.#U; | |
let g = 0; | |
const p = this.createEdge(0), | |
f = this.createNode(0); | |
for (; g < t; ) { | |
const l = e[g++], | |
I = l / o, | |
x = s[I] + 1, | |
m = a[I], | |
N = a[I + 1]; | |
f.nodeIndex = l; | |
for (let a = m; a < N; a += i) { | |
if (r.getValue(a + h) === c) continue; | |
const i = r.getValue(a + d), | |
l = i / o; | |
s[l] === u && ((p.edgeIndex = a), (n && !n(f, p)) || ((s[l] = x), (e[t++] = i))); | |
} | |
} | |
if (t > l) throw new Error("BFS failed. Nodes to visit (" + t + ") is more than nodes count (" + l + ")"); | |
} | |
buildAggregates(e) { | |
const t = {}, | |
s = {}, | |
n = [], | |
i = this.nodes, | |
o = i.length, | |
r = this.nodeFieldCount, | |
a = this.nodeSelfSizeOffset, | |
d = this.rootNode(), | |
h = this.nodeDistances; | |
for (let l = 0; l < o; l += r) { | |
if (((d.nodeIndex = l), e && !e(d))) continue; | |
const o = i.getValue(l + a); | |
if (!o) continue; | |
const c = d.classIndex(), | |
u = h[l / r]; | |
if (c in t) { | |
const e = t[c]; | |
if (!e) continue; | |
(e.distance = Math.min(e.distance, u)), ++e.count, (e.self += o), e.idxs.push(l); | |
} else { | |
const e = d.type(), | |
i = { count: 1, distance: u, self: o, maxRet: 0, type: e, name: "object" === e || "native" === e ? d.className() : null, idxs: [l] }; | |
(t[c] = i), n.push(c), (s[d.className()] = i); | |
} | |
} | |
for (let e = 0, s = n.length; e < s; ++e) { | |
const s = t[n[e]]; | |
s && (s.idxs = s.idxs.slice()); | |
} | |
return { aggregatesByClassName: s, aggregatesByClassIndex: t }; | |
} | |
calculateClassesRetainedSize(e, t) { | |
const s = this.rootNodeIndexInternal, | |
n = this.createNode(s), | |
i = [s], | |
o = [-1], | |
r = [], | |
a = new Map(), | |
d = this.nodeFieldCount, | |
h = this.dominatedNodes, | |
l = this.firstDominatedNodeIndex; | |
for (; i.length; ) { | |
const s = i.pop(); | |
n.nodeIndex = s; | |
let c = n.classIndex(); | |
const u = Boolean(a.get(c)), | |
g = s / d, | |
p = l[g], | |
f = l[g + 1]; | |
u || (t && !t(n)) || !n.selfSize() || ((e[c].maxRet += n.retainedSize()), p !== f && (a.set(c, !0), o.push(i.length), r.push(c))); | |
for (let e = p; e < f; e++) i.push(h[e]); | |
const I = i.length; | |
for (; o[o.length - 1] === I; ) o.pop(), (c = r.pop()), a.set(c, !1); | |
} | |
} | |
sortAggregateIndexes(e) { | |
const t = this.createNode(), | |
s = this.createNode(); | |
for (const n in e) e[n].idxs.sort((e, n) => ((t.nodeIndex = e), (s.nodeIndex = n), t.id() < s.id() ? -1 : 1)); | |
} | |
tryParseWeakMapEdgeName(e) { | |
if (this.#oe.getBit(e)) return; | |
const t = this.strings[e].match(/^\d+(?<duplicatedPart> \/ part of key \(.*? @\d+\) -> value \(.*? @\d+\) pair in WeakMap \(table @(?<tableId>\d+)\))$/); | |
if (t) return t.groups; | |
this.#oe.setBit(e); | |
} | |
isEssentialEdge(e, t) { | |
const s = this.containmentEdges.getValue(t + this.edgeTypeOffset); | |
if (s === this.edgeInternalType) { | |
const s = this.containmentEdges.getValue(t + this.edgeNameOffset), | |
n = this.tryParseWeakMapEdgeName(s); | |
if (n) { | |
return this.nodes.getValue(e + this.nodeIdOffset) !== parseInt(n.tableId, 10); | |
} | |
} | |
return s !== this.edgeWeakType && (s !== this.edgeShortcutType || e === this.rootNodeIndexInternal); | |
} | |
buildPostOrderIndex() { | |
const e = this.nodeFieldCount, | |
t = this.nodeCount, | |
s = this.rootNodeIndexInternal / e, | |
n = this.edgeFieldsCount, | |
i = this.edgeToNodeOffset, | |
o = this.firstEdgeIndexes, | |
r = this.containmentEdges, | |
a = this.userObjectsMapAndFlag(), | |
d = a ? a.map : null, | |
h = a ? a.flag : 0, | |
l = new Uint32Array(t), | |
c = new Uint32Array(t), | |
u = new Uint32Array(t), | |
g = new Uint32Array(t), | |
p = new Uint8Array(t); | |
let f = 0, | |
I = 0; | |
(l[0] = s), (c[0] = o[s]), (p[s] = 1); | |
let x = 0; | |
for (;;) { | |
for (++x; I >= 0; ) { | |
const t = l[I], | |
a = c[I]; | |
if (a < o[t + 1]) { | |
if (((c[I] += n), !this.isEssentialEdge(t * e, a))) continue; | |
const u = r.getValue(a + i) / e; | |
if (p[u]) continue; | |
const g = !d || d[t] & h, | |
f = !d || d[u] & h; | |
if (t !== s && f && !g) continue; | |
++I, (l[I] = u), (c[I] = o[u]), (p[u] = 1); | |
} else (g[t] = f), (u[f++] = t), --I; | |
} | |
if (f === t || x > 1) break; | |
const a = new S(`Heap snapshot: ${t - f} nodes are unreachable from the root. Following nodes have only weak retainers:`), | |
m = this.rootNode(); | |
--f, (I = 0), (l[0] = s), (c[0] = o[s + 1]); | |
for (let s = 0; s < t; ++s) { | |
if (p[s] || !this.hasOnlyWeakRetainers(s)) continue; | |
(l[++I] = s), (c[I] = o[s]), (p[s] = 1), (m.nodeIndex = s * e); | |
const t = []; | |
for (let e = m.retainers(); e.hasNext(); e.next()) t.push(`${e.item().node().name()}@${e.item().node().id()}.${e.item().name()}`); | |
a.addError(`${m.name()} @${m.id()} weak retainers: ${t.join(", ")}`); | |
} | |
console.warn(a.toString()); | |
} | |
if (f !== t) { | |
const n = new S("Still found " + (t - f) + " unreachable nodes in heap snapshot:"), | |
i = this.rootNode(); | |
--f; | |
for (let s = 0; s < t; ++s) p[s] || ((i.nodeIndex = s * e), n.addError(i.name() + " @" + i.id()), (g[s] = f), (u[f++] = s)); | |
(g[s] = f), (u[f++] = s), console.warn(n.toString()); | |
} | |
return { postOrderIndex2NodeOrdinal: u, nodeOrdinal2PostOrderIndex: g }; | |
} | |
hasOnlyWeakRetainers(e) { | |
const t = this.edgeTypeOffset, | |
s = this.edgeWeakType, | |
n = this.edgeShortcutType, | |
i = this.containmentEdges, | |
o = this.retainingEdges, | |
r = this.firstRetainerIndex[e], | |
a = this.firstRetainerIndex[e + 1]; | |
for (let e = r; e < a; ++e) { | |
const r = o[e], | |
a = i.getValue(r + t); | |
if (a !== s && a !== n) return !1; | |
} | |
return !0; | |
} | |
buildDominatorTree(e, t) { | |
const n = this.nodeFieldCount, | |
i = this.firstRetainerIndex, | |
o = this.retainingNodes, | |
r = this.retainingEdges, | |
a = this.edgeFieldsCount, | |
d = this.edgeToNodeOffset, | |
h = this.firstEdgeIndexes, | |
l = this.containmentEdges, | |
c = this.rootNodeIndexInternal, | |
u = this.userObjectsMapAndFlag(), | |
g = u ? u.map : null, | |
p = u ? u.flag : 0, | |
f = e.length, | |
I = f - 1, | |
x = f, | |
m = new Uint32Array(f); | |
for (let e = 0; e < I; ++e) m[e] = x; | |
m[I] = I; | |
const N = s.TypedArrayUtilities.createBitVector(f); | |
let y; | |
{ | |
y = this.rootNodeIndexInternal / n; | |
const e = h[y + 1]; | |
for (let s = h[y]; s < e; s += a) { | |
if (!this.isEssentialEdge(this.rootNodeIndexInternal, s)) continue; | |
const e = l.getValue(s + d) / n; | |
N.setBit(t[e]); | |
} | |
} | |
let S = !0; | |
for (; S; ) { | |
S = !1; | |
for (let s = N.previous(I); s >= 0; s = N.previous(s)) { | |
if ((N.clearBit(s), m[s] === I)) continue; | |
y = e[s]; | |
const u = !g || g[y] & p; | |
let f = x; | |
const w = i[y], | |
T = i[y + 1]; | |
let O = !0; | |
for (let e = w; e < T; ++e) { | |
const s = r[e], | |
i = o[e]; | |
if (!this.isEssentialEdge(i, s)) continue; | |
O = !1; | |
const a = i / n, | |
d = !g || g[a] & p; | |
if (i !== c && u && !d) continue; | |
let h = t[a]; | |
if (m[h] !== x) { | |
if (f === x) f = h; | |
else | |
for (; h !== f; ) { | |
for (; h < f; ) h = m[h]; | |
for (; f < h; ) f = m[f]; | |
} | |
if (f === I) break; | |
} | |
} | |
if ((O && (f = I), f !== x && m[s] !== f)) { | |
(m[s] = f), (S = !0), (y = e[s]); | |
const i = h[y] + d, | |
o = h[y + 1]; | |
for (let e = i; e < o; e += a) { | |
const s = l.getValue(e) / n; | |
N.setBit(t[s]); | |
} | |
} | |
} | |
} | |
const w = new Uint32Array(f); | |
for (let t = 0, s = m.length; t < s; ++t) (y = e[t]), (w[y] = e[m[t]]); | |
return w; | |
} | |
calculateRetainedSizes(e) { | |
const t = this.nodeCount, | |
s = this.nodes, | |
n = this.nodeSelfSizeOffset, | |
i = this.nodeFieldCount, | |
o = this.dominatorsTree, | |
r = this.retainedSizes; | |
for (let e = 0; e < t; ++e) r[e] = s.getValue(e * i + n); | |
for (let s = 0; s < t - 1; ++s) { | |
const t = e[s]; | |
r[o[t]] += r[t]; | |
} | |
} | |
buildDominatedNodes() { | |
const e = this.firstDominatedNodeIndex, | |
t = this.dominatedNodes, | |
s = this.nodeFieldCount, | |
n = this.dominatorsTree; | |
let i = 0, | |
o = this.nodeCount; | |
const r = this.rootNodeIndexInternal / s; | |
if (r === i) i = 1; | |
else { | |
if (r !== o - 1) throw new Error("Root node is expected to be either first or last"); | |
o -= 1; | |
} | |
for (let t = i; t < o; ++t) ++e[n[t]]; | |
let a = 0; | |
for (let s = 0, n = this.nodeCount; s < n; ++s) { | |
const n = (t[a] = e[s]); | |
(e[s] = a), (a += n); | |
} | |
e[this.nodeCount] = t.length; | |
for (let r = i; r < o; ++r) { | |
let i = e[n[r]]; | |
(i += --t[i]), (t[i] = r * s); | |
} | |
} | |
calculateObjectNames() { | |
const { nodes: e, nodeCount: t, nodeNameOffset: s, nodeNativeType: n, nodeHiddenType: i, nodeObjectType: o, nodeCodeType: r, nodeClosureType: a, nodeRegExpType: d } = this; | |
-1 === this.nodeDetachednessAndClassIndexOffset && (this.detachednessAndClassIndexArray = new Uint32Array(t)); | |
const h = new Map(), | |
l = (e) => { | |
let t = h.get(e); | |
return void 0 === t && ((t = this.addString(e)), h.set(e, t)), t; | |
}, | |
c = l("(system)"), | |
u = l("(compiled code)"), | |
g = l("Function"), | |
p = l("RegExp"); | |
function f(t) { | |
switch (t.rawType()) { | |
case i: | |
return c; | |
case o: | |
case n: { | |
let n = t.rawName(); | |
if (n.startsWith("<")) { | |
const e = n.indexOf(" "); | |
return -1 !== e && (n = n.substring(0, e) + ">"), l(n); | |
} | |
if (n.startsWith("Detached <")) { | |
const e = n.indexOf(" ", 10); | |
return -1 !== e && (n = n.substring(0, e) + ">"), l(n); | |
} | |
return e.getValue(t.nodeIndex + s); | |
} | |
case r: | |
return u; | |
case a: | |
return g; | |
case d: | |
return p; | |
default: | |
return l("(" + t.type() + ")"); | |
} | |
} | |
const I = this.createNode(0); | |
for (let e = 0; e < t; ++e) I.setClassIndex(f(I)), (I.nodeIndex = I.nextNodeIndex()); | |
} | |
iterateFilteredChildren(e, t, s) { | |
const n = this.firstEdgeIndexes[e], | |
i = this.firstEdgeIndexes[e + 1]; | |
for (let e = n; e < i; e += this.edgeFieldsCount) { | |
const n = this.containmentEdges.getValue(e + this.edgeToNodeOffset) / this.nodeFieldCount; | |
t(this.containmentEdges.getValue(e + this.edgeTypeOffset)) && s(n); | |
} | |
} | |
addString(e) { | |
return this.strings.push(e), this.strings.length - 1; | |
} | |
propagateDOMState() { | |
if (-1 === this.nodeDetachednessAndClassIndexOffset) return; | |
console.time("propagateDOMState"); | |
const e = new Uint8Array(this.nodeCount), | |
t = [], | |
s = [], | |
n = new Map(), | |
i = this.createNode(0), | |
o = function (o, r, a) { | |
if (e[r]) return; | |
const d = r * o.nodeFieldCount; | |
o.nodes.getValue(d + o.nodeTypeOffset) === o.nodeNativeType | |
? ((i.nodeIndex = d), | |
i.setDetachedness(a), | |
1 === a | |
? t.push(r) | |
: 2 === a && | |
(!(function (e, t) { | |
const s = e.nodes.getValue(t + e.nodeNameOffset); | |
let i = n.get(s); | |
void 0 === i && ((i = e.addString("Detached " + e.strings[s])), n.set(s, i)), e.nodes.setValue(t + e.nodeNameOffset, i); | |
})(o, d), | |
s.push(r)), | |
(e[r] = 1)) | |
: (e[r] = 1); | |
}, | |
r = function (e, t, s) { | |
e.iterateFilteredChildren( | |
t, | |
(t) => ![e.edgeHiddenType, e.edgeInvisibleType, e.edgeWeakType].includes(t), | |
(t) => o(e, t, s) | |
); | |
}; | |
for (let e = 0; e < this.nodeCount; ++e) { | |
i.nodeIndex = e * this.nodeFieldCount; | |
const t = i.detachedness(); | |
0 !== t && o(this, e, t); | |
} | |
for (; 0 !== t.length; ) { | |
r(this, t.pop(), 1); | |
} | |
for (; 0 !== s.length; ) { | |
const e = s.pop(); | |
i.nodeIndex = e * this.nodeFieldCount; | |
1 !== i.detachedness() && r(this, e, 2); | |
} | |
console.timeEnd("propagateDOMState"); | |
} | |
buildSamples() { | |
const t = this.#j; | |
if (!t || !t.length) return; | |
const n = t.length / 2, | |
i = new Array(n), | |
o = new Array(n), | |
r = new Array(n), | |
a = this.#k.sample_fields.indexOf("timestamp_us"), | |
d = this.#k.sample_fields.indexOf("last_assigned_id"); | |
for (let e = 0; e < n; e++) (i[e] = 0), (o[e] = t[2 * e + a] / 1e3), (r[e] = t[2 * e + d]); | |
const h = this.nodes.length, | |
l = this.nodeFieldCount, | |
c = this.rootNode(); | |
for (let e = 0; e < h; e += l) { | |
c.nodeIndex = e; | |
const t = c.id(); | |
if (t % 2 == 0) continue; | |
const o = s.ArrayUtilities.lowerBound(r, t, s.ArrayUtilities.DEFAULT_COMPARATOR); | |
o !== n && (i[o] += c.selfSize()); | |
} | |
this.#H = new e.HeapSnapshotModel.Samples(o, r, i); | |
} | |
buildLocationMap() { | |
const t = new Map(), | |
s = this.#P; | |
for (let n = 0; n < s.length; n += this.#Y) { | |
const i = s[n + this.#q], | |
o = s[n + this.#G], | |
r = s[n + this.#K], | |
a = s[n + this.#X]; | |
t.set(i, new e.HeapSnapshotModel.Location(o, r, a)); | |
} | |
this.#te = t; | |
} | |
getLocation(e) { | |
return this.#te.get(e) || null; | |
} | |
getSamples() { | |
return this.#H; | |
} | |
calculateFlags() { | |
throw new Error("Not implemented"); | |
} | |
calculateStatistics() { | |
throw new Error("Not implemented"); | |
} | |
userObjectsMapAndFlag() { | |
throw new Error("Not implemented"); | |
} | |
calculateSnapshotDiff(t, s) { | |
let n = this.#B[t]; | |
if (n) return n; | |
n = {}; | |
const i = this.getAggregatesByClassName(!0, "allObjects"); | |
for (const e in s) { | |
const t = s[e], | |
o = this.calculateDiffForClass(t, i[e]); | |
o && (n[e] = o); | |
} | |
const o = new e.HeapSnapshotModel.AggregateForDiff(); | |
for (const e in i) { | |
if (e in s) continue; | |
const t = this.calculateDiffForClass(o, i[e]); | |
t && (n[e] = t); | |
} | |
return (this.#B[t] = n), n; | |
} | |
calculateDiffForClass(t, s) { | |
const n = t.ids, | |
i = t.indexes, | |
o = t.selfSizes, | |
r = s ? s.idxs : []; | |
let a = 0, | |
d = 0; | |
const h = n.length, | |
l = r.length, | |
c = new e.HeapSnapshotModel.Diff(), | |
u = this.createNode(r[d]); | |
for (; a < h && d < l; ) { | |
const e = n[a]; | |
e < u.id() | |
? (c.deletedIndexes.push(i[a]), c.removedCount++, (c.removedSize += o[a]), ++a) | |
: e > u.id() | |
? (c.addedIndexes.push(r[d]), c.addedCount++, (c.addedSize += u.selfSize()), (u.nodeIndex = r[++d])) | |
: (++a, (u.nodeIndex = r[++d])); | |
} | |
for (; a < h; ) c.deletedIndexes.push(i[a]), c.removedCount++, (c.removedSize += o[a]), ++a; | |
for (; d < l; ) c.addedIndexes.push(r[d]), c.addedCount++, (c.addedSize += u.selfSize()), (u.nodeIndex = r[++d]); | |
return (c.countDelta = c.addedCount - c.removedCount), (c.sizeDelta = c.addedSize - c.removedSize), c.addedCount || c.removedCount ? c : null; | |
} | |
nodeForSnapshotObjectId(e) { | |
for (let t = this.allNodes(); t.hasNext(); t.next()) if (t.node.id() === e) return t.node; | |
return null; | |
} | |
nodeClassName(e) { | |
const t = this.nodeForSnapshotObjectId(e); | |
return t ? t.className() : null; | |
} | |
idsOfObjectsWithName(e) { | |
const t = []; | |
for (let s = this.allNodes(); s.hasNext(); s.next()) s.item().name() === e && t.push(s.item().id()); | |
return t; | |
} | |
createEdgesProvider(e) { | |
const t = this.createNode(e), | |
s = this.containmentEdgesFilter(), | |
n = new c(this); | |
return new F(this, s, t.edges(), n); | |
} | |
createEdgesProviderForTest(e, t) { | |
const s = this.createNode(e), | |
n = new c(this); | |
return new F(this, t, s.edges(), n); | |
} | |
retainingEdgesFilter() { | |
return null; | |
} | |
containmentEdgesFilter() { | |
return null; | |
} | |
createRetainingEdgesProvider(e) { | |
const t = this.createNode(e), | |
s = this.retainingEdgesFilter(), | |
n = new u(this); | |
return new F(this, s, t.retainers(), n); | |
} | |
createAddedNodesProvider(e, t) { | |
const s = this.#B[e][t]; | |
return new b(this, s.addedIndexes); | |
} | |
createDeletedNodesProvider(e) { | |
return new b(this, e); | |
} | |
createNodesProviderForClass(e, t) { | |
return new b(this, this.aggregatesWithFilter(t)[e].idxs); | |
} | |
maxJsNodeId() { | |
const e = this.nodeFieldCount, | |
t = this.nodes, | |
s = t.length; | |
let n = 0; | |
for (let i = this.nodeIdOffset; i < s; i += e) { | |
const e = t.getValue(i); | |
e % 2 != 0 && n < e && (n = e); | |
} | |
return n; | |
} | |
updateStaticData() { | |
return new e.HeapSnapshotModel.StaticData(this.nodeCount, this.rootNodeIndexInternal, this.totalSize, this.maxJsNodeId()); | |
} | |
ignoreNodeInRetainersView(e) { | |
this.#se.add(e), this.calculateDistances(!0), this.#re(); | |
} | |
unignoreNodeInRetainersView(e) { | |
this.#se.delete(e), 0 === this.#se.size ? (this.#ie = void 0) : this.calculateDistances(!0), this.#re(); | |
} | |
unignoreAllNodesInRetainersView() { | |
this.#se.clear(), (this.#ie = void 0), this.#re(); | |
} | |
#re() { | |
const e = this.#ie; | |
if ((this.#ne.clear(), void 0 === e)) return; | |
const t = new s.MapUtilities.Multimap(), | |
n = this.#U, | |
{ nodeCount: i, nodeFieldCount: o } = this, | |
r = this.createNode(0); | |
for (let s = 0; s < i; ++s) | |
if (e[s] === n) { | |
r.nodeIndex = s * o; | |
for (let e = r.edges(); e.hasNext(); e.next()) { | |
const s = e.edge; | |
if (!s.isInternal()) continue; | |
const n = this.tryParseWeakMapEdgeName(s.nameIndex()); | |
n && t.set(s.nodeIndex(), n.duplicatedPart); | |
} | |
} | |
for (const e of t.keys()) { | |
r.nodeIndex = e; | |
for (let s = r.retainers(); s.hasNext(); s.next()) { | |
const n = s.item(); | |
if (!n.isInternal()) continue; | |
const i = this.tryParseWeakMapEdgeName(n.nameIndex()); | |
if (i && t.hasValue(e, i.duplicatedPart)) { | |
const e = this.retainingEdges[n.itemIndex()]; | |
this.#ne.add(e); | |
} | |
} | |
} | |
} | |
areNodesIgnoredInRetainersView() { | |
return this.#se.size > 0; | |
} | |
getDistanceForRetainersView(t) { | |
const s = t / this.nodeFieldCount, | |
n = (this.#ie ?? this.nodeDistances)[s]; | |
return n === this.#U ? Math.max(0, this.nodeDistances[s]) + e.HeapSnapshotModel.baseUnreachableDistance : n; | |
} | |
isNodeIgnoredInRetainersView(e) { | |
return this.#se.has(e); | |
} | |
isEdgeIgnoredInRetainersView(e) { | |
return this.#ne.has(e); | |
} | |
} | |
class C { | |
location_fields = []; | |
node_fields = []; | |
node_types = []; | |
edge_fields = []; | |
edge_types = []; | |
trace_function_info_fields = []; | |
trace_node_fields = []; | |
sample_fields = []; | |
type_strings = {}; | |
} | |
class E { | |
iterator; | |
#ae; | |
#de; | |
iterationOrder; | |
currentComparator; | |
#he; | |
#le; | |
constructor(e, t) { | |
(this.iterator = e), (this.#ae = t), (this.#de = !e.hasNext()), (this.iterationOrder = null), (this.currentComparator = null), (this.#he = 0), (this.#le = 0); | |
} | |
createIterationOrder() { | |
if (!this.iterationOrder) { | |
this.iterationOrder = []; | |
for (let e = this.iterator; e.hasNext(); e.next()) this.iterationOrder.push(e.item().itemIndex()); | |
} | |
} | |
isEmpty() { | |
return this.#de; | |
} | |
serializeItemsRange(t, s) { | |
if ((this.createIterationOrder(), t > s)) throw new Error("Start position > end position: " + t + " > " + s); | |
if (!this.iterationOrder) throw new Error("Iteration order undefined"); | |
if ((s > this.iterationOrder.length && (s = this.iterationOrder.length), this.#he < s && t < this.iterationOrder.length - this.#le && this.currentComparator)) { | |
const e = this.currentComparator; | |
this.sort(e, this.#he, this.iterationOrder.length - 1 - this.#le, t, s - 1), t <= this.#he && (this.#he = s), s >= this.iterationOrder.length - this.#le && (this.#le = this.iterationOrder.length - t); | |
} | |
let n = t; | |
const i = s - t, | |
o = new Array(i); | |
for (let e = 0; e < i; ++e) { | |
const t = this.iterationOrder[n++], | |
s = this.#ae.itemForIndex(t); | |
o[e] = s.serialize(); | |
} | |
return new e.HeapSnapshotModel.ItemsRange(t, s, this.iterationOrder.length, o); | |
} | |
sortAndRewind(e) { | |
(this.currentComparator = e), (this.#he = 0), (this.#le = 0); | |
} | |
} | |
class F extends E { | |
snapshot; | |
constructor(e, t, s, n) { | |
super(t ? new N(s, t) : s, n), (this.snapshot = e); | |
} | |
sort(e, t, n, i, o) { | |
const r = e.fieldName1, | |
a = e.fieldName2, | |
d = e.ascending1, | |
h = e.ascending2, | |
l = this.iterator.item().clone(), | |
c = l.clone(), | |
u = this.snapshot.createNode(), | |
g = this.snapshot.createNode(); | |
function p(e, t, s, n) { | |
(l.edgeIndex = s), (c.edgeIndex = n); | |
let i = 0; | |
if ("!edgeName" === e) { | |
if ("__proto__" === c.name()) return -1; | |
if ("__proto__" === l.name()) return 1; | |
i = l.hasStringName() === c.hasStringName() ? (l.name() < c.name() ? -1 : l.name() > c.name() ? 1 : 0) : l.hasStringName() ? -1 : 1; | |
} else i = l.getValueForSorting(e) - c.getValueForSorting(e); | |
return t ? i : -i; | |
} | |
function f(e, t, s, n) { | |
(l.edgeIndex = s), (u.nodeIndex = l.nodeIndex()); | |
const i = u[e](); | |
(c.edgeIndex = n), (g.nodeIndex = c.nodeIndex()); | |
const o = g[e](), | |
r = i < o ? -1 : i > o ? 1 : 0; | |
return t ? r : -r; | |
} | |
if (!this.iterationOrder) throw new Error("Iteration order not defined"); | |
function I(e) { | |
return e.startsWith("!edge"); | |
} | |
I(r) | |
? I(a) | |
? s.ArrayUtilities.sortRange( | |
this.iterationOrder, | |
function (e, t) { | |
let s = p(r, d, e, t); | |
return 0 === s && (s = p(a, h, e, t)), 0 === s ? e - t : s; | |
}, | |
t, | |
n, | |
i, | |
o | |
) | |
: s.ArrayUtilities.sortRange( | |
this.iterationOrder, | |
function (e, t) { | |
let s = p(r, d, e, t); | |
return 0 === s && (s = f(a, h, e, t)), 0 === s ? e - t : s; | |
}, | |
t, | |
n, | |
i, | |
o | |
) | |
: I(a) | |
? s.ArrayUtilities.sortRange( | |
this.iterationOrder, | |
function (e, t) { | |
let s = f(r, d, e, t); | |
return 0 === s && (s = p(a, h, e, t)), 0 === s ? e - t : s; | |
}, | |
t, | |
n, | |
i, | |
o | |
) | |
: s.ArrayUtilities.sortRange( | |
this.iterationOrder, | |
function (e, t) { | |
let s = f(r, d, e, t); | |
return 0 === s && (s = f(a, h, e, t)), 0 === s ? e - t : s; | |
}, | |
t, | |
n, | |
i, | |
o | |
); | |
} | |
} | |
class b extends E { | |
snapshot; | |
constructor(e, t) { | |
const s = new l(e); | |
super(new m(s, t), s), (this.snapshot = e); | |
} | |
nodePosition(e) { | |
this.createIterationOrder(); | |
const t = this.snapshot.createNode(); | |
let s = 0; | |
if (!this.iterationOrder) throw new Error("Iteration order not defined"); | |
for (; s < this.iterationOrder.length && ((t.nodeIndex = this.iterationOrder[s]), t.id() !== e); s++); | |
if (s === this.iterationOrder.length) return -1; | |
const n = this.iterationOrder[s]; | |
let i = 0; | |
const o = this.currentComparator, | |
r = this.buildCompareFunction(o); | |
for (let e = 0; e < this.iterationOrder.length; e++) r(this.iterationOrder[e], n) < 0 && ++i; | |
return i; | |
} | |
buildCompareFunction(e) { | |
const t = this.snapshot.createNode(), | |
s = this.snapshot.createNode(), | |
n = t[e.fieldName1], | |
i = t[e.fieldName2], | |
o = e.ascending1 ? 1 : -1, | |
r = e.ascending2 ? 1 : -1; | |
function a(e, n) { | |
const i = e.call(t), | |
o = e.call(s); | |
return i < o ? -n : i > o ? n : 0; | |
} | |
return function (e, d) { | |
(t.nodeIndex = e), (s.nodeIndex = d); | |
let h = a(n, o); | |
return 0 === h && (h = a(i, r)), h || e - d; | |
}; | |
} | |
sort(e, t, n, i, o) { | |
if (!this.iterationOrder) throw new Error("Iteration order not defined"); | |
s.ArrayUtilities.sortRange(this.iterationOrder, this.buildCompareFunction(e), t, n, i, o); | |
} | |
} | |
class A extends O { | |
nodeFlags; | |
lazyStringCache; | |
flags; | |
#ce; | |
constructor(e, t) { | |
super(e, t), (this.nodeFlags = { canBeQueried: 1, detachedDOMTreeNode: 2, pageObject: 4 }), (this.lazyStringCache = {}), this.initialize(); | |
} | |
createNode(e) { | |
return new v(this, void 0 === e ? -1 : e); | |
} | |
createEdge(e) { | |
return new _(this, e); | |
} | |
createRetainingEdge(e) { | |
return new z(this, e); | |
} | |
containmentEdgesFilter() { | |
return (e) => !e.isInvisible(); | |
} | |
retainingEdgesFilter() { | |
const e = this.containmentEdgesFilter(); | |
return function (t) { | |
return e(t) && !t.node().isRoot() && !t.isWeak(); | |
}; | |
} | |
calculateFlags() { | |
(this.flags = new Uint32Array(this.nodeCount)), this.markDetachedDOMTreeNodes(), this.markQueriableHeapObjects(), this.markPageOwnedNodes(); | |
} | |
#ue() { | |
for (let e = this.rootNode().edges(); e.hasNext(); e.next()) if (this.isUserRoot(e.edge.node())) return !0; | |
return !1; | |
} | |
calculateShallowSizes() { | |
if (!this.#ue()) return; | |
const { nodeCount: e, nodes: t, nodeFieldCount: s, nodeSelfSizeOffset: n } = this, | |
i = 4294967295, | |
o = 4294967294; | |
if (e >= o) throw new Error("Too many nodes for calculateShallowSizes"); | |
const r = new Uint32Array(e), | |
a = [], | |
d = this.createNode(0); | |
for (let t = 0; t < e; ++t) d.isHidden() || d.isArray() ? (r[t] = i) : ((r[t] = t), a.push(t)), (d.nodeIndex = d.nextNodeIndex()); | |
for (; 0 !== a.length; ) { | |
const e = a.pop(), | |
t = r[e]; | |
d.nodeIndex = e * s; | |
for (let e = d.edges(); e.hasNext(); e.next()) { | |
const n = e.edge; | |
if (n.isWeak()) continue; | |
const d = n.nodeIndex() / s; | |
switch (r[d]) { | |
case i: | |
(r[d] = t), a.push(d); | |
break; | |
case d: | |
case t: | |
case o: | |
break; | |
default: | |
(r[d] = o), a.push(d); | |
} | |
} | |
} | |
for (let a = 0; a < e; ++a) { | |
const e = r[a]; | |
switch (e) { | |
case i: | |
case o: | |
case a: | |
break; | |
default: { | |
const i = a * s, | |
o = e * s; | |
if (((d.nodeIndex = o), d.isSynthetic() || d.isRoot())) break; | |
const r = t.getValue(i + n); | |
t.setValue(i + n, 0), t.setValue(o + n, t.getValue(o + n) + r); | |
break; | |
} | |
} | |
} | |
} | |
calculateDistances(e) { | |
const t = new Set(), | |
s = this; | |
super.calculateDistances(e, function (e, n) { | |
if (e.isHidden() && "sloppy_function_map" === n.name() && "system / NativeContext" === e.rawName()) return !1; | |
if (e.isArray() && "(map descriptors)" === e.rawName()) { | |
const e = parseInt(n.name(), 10); | |
return e < 2 || e % 3 != 1; | |
} | |
if (n.isInternal()) { | |
const e = s.tryParseWeakMapEdgeName(n.nameIndex()); | |
if (e && !t.delete(e.duplicatedPart)) return t.add(e.duplicatedPart), !1; | |
} | |
return !0; | |
}); | |
} | |
isUserRoot(e) { | |
return e.isUserRoot() || e.isDocumentDOMTreesRoot(); | |
} | |
userObjectsMapAndFlag() { | |
return { map: this.flags, flag: this.nodeFlags.pageObject }; | |
} | |
flagsOfNode(e) { | |
return this.flags[e.nodeIndex / this.nodeFieldCount]; | |
} | |
markDetachedDOMTreeNodes() { | |
const e = this.nodes, | |
t = e.length, | |
s = this.nodeFieldCount, | |
n = this.nodeNativeType, | |
i = this.nodeTypeOffset, | |
o = this.nodeFlags.detachedDOMTreeNode, | |
r = this.rootNode(); | |
for (let a = 0, d = 0; a < t; a += s, d++) { | |
e.getValue(a + i) === n && ((r.nodeIndex = a), r.name().startsWith("Detached ") && (this.flags[d] |= o)); | |
} | |
} | |
markQueriableHeapObjects() { | |
const e = this.nodeFlags.canBeQueried, | |
t = this.edgeHiddenType, | |
s = this.edgeInternalType, | |
n = this.edgeInvisibleType, | |
i = this.edgeWeakType, | |
o = this.edgeToNodeOffset, | |
r = this.edgeTypeOffset, | |
a = this.edgeFieldsCount, | |
d = this.containmentEdges, | |
h = this.nodeFieldCount, | |
l = this.firstEdgeIndexes, | |
c = this.flags, | |
u = []; | |
for (let e = this.rootNode().edges(); e.hasNext(); e.next()) e.edge.node().isUserRoot() && u.push(e.edge.node().nodeIndex / h); | |
for (; u.length; ) { | |
const g = u.pop(); | |
if (c[g] & e) continue; | |
c[g] |= e; | |
const p = l[g], | |
f = l[g + 1]; | |
for (let l = p; l < f; l += a) { | |
const a = d.getValue(l + o) / h; | |
if (c[a] & e) continue; | |
const g = d.getValue(l + r); | |
g !== t && g !== n && g !== s && g !== i && u.push(a); | |
} | |
} | |
} | |
markPageOwnedNodes() { | |
const e = this.edgeShortcutType, | |
t = this.edgeElementType, | |
s = this.edgeToNodeOffset, | |
n = this.edgeTypeOffset, | |
i = this.edgeFieldsCount, | |
o = this.edgeWeakType, | |
r = this.firstEdgeIndexes, | |
a = this.containmentEdges, | |
d = this.nodeFieldCount, | |
h = this.nodeCount, | |
l = this.flags, | |
c = this.nodeFlags.pageObject, | |
u = new Uint32Array(h); | |
let g = 0; | |
const p = this.rootNodeIndexInternal / d, | |
f = this.rootNode(); | |
for (let o = r[p], h = r[p + 1]; o < h; o += i) { | |
const i = a.getValue(o + n), | |
r = a.getValue(o + s); | |
if (i === t) { | |
if (((f.nodeIndex = r), !f.isDocumentDOMTreesRoot())) continue; | |
} else if (i !== e) continue; | |
const h = r / d; | |
(u[g++] = h), (l[h] |= c); | |
} | |
for (; g; ) { | |
const e = u[--g], | |
t = r[e], | |
h = r[e + 1]; | |
for (let e = t; e < h; e += i) { | |
const t = a.getValue(e + s) / d; | |
if (l[t] & c) continue; | |
a.getValue(e + n) !== o && ((u[g++] = t), (l[t] |= c)); | |
} | |
} | |
} | |
calculateStatistics() { | |
const t = this.nodeFieldCount, | |
s = this.nodes, | |
n = s.length, | |
i = this.nodeTypeOffset, | |
o = this.nodeSelfSizeOffset, | |
r = this.nodeNativeType, | |
a = this.nodeCodeType, | |
d = this.nodeConsStringType, | |
h = this.nodeSlicedStringType, | |
l = this.nodeDistances; | |
let c = 0, | |
u = 0, | |
g = 0, | |
p = 0, | |
f = 0; | |
const I = this.rootNode(); | |
for (let x = 0; x < n; x += t) { | |
const n = s.getValue(x + o); | |
if (l[x / t] >= e.HeapSnapshotModel.baseSystemDistance) { | |
f += n; | |
continue; | |
} | |
const m = s.getValue(x + i); | |
(I.nodeIndex = x), m === r ? (c += n) : m === a ? (u += n) : m === d || m === h || "string" === I.type() ? (g += n) : "Array" === I.rawName() && (p += this.calculateArraySize(I)); | |
} | |
(this.#ce = new e.HeapSnapshotModel.Statistics()), | |
(this.#ce.total = this.totalSize), | |
(this.#ce.v8heap = this.totalSize - c), | |
(this.#ce.native = c), | |
(this.#ce.code = u), | |
(this.#ce.jsArrays = p), | |
(this.#ce.strings = g), | |
(this.#ce.system = f); | |
} | |
calculateArraySize(e) { | |
let t = e.selfSize(); | |
const s = e.edgeIndexesStart(), | |
n = e.edgeIndexesEnd(), | |
i = this.containmentEdges, | |
o = this.strings, | |
r = this.edgeToNodeOffset, | |
a = this.edgeTypeOffset, | |
d = this.edgeNameOffset, | |
h = this.edgeFieldsCount, | |
l = this.edgeInternalType; | |
for (let c = s; c < n; c += h) { | |
if (i.getValue(c + a) !== l) continue; | |
if ("elements" !== o[i.getValue(c + d)]) continue; | |
const s = i.getValue(c + r); | |
(e.nodeIndex = s), 1 === e.retainersCount() && (t += e.selfSize()); | |
break; | |
} | |
return t; | |
} | |
getStatistics() { | |
return this.#ce; | |
} | |
} | |
class v extends I { | |
constructor(e, t) { | |
super(e, t); | |
} | |
canBeQueried() { | |
const e = this.snapshot, | |
t = e.flagsOfNode(this); | |
return Boolean(t & e.nodeFlags.canBeQueried); | |
} | |
name() { | |
const e = this.snapshot, | |
t = (t) => { | |
let s = e.lazyStringCache[this.nodeIndex]; | |
return void 0 === s && ((s = t()), (e.lazyStringCache[this.nodeIndex] = s)), s; | |
}; | |
return this.rawType() === e.nodeConsStringType ? t(() => this.consStringName()) : this.rawType() === e.nodeObjectType && "Object" === this.rawName() ? t(() => this.#ge()) : this.rawName(); | |
} | |
consStringName() { | |
const e = this.snapshot, | |
t = e.nodeConsStringType, | |
s = e.edgeInternalType, | |
n = e.edgeFieldsCount, | |
i = e.edgeToNodeOffset, | |
o = e.edgeTypeOffset, | |
r = e.edgeNameOffset, | |
a = e.strings, | |
d = e.containmentEdges, | |
h = e.firstEdgeIndexes, | |
l = e.nodeFieldCount, | |
c = e.nodeTypeOffset, | |
u = e.nodeNameOffset, | |
g = e.nodes, | |
p = []; | |
p.push(this.nodeIndex); | |
let f = ""; | |
for (; p.length && f.length < 1024; ) { | |
const e = p.pop(); | |
if (g.getValue(e + c) !== t) { | |
f += a[g.getValue(e + u)]; | |
continue; | |
} | |
const I = e / l, | |
x = h[I], | |
m = h[I + 1]; | |
let N = 0, | |
y = 0; | |
for (let e = x; e < m && (!N || !y); e += n) { | |
if (d.getValue(e + o) === s) { | |
const t = a[d.getValue(e + r)]; | |
"first" === t ? (N = d.getValue(e + i)) : "second" === t && (y = d.getValue(e + i)); | |
} | |
} | |
p.push(y), p.push(N); | |
} | |
return f; | |
} | |
#ge() { | |
const e = this.snapshot, | |
{ edgeFieldsCount: t, edgePropertyType: s } = e, | |
n = e.createEdge(0); | |
let i = "{", | |
o = "}", | |
r = this.edgeIndexesStart(), | |
a = this.edgeIndexesEnd() - t, | |
d = !1; | |
for (; r <= a; ) { | |
if (((n.edgeIndex = d ? a : r), n.rawType() !== s || "__proto__" === n.name())) { | |
d ? (a -= t) : (r += t); | |
continue; | |
} | |
const e = v.formatPropertyName(n.name()); | |
if (i.length > 1 && i.length + o.length + e.length > 100) break; | |
d ? ((a -= t), o.length > 1 && (o = ", " + o), (o = e + o)) : ((r += t), i.length > 1 && (i += ", "), (i += e)), (d = !d); | |
} | |
return r <= a && (i += ", ..."), o.length > 1 && (i += ", "), i + o; | |
} | |
static formatPropertyName(e) { | |
return /[,'"{}]/.test(e) && (e = (e = JSON.stringify({ [e]: 0 })).substring(1, e.length - 3)), e; | |
} | |
id() { | |
const e = this.snapshot; | |
return e.nodes.getValue(this.nodeIndex + e.nodeIdOffset); | |
} | |
isHidden() { | |
return this.rawType() === this.snapshot.nodeHiddenType; | |
} | |
isArray() { | |
return this.rawType() === this.snapshot.nodeArrayType; | |
} | |
isSynthetic() { | |
return this.rawType() === this.snapshot.nodeSyntheticType; | |
} | |
isUserRoot() { | |
return !this.isSynthetic(); | |
} | |
isDocumentDOMTreesRoot() { | |
return this.isSynthetic() && "(Document DOM trees)" === this.rawName(); | |
} | |
serialize() { | |
const e = super.serialize(), | |
t = this.snapshot, | |
s = t.flagsOfNode(this); | |
return s & t.nodeFlags.canBeQueried && (e.canBeQueried = !0), s & t.nodeFlags.detachedDOMTreeNode && (e.detachedDOMTreeNode = !0), e; | |
} | |
} | |
class _ extends h { | |
constructor(e, t) { | |
super(e, t); | |
} | |
clone() { | |
const e = this.snapshot; | |
return new _(e, this.edgeIndex); | |
} | |
hasStringName() { | |
return this.isShortcut() ? isNaN(parseInt(this.nameInternal(), 10)) : this.hasStringNameInternal(); | |
} | |
isElement() { | |
return this.rawType() === this.snapshot.edgeElementType; | |
} | |
isHidden() { | |
return this.rawType() === this.snapshot.edgeHiddenType; | |
} | |
isWeak() { | |
return this.rawType() === this.snapshot.edgeWeakType; | |
} | |
isInternal() { | |
return this.rawType() === this.snapshot.edgeInternalType; | |
} | |
isInvisible() { | |
return this.rawType() === this.snapshot.edgeInvisibleType; | |
} | |
isShortcut() { | |
return this.rawType() === this.snapshot.edgeShortcutType; | |
} | |
name() { | |
const e = this.nameInternal(); | |
if (!this.isShortcut()) return String(e); | |
const t = parseInt(e, 10); | |
return String(isNaN(t) ? e : t); | |
} | |
toString() { | |
const e = this.name(); | |
switch (this.type()) { | |
case "context": | |
return "->" + e; | |
case "element": | |
return "[" + e + "]"; | |
case "weak": | |
return "[[" + e + "]]"; | |
case "property": | |
return -1 === e.indexOf(" ") ? "." + e : '["' + e + '"]'; | |
case "shortcut": | |
return "string" == typeof e ? (-1 === e.indexOf(" ") ? "." + e : '["' + e + '"]') : "[" + e + "]"; | |
case "internal": | |
case "hidden": | |
case "invisible": | |
return "{" + e + "}"; | |
} | |
return "?" + e + "?"; | |
} | |
hasStringNameInternal() { | |
const e = this.rawType(), | |
t = this.snapshot; | |
return e !== t.edgeElementType && e !== t.edgeHiddenType; | |
} | |
nameInternal() { | |
return this.hasStringNameInternal() ? this.snapshot.strings[this.nameOrIndex()] : this.nameOrIndex(); | |
} | |
nameOrIndex() { | |
return this.edges.getValue(this.edgeIndex + this.snapshot.edgeNameOffset); | |
} | |
rawType() { | |
return this.edges.getValue(this.edgeIndex + this.snapshot.edgeTypeOffset); | |
} | |
nameIndex() { | |
if (!this.hasStringNameInternal()) throw new Error("Edge does not have string name"); | |
return this.nameOrIndex(); | |
} | |
} | |
class z extends p { | |
constructor(e, t) { | |
super(e, t); | |
} | |
clone() { | |
const e = this.snapshot; | |
return new z(e, this.retainerIndex()); | |
} | |
isHidden() { | |
return this.edge().isHidden(); | |
} | |
isInvisible() { | |
return this.edge().isInvisible(); | |
} | |
isShortcut() { | |
return this.edge().isShortcut(); | |
} | |
isWeak() { | |
return this.edge().isWeak(); | |
} | |
} | |
var D = Object.freeze({ | |
__proto__: null, | |
HeapSnapshotEdge: h, | |
HeapSnapshotNodeIndexProvider: l, | |
HeapSnapshotEdgeIndexProvider: c, | |
HeapSnapshotRetainerEdgeIndexProvider: u, | |
HeapSnapshotEdgeIterator: g, | |
HeapSnapshotRetainerEdge: p, | |
HeapSnapshotRetainerEdgeIterator: f, | |
HeapSnapshotNode: I, | |
HeapSnapshotNodeIterator: x, | |
HeapSnapshotIndexRangeIterator: m, | |
HeapSnapshotFilteredIterator: N, | |
HeapSnapshotProgress: y, | |
HeapSnapshotProblemReport: S, | |
HeapSnapshot: O, | |
HeapSnapshotHeader: class { | |
title; | |
meta; | |
node_count; | |
edge_count; | |
trace_function_count; | |
root_index; | |
constructor() { | |
(this.title = ""), (this.meta = new C()), (this.node_count = 0), (this.edge_count = 0), (this.trace_function_count = 0), (this.root_index = 0); | |
} | |
}, | |
HeapSnapshotItemProvider: E, | |
HeapSnapshotEdgesProvider: F, | |
HeapSnapshotNodesProvider: b, | |
JSHeapSnapshot: A, | |
JSHeapSnapshotNode: v, | |
JSHeapSnapshotEdge: _, | |
JSHeapSnapshotRetainerEdge: z, | |
}); | |
class R { | |
#M; | |
#pe; | |
#fe; | |
#Ie; | |
#xe; | |
#me; | |
#Ne; | |
#ye = ""; | |
constructor(e) { | |
this.#Se(), (this.#M = new y(e)), (this.#pe = []), (this.#fe = null), (this.#Ie = !1), this.#we(); | |
} | |
dispose() { | |
this.#Se(); | |
} | |
#Se() { | |
(this.#ye = ""), (this.#xe = void 0); | |
} | |
close() { | |
(this.#Ie = !0), this.#fe && this.#fe(""); | |
} | |
buildSnapshot() { | |
(this.#xe = this.#xe || {}), this.#M.updateStatus("Processing snapshot…"); | |
const e = new A(this.#xe, this.#M); | |
return this.#Se(), e; | |
} | |
#Te() { | |
let e = 0; | |
const t = "0".charCodeAt(0), | |
s = "9".charCodeAt(0), | |
n = "]".charCodeAt(0), | |
i = this.#ye.length; | |
for (;;) { | |
for (; e < i; ) { | |
const i = this.#ye.charCodeAt(e); | |
if (t <= i && i <= s) break; | |
if (i === n) return (this.#ye = this.#ye.slice(e + 1)), !1; | |
++e; | |
} | |
if (e === i) return (this.#ye = ""), !0; | |
let o = 0; | |
const r = e; | |
for (; e < i; ) { | |
const n = this.#ye.charCodeAt(e); | |
if (t > n || n > s) break; | |
(o *= 10), (o += n - t), ++e; | |
} | |
if (e === i) return (this.#ye = this.#ye.slice(r)), !0; | |
if (!this.#me) throw new Error("Array not instantiated"); | |
this.#me.setValue(this.#Ne++, o); | |
} | |
} | |
#Oe() { | |
this.#M.updateStatus("Parsing strings…"); | |
const e = this.#ye.lastIndexOf("]"); | |
if (-1 === e) throw new Error("Incomplete JSON"); | |
if (((this.#ye = this.#ye.slice(0, e + 1)), !this.#xe)) throw new Error("No snapshot in parseStringsArray"); | |
this.#xe.strings = JSON.parse(this.#ye); | |
} | |
write(e) { | |
this.#pe.push(e), this.#fe && (this.#fe(this.#pe.shift()), (this.#fe = null)); | |
} | |
#Ce() { | |
if (this.#pe.length > 0) return Promise.resolve(this.#pe.shift()); | |
const { promise: e, resolve: t } = s.PromiseUtilities.promiseWithResolvers(); | |
return (this.#fe = t), e; | |
} | |
async #Ee(e, t) { | |
for (;;) { | |
const s = this.#ye.indexOf(e, t || 0); | |
if (-1 !== s) return s; | |
(t = this.#ye.length - e.length + 1), (this.#ye += await this.#Ce()); | |
} | |
} | |
async #Fe(e, t, n) { | |
const i = await this.#Ee(e), | |
o = await this.#Ee("[", i); | |
for (this.#ye = this.#ye.slice(o + 1), this.#me = void 0 === n ? s.TypedArrayUtilities.createExpandableBigUint32Array() : s.TypedArrayUtilities.createFixedBigUint32Array(n), this.#Ne = 0; this.#Te(); ) | |
n ? this.#M.updateProgress(t, this.#Ne, this.#me.length) : this.#M.updateStatus(t), (this.#ye += await this.#Ce()); | |
const r = this.#me; | |
return (this.#me = null), r; | |
} | |
async #we() { | |
const e = '"snapshot"', | |
t = await this.#Ee(e); | |
if (-1 === t) throw new Error("Snapshot token not found"); | |
this.#M.updateStatus("Loading snapshot info…"); | |
const s = this.#ye.slice(t + 10 + 1); | |
let i = !1; | |
const o = new n.TextUtils.BalancedJSONTokenizer((e) => { | |
(this.#ye = o.remainder()), (i = !0), (this.#xe = this.#xe || {}), (this.#xe.snapshot = JSON.parse(e)); | |
}); | |
for (o.write(s); !i; ) o.write(await this.#Ce()); | |
this.#xe = this.#xe || {}; | |
const r = await this.#Fe('"nodes"', "Loading nodes… {PH1}%", this.#xe.snapshot.meta.node_fields.length * this.#xe.snapshot.node_count); | |
this.#xe.nodes = r; | |
const a = await this.#Fe('"edges"', "Loading edges… {PH1}%", this.#xe.snapshot.meta.edge_fields.length * this.#xe.snapshot.edge_count); | |
if (((this.#xe.edges = a), this.#xe.snapshot.trace_function_count)) { | |
const e = await this.#Fe('"trace_function_infos"', "Loading allocation traces… {PH1}%", this.#xe.snapshot.meta.trace_function_info_fields.length * this.#xe.snapshot.trace_function_count); | |
this.#xe.trace_function_infos = e.asUint32ArrayOrFail(); | |
const t = await this.#Ee(":"), | |
s = await this.#Ee('"', t), | |
n = this.#ye.indexOf("["), | |
i = this.#ye.lastIndexOf("]", s); | |
(this.#xe.trace_tree = JSON.parse(this.#ye.substring(n, i + 1))), (this.#ye = this.#ye.slice(i + 1)); | |
} | |
if (this.#xe.snapshot.meta.sample_fields) { | |
const e = await this.#Fe('"samples"', "Loading samples…"); | |
this.#xe.samples = e.asArrayOrFail(); | |
} | |
if (this.#xe.snapshot.meta.location_fields) { | |
const e = await this.#Fe('"locations"', "Loading locations…"); | |
this.#xe.locations = e.asArrayOrFail(); | |
} else this.#xe.locations = []; | |
this.#M.updateStatus("Loading strings…"); | |
const d = await this.#Ee('"strings"'), | |
h = await this.#Ee("[", d); | |
for (this.#ye = this.#ye.slice(h); !this.#Ie; ) this.#ye += await this.#Ce(); | |
this.#Oe(); | |
} | |
} | |
var V = Object.freeze({ __proto__: null, HeapSnapshotLoader: R }); | |
var k = Object.freeze({ | |
__proto__: null, | |
HeapSnapshotWorkerDispatcher: class { | |
#be; | |
#Ae; | |
constructor(e) { | |
(this.#be = []), (this.#Ae = e); | |
} | |
sendEvent(e, t) { | |
this.#Ae({ eventName: e, data: t }); | |
} | |
dispatchMessage({ data: t }) { | |
const s = { callId: t.callId, result: null, error: void 0, errorCallStack: void 0, errorMethodName: void 0 }; | |
try { | |
switch (t.disposition) { | |
case "createLoader": | |
this.#be[t.objectId] = new R(this); | |
break; | |
case "dispose": | |
delete this.#be[t.objectId]; | |
break; | |
case "getter": { | |
const e = this.#be[t.objectId][t.methodName]; | |
s.result = e; | |
break; | |
} | |
case "factory": { | |
const e = this.#be[t.objectId], | |
n = e[t.methodName].apply(e, t.methodArguments); | |
n && (this.#be[t.newObjectId] = n), (s.result = Boolean(n)); | |
break; | |
} | |
case "method": { | |
const e = this.#be[t.objectId]; | |
s.result = e[t.methodName].apply(e, t.methodArguments); | |
break; | |
} | |
case "evaluateForTest": | |
try { | |
(globalThis.HeapSnapshotWorker = { AllocationProfile: d, HeapSnapshot: D, HeapSnapshotLoader: V }), (globalThis.HeapSnapshotModel = e), (s.result = self.eval(t.source)); | |
} catch (e) { | |
s.result = e.toString(); | |
} | |
} | |
} catch (e) { | |
(s.error = e.toString()), (s.errorCallStack = e.stack), t.methodName && (s.errorMethodName = t.methodName); | |
} | |
this.#Ae(s); | |
} | |
}, | |
}); | |
export { d as AllocationProfile, D as HeapSnapshot, V as HeapSnapshotLoader, k as HeapSnapshotWorkerDispatcher }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment