summaryrefslogtreecommitdiffstats
path: root/devtools/shared/heapsnapshot
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2020-02-22 17:32:39 -0500
committerwolfbeast <mcwerewolf@wolfbeast.com>2020-04-14 12:50:57 +0200
commit36fc5f674ef1a02d1498484c563a7108f4de44ed (patch)
tree120483cd8fc0decd189d5118941a9b23d6156ad5 /devtools/shared/heapsnapshot
parent7b30664f59e65cadb7d5eb2e42591e90a32871f8 (diff)
downloadUXP-36fc5f674ef1a02d1498484c563a7108f4de44ed.tar
UXP-36fc5f674ef1a02d1498484c563a7108f4de44ed.tar.gz
UXP-36fc5f674ef1a02d1498484c563a7108f4de44ed.tar.lz
UXP-36fc5f674ef1a02d1498484c563a7108f4de44ed.tar.xz
UXP-36fc5f674ef1a02d1498484c563a7108f4de44ed.zip
Reclassify heapsnapshot and nsJSInspector as not part of devtools
This resolves Issue #316
Diffstat (limited to 'devtools/shared/heapsnapshot')
-rw-r--r--devtools/shared/heapsnapshot/.gitattributes1
-rw-r--r--devtools/shared/heapsnapshot/AutoMemMap.cpp64
-rw-r--r--devtools/shared/heapsnapshot/AutoMemMap.h75
-rw-r--r--devtools/shared/heapsnapshot/CensusUtils.js489
-rw-r--r--devtools/shared/heapsnapshot/CoreDump.pb.cc2542
-rw-r--r--devtools/shared/heapsnapshot/CoreDump.pb.h1893
-rw-r--r--devtools/shared/heapsnapshot/CoreDump.proto143
-rw-r--r--devtools/shared/heapsnapshot/DeserializedNode.cpp150
-rw-r--r--devtools/shared/heapsnapshot/DeserializedNode.h317
-rw-r--r--devtools/shared/heapsnapshot/DominatorTree.cpp140
-rw-r--r--devtools/shared/heapsnapshot/DominatorTree.h67
-rw-r--r--devtools/shared/heapsnapshot/DominatorTreeNode.js336
-rw-r--r--devtools/shared/heapsnapshot/FileDescriptorOutputStream.cpp86
-rw-r--r--devtools/shared/heapsnapshot/FileDescriptorOutputStream.h41
-rw-r--r--devtools/shared/heapsnapshot/HeapAnalysesClient.js277
-rw-r--r--devtools/shared/heapsnapshot/HeapAnalysesWorker.js303
-rw-r--r--devtools/shared/heapsnapshot/HeapSnapshot.cpp1619
-rw-r--r--devtools/shared/heapsnapshot/HeapSnapshot.h224
-rw-r--r--devtools/shared/heapsnapshot/HeapSnapshotFileUtils.js95
-rw-r--r--devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperChild.h32
-rw-r--r--devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.cpp53
-rw-r--r--devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.h35
-rw-r--r--devtools/shared/heapsnapshot/PHeapSnapshotTempFileHelper.ipdl35
-rw-r--r--devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp100
-rw-r--r--devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.h70
-rw-r--r--devtools/shared/heapsnapshot/census-tree-node.js748
-rwxr-xr-xdevtools/shared/heapsnapshot/generate-core-dump-sources.sh26
-rw-r--r--devtools/shared/heapsnapshot/moz.build63
-rw-r--r--devtools/shared/heapsnapshot/shortest-paths.js91
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp100
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/DeserializedStackFrameUbiStackFrames.cpp91
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/DevTools.h276
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp73
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp64
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp53
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp37
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/SerializesTypeNames.cpp30
-rw-r--r--devtools/shared/heapsnapshot/tests/gtest/moz.build31
-rw-r--r--devtools/shared/heapsnapshot/tests/mochitest/chrome.ini8
-rw-r--r--devtools/shared/heapsnapshot/tests/mochitest/mochitest.ini6
-rw-r--r--devtools/shared/heapsnapshot/tests/mochitest/test_DominatorTree_01.html37
-rw-r--r--devtools/shared/heapsnapshot/tests/mochitest/test_SaveHeapSnapshot.html25
-rw-r--r--devtools/shared/heapsnapshot/tests/mochitest/test_saveHeapSnapshot_e10s_01.html82
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/.eslintrc.js6
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/Census.jsm165
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/Match.jsm190
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/dominator-tree-worker.js47
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js448
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/heap-snapshot-worker.js46
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_01.js46
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_02.js45
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_03.js47
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_04.js53
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_attachShortestPaths_01.js132
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_getNodeByIdAlongPath_01.js44
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_01.js112
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_02.js30
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_03.js117
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_partialTraversal_01.js164
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_01.js23
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_02.js40
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_03.js13
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_04.js22
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_05.js75
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_06.js56
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_01.js22
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_02.js23
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_01.js59
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_02.js22
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_03.js62
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCensusIndividuals_01.js89
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCreationTime_01.js58
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_01.js69
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_02.js31
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getImmediatelyDominated_01.js81
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_readHeapSnapshot_01.js18
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_01.js54
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_02.js59
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_01.js27
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_02.js29
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_03.js48
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_04.js118
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_05.js44
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_06.js109
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_07.js52
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_01.js69
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_02.js47
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_creationTime_01.js30
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_deepStack_01.js70
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_describeNode_01.js42
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_01.js31
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_02.js57
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_03.js34
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_04.js36
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_05.js24
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_06.js125
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_07.js82
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_08.js82
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_09.js92
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_10.js68
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_11.js116
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_12.js50
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot.js20
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_with_allocations.js36
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_worker.js40
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_SaveHeapSnapshot.js82
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-01.js76
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-02.js136
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-03.js96
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-04.js159
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-05.js145
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-06.js200
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-07.js200
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-08.js142
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-09.js44
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-10.js43
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_diff_01.js74
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_diff_02.js25
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_diff_03.js73
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_diff_04.js63
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_diff_05.js34
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_diff_06.js137
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_filtering_01.js105
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_filtering_02.js124
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_filtering_03.js59
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_filtering_04.js102
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_census_filtering_05.js71
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_countToBucketBreakdown_01.js37
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_deduplicatePaths_01.js113
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_getCensusIndividuals_01.js60
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_getReportLeaves_01.js114
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/test_saveHeapSnapshot_e10s_01.js8
-rw-r--r--devtools/shared/heapsnapshot/tests/unit/xpcshell.ini98
133 files changed, 0 insertions, 17794 deletions
diff --git a/devtools/shared/heapsnapshot/.gitattributes b/devtools/shared/heapsnapshot/.gitattributes
deleted file mode 100644
index 44e248a8d..000000000
--- a/devtools/shared/heapsnapshot/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-CoreDump.pb.* binary
diff --git a/devtools/shared/heapsnapshot/AutoMemMap.cpp b/devtools/shared/heapsnapshot/AutoMemMap.cpp
deleted file mode 100644
index e725a99c6..000000000
--- a/devtools/shared/heapsnapshot/AutoMemMap.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/devtools/AutoMemMap.h"
-
-#include "mozilla/Unused.h"
-#include "nsDebug.h"
-
-namespace mozilla {
-namespace devtools {
-
-AutoMemMap::~AutoMemMap()
-{
- if (addr) {
- Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
- addr = nullptr;
- }
-
- if (fileMap) {
- Unused << NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS);
- fileMap = nullptr;
- }
-
- if (fd) {
- Unused << NS_WARN_IF(PR_Close(fd) != PR_SUCCESS);
- fd = nullptr;
- }
-}
-
-nsresult
-AutoMemMap::init(const char* filePath, int flags, int mode, PRFileMapProtect prot)
-{
- MOZ_ASSERT(!fd);
- MOZ_ASSERT(!fileMap);
- MOZ_ASSERT(!addr);
-
- if (PR_GetFileInfo64(filePath, &fileInfo) != PR_SUCCESS)
- return NS_ERROR_FILE_NOT_FOUND;
-
- // Check if the file is too big to memmap.
- if (fileInfo.size > int64_t(UINT32_MAX))
- return NS_ERROR_INVALID_ARG;
- auto length = uint32_t(fileInfo.size);
-
- fd = PR_Open(filePath, flags, flags);
- if (!fd)
- return NS_ERROR_UNEXPECTED;
-
- fileMap = PR_CreateFileMap(fd, fileInfo.size, prot);
- if (!fileMap)
- return NS_ERROR_UNEXPECTED;
-
- addr = PR_MemMap(fileMap, 0, length);
- if (!addr)
- return NS_ERROR_UNEXPECTED;
-
- return NS_OK;
-}
-
-} // namespace devtools
-} // namespace mozilla
diff --git a/devtools/shared/heapsnapshot/AutoMemMap.h b/devtools/shared/heapsnapshot/AutoMemMap.h
deleted file mode 100644
index 537d68004..000000000
--- a/devtools/shared/heapsnapshot/AutoMemMap.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_AutoMemMap_h
-#define mozilla_devtools_AutoMemMap_h
-
-#include <prio.h>
-#include "mozilla/GuardObjects.h"
-
-namespace mozilla {
-namespace devtools {
-
-// # AutoMemMap
-//
-// AutoMemMap is an RAII class to manage mapping a file to memory. It is a
-// wrapper aorund managing opening and closing a file and calling PR_MemMap and
-// PR_MemUnmap.
-//
-// Example usage:
-//
-// {
-// AutoMemMap mm;
-// if (NS_FAILED(mm.init("/path/to/desired/file"))) {
-// // Handle the error however you see fit.
-// return false;
-// }
-//
-// doStuffWithMappedMemory(mm.address());
-// }
-// // The memory is automatically unmapped when the AutoMemMap leaves scope.
-class MOZ_RAII AutoMemMap
-{
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
-
- PRFileInfo64 fileInfo;
- PRFileDesc* fd;
- PRFileMap* fileMap;
- void* addr;
-
- AutoMemMap(const AutoMemMap& aOther) = delete;
- void operator=(const AutoMemMap& aOther) = delete;
-
-public:
- explicit AutoMemMap(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
- : fd(nullptr)
- , fileMap(nullptr)
- , addr(nullptr)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- };
- ~AutoMemMap();
-
- // Initialize this AutoMemMap.
- nsresult init(const char* filePath, int flags = PR_RDONLY, int mode = 0,
- PRFileMapProtect prot = PR_PROT_READONLY);
-
- // Get the size of the memory mapped file.
- uint32_t size() const {
- MOZ_ASSERT(fileInfo.size <= UINT32_MAX,
- "Should only call size() if init() succeeded.");
- return uint32_t(fileInfo.size);
- }
-
- // Get the mapped memory.
- void* address() { MOZ_ASSERT(addr); return addr; }
- const void* address() const { MOZ_ASSERT(addr); return addr; }
-};
-
-} // namespace devtools
-} // namespace mozilla
-
-#endif // mozilla_devtools_AutoMemMap_h
diff --git a/devtools/shared/heapsnapshot/CensusUtils.js b/devtools/shared/heapsnapshot/CensusUtils.js
deleted file mode 100644
index 36bdd2d82..000000000
--- a/devtools/shared/heapsnapshot/CensusUtils.js
+++ /dev/null
@@ -1,489 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { flatten } = require("resource://devtools/shared/ThreadSafeDevToolsUtils.js");
-
-/** * Visitor ****************************************************************/
-
-/**
- * A Visitor visits each node and edge of a census report tree as the census
- * report is being traversed by `walk`.
- */
-function Visitor() { }
-exports.Visitor = Visitor;
-
-/**
- * The `enter` method is called when a new sub-report is entered in traversal.
- *
- * @param {Object} breakdown
- * The breakdown for the sub-report that is being entered by traversal.
- *
- * @param {Object} report
- * The report generated by the given breakdown.
- *
- * @param {any} edge
- * The edge leading to this sub-report. The edge is null if (but not iff!
- * eg, null allocation stack edges) we are entering the root report.
- */
-Visitor.prototype.enter = function (breakdown, report, edge) { };
-
-/**
- * The `exit` method is called when traversal of a sub-report has finished.
- *
- * @param {Object} breakdown
- * The breakdown for the sub-report whose traversal has finished.
- *
- * @param {Object} report
- * The report generated by the given breakdown.
- *
- * @param {any} edge
- * The edge leading to this sub-report. The edge is null if (but not iff!
- * eg, null allocation stack edges) we are entering the root report.
- */
-Visitor.prototype.exit = function (breakdown, report, edge) { };
-
-/**
- * The `count` method is called when leaf nodes (reports whose breakdown is
- * by: "count") in the report tree are encountered.
- *
- * @param {Object} breakdown
- * The count breakdown for this report.
- *
- * @param {Object} report
- * The report generated by a breakdown by "count".
- *
- * @param {any|null} edge
- * The edge leading to this count report. The edge is null if we are
- * entering the root report.
- */
-Visitor.prototype.count = function (breakdown, report, edge) { };
-
-/** * getReportEdges *********************************************************/
-
-const EDGES = Object.create(null);
-
-EDGES.count = function (breakdown, report) {
- return [];
-};
-
-EDGES.bucket = function (breakdown, report) {
- return [];
-};
-
-EDGES.internalType = function (breakdown, report) {
- return Object.keys(report).map(key => ({
- edge: key,
- referent: report[key],
- breakdown: breakdown.then
- }));
-};
-
-EDGES.objectClass = function (breakdown, report) {
- return Object.keys(report).map(key => ({
- edge: key,
- referent: report[key],
- breakdown: key === "other" ? breakdown.other : breakdown.then
- }));
-};
-
-EDGES.coarseType = function (breakdown, report) {
- return [
- { edge: "objects", referent: report.objects, breakdown: breakdown.objects },
- { edge: "scripts", referent: report.scripts, breakdown: breakdown.scripts },
- { edge: "strings", referent: report.strings, breakdown: breakdown.strings },
- { edge: "other", referent: report.other, breakdown: breakdown.other },
- ];
-};
-
-EDGES.allocationStack = function (breakdown, report) {
- const edges = [];
- report.forEach((value, key) => {
- edges.push({
- edge: key,
- referent: value,
- breakdown: key === "noStack" ? breakdown.noStack : breakdown.then
- });
- });
- return edges;
-};
-
-EDGES.filename = function (breakdown, report) {
- return Object.keys(report).map(key => ({
- edge: key,
- referent: report[key],
- breakdown: key === "noFilename" ? breakdown.noFilename : breakdown.then
- }));
-};
-
-/**
- * Get the set of outgoing edges from `report` as specified by the given
- * breakdown.
- *
- * @param {Object} breakdown
- * The census breakdown.
- *
- * @param {Object} report
- * The census report.
- */
-function getReportEdges(breakdown, report) {
- return EDGES[breakdown.by](breakdown, report);
-}
-exports.getReportEdges = getReportEdges;
-
-/** * walk *******************************************************************/
-
-function recursiveWalk(breakdown, edge, report, visitor) {
- if (breakdown.by === "count") {
- visitor.enter(breakdown, report, edge);
- visitor.count(breakdown, report, edge);
- visitor.exit(breakdown, report, edge);
- } else {
- visitor.enter(breakdown, report, edge);
- for (let { edge, referent, breakdown: subBreakdown } of getReportEdges(breakdown, report)) {
- recursiveWalk(subBreakdown, edge, referent, visitor);
- }
- visitor.exit(breakdown, report, edge);
- }
-}
-
-/**
- * Walk the given `report` that was generated by taking a census with the
- * specified `breakdown`.
- *
- * @param {Object} breakdown
- * The census breakdown.
- *
- * @param {Object} report
- * The census report.
- *
- * @param {Visitor} visitor
- * The Visitor instance to call into while traversing.
- */
-function walk(breakdown, report, visitor) {
- recursiveWalk(breakdown, null, report, visitor);
-}
-exports.walk = walk;
-
-/** * diff *******************************************************************/
-
-/**
- * Return true if the object is a Map, false otherwise. Works with Map objects
- * from other globals, unlike `instanceof`.
- *
- * @returns {Boolean}
- */
-function isMap(obj) {
- return Object.prototype.toString.call(obj) === "[object Map]";
-}
-
-/**
- * A Visitor for computing the difference between the census report being
- * traversed and the given other census.
- *
- * @param {Object} otherCensus
- * The other census report.
- */
-function DiffVisitor(otherCensus) {
- // The other census we are comparing against.
- this._otherCensus = otherCensus;
-
- // The total bytes and count of the basis census we are traversing.
- this._totalBytes = 0;
- this._totalCount = 0;
-
- // Stack maintaining the current corresponding sub-report for the other
- // census we are comparing against.
- this._otherCensusStack = [];
-
- // Stack maintaining the set of edges visited at each sub-report.
- this._edgesVisited = [new Set()];
-
- // The final delta census. Valid only after traversal.
- this._results = null;
-
- // Stack maintaining the results corresponding to each sub-report we are
- // currently traversing.
- this._resultsStack = [];
-}
-
-DiffVisitor.prototype = Object.create(Visitor.prototype);
-
-/**
- * Given a report and an outgoing edge, get the edge's referent.
- */
-DiffVisitor.prototype._get = function (report, edge) {
- if (!report) {
- return undefined;
- }
- return isMap(report) ? report.get(edge) : report[edge];
-};
-
-/**
- * Given a report, an outgoing edge, and a value, set the edge's referent to
- * the given value.
- */
-DiffVisitor.prototype._set = function (report, edge, val) {
- if (isMap(report)) {
- report.set(edge, val);
- } else {
- report[edge] = val;
- }
-};
-
-/**
- * @overrides Visitor.prototype.enter
- */
-DiffVisitor.prototype.enter = function (breakdown, report, edge) {
- const isFirstTimeEntering = this._results === null;
-
- const newResults = breakdown.by === "allocationStack" ? new Map() : {};
- let newOther;
-
- if (!this._results) {
- // This is the first time we have entered a sub-report.
- this._results = newResults;
- newOther = this._otherCensus;
- } else {
- const topResults = this._resultsStack[this._resultsStack.length - 1];
- this._set(topResults, edge, newResults);
-
- const topOther = this._otherCensusStack[this._otherCensusStack.length - 1];
- newOther = this._get(topOther, edge);
- }
-
- this._resultsStack.push(newResults);
- this._otherCensusStack.push(newOther);
-
- const visited = this._edgesVisited[this._edgesVisited.length - 1];
- visited.add(edge);
- this._edgesVisited.push(new Set());
-};
-
-/**
- * @overrides Visitor.prototype.exit
- */
-DiffVisitor.prototype.exit = function (breakdown, report, edge) {
- // Find all the edges in the other census report that were not traversed and
- // add them to the results directly.
- const other = this._otherCensusStack[this._otherCensusStack.length - 1];
- if (other) {
- const visited = this._edgesVisited[this._edgesVisited.length - 1];
- const unvisited = getReportEdges(breakdown, other)
- .map(e => e.edge)
- .filter(e => !visited.has(e));
- const results = this._resultsStack[this._resultsStack.length - 1];
- for (let edge of unvisited) {
- this._set(results, edge, this._get(other, edge));
- }
- }
-
- this._otherCensusStack.pop();
- this._resultsStack.pop();
- this._edgesVisited.pop();
-};
-
-/**
- * @overrides Visitor.prototype.count
- */
-DiffVisitor.prototype.count = function (breakdown, report, edge) {
- const other = this._otherCensusStack[this._otherCensusStack.length - 1];
- const results = this._resultsStack[this._resultsStack.length - 1];
-
- if (breakdown.count) {
- this._totalCount += report.count;
- }
- if (breakdown.bytes) {
- this._totalBytes += report.bytes;
- }
-
- if (other) {
- if (breakdown.count) {
- results.count = other.count - report.count;
- }
- if (breakdown.bytes) {
- results.bytes = other.bytes - report.bytes;
- }
- } else {
- if (breakdown.count) {
- results.count = -report.count;
- }
- if (breakdown.bytes) {
- results.bytes = -report.bytes;
- }
- }
-};
-
-const basisTotalBytes = exports.basisTotalBytes = Symbol("basisTotalBytes");
-const basisTotalCount = exports.basisTotalCount = Symbol("basisTotalCount");
-
-/**
- * Get the resulting report of the difference between the traversed census
- * report and the other census report.
- *
- * @returns {Object}
- * The delta census report.
- */
-DiffVisitor.prototype.results = function () {
- if (!this._results) {
- throw new Error("Attempt to get results before computing diff!");
- }
-
- if (this._resultsStack.length) {
- throw new Error("Attempt to get results while still computing diff!");
- }
-
- this._results[basisTotalBytes] = this._totalBytes;
- this._results[basisTotalCount] = this._totalCount;
-
- return this._results;
-};
-
-/**
- * Take the difference between two censuses. The resulting delta report
- * contains the number/size of things that are in the `endCensus` that are not
- * in the `startCensus`.
- *
- * @param {Object} breakdown
- * The breakdown used to generate both census reports.
- *
- * @param {Object} startCensus
- * The first census report.
- *
- * @param {Object} endCensus
- * The second census report.
- *
- * @returns {Object}
- * A delta report mirroring the structure of the two census reports (as
- * specified by the given breakdown). Has two additional properties:
- * - {Number} basisTotalBytes: the total number of bytes in the start
- * census.
- * - {Number} basisTotalCount: the total count in the start census.
- */
-function diff(breakdown, startCensus, endCensus) {
- const visitor = new DiffVisitor(endCensus);
- walk(breakdown, startCensus, visitor);
- return visitor.results();
-}
-exports.diff = diff;
-
-/**
- * Creates a hash map mapping node IDs to its parent node.
- *
- * @param {CensusTreeNode} node
- * @param {Object<number, TreeNode>} aggregator
- *
- * @return {Object<number, TreeNode>}
- */
-const createParentMap = exports.createParentMap = function (node,
- getId = node => node.id,
- aggregator = Object.create(null)) {
- if (node.children) {
- for (let i = 0, length = node.children.length; i < length; i++) {
- const child = node.children[i];
- aggregator[getId(child)] = node;
- createParentMap(child, getId, aggregator);
- }
- }
-
- return aggregator;
-};
-
-const BUCKET = Object.freeze({ by: "bucket" });
-
-/**
- * Convert a breakdown whose leaves are { by: "count" } to an identical
- * breakdown, except with { by: "bucket" } leaves.
- *
- * @param {Object} breakdown
- * @returns {Object}
- */
-exports.countToBucketBreakdown = function (breakdown) {
- if (typeof breakdown !== "object" || !breakdown) {
- return breakdown;
- }
-
- if (breakdown.by === "count") {
- return BUCKET;
- }
-
- const keys = Object.keys(breakdown);
- const vals = keys.reduce((vs, k) => {
- vs.push(exports.countToBucketBreakdown(breakdown[k]));
- return vs;
- }, []);
-
- const result = {};
- for (let i = 0, length = keys.length; i < length; i++) {
- result[keys[i]] = vals[i];
- }
-
- return Object.freeze(result);
-};
-
-/**
- * A Visitor for finding report leaves by their DFS index.
- */
-function GetLeavesVisitor(targetIndices) {
- this._index = -1;
- this._targetIndices = targetIndices;
- this._leaves = [];
-}
-
-GetLeavesVisitor.prototype = Object.create(Visitor.prototype);
-
-/**
- * @overrides Visitor.prototype.enter
- */
-GetLeavesVisitor.prototype.enter = function (breakdown, report, edge) {
- this._index++;
- if (this._targetIndices.has(this._index)) {
- this._leaves.push(report);
- }
-};
-
-/**
- * Get the accumulated report leaves after traversal.
- */
-GetLeavesVisitor.prototype.leaves = function () {
- if (this._index === -1) {
- throw new Error("Attempt to call `leaves` before traversing report!");
- }
- return this._leaves;
-};
-
-/**
- * Given a set of indices of leaves in a pre-order depth-first traversal of the
- * given census report, return the leaves.
- *
- * @param {Set<Number>} indices
- * @param {Object} breakdown
- * @param {Object} report
- *
- * @returns {Array<Object>}
- */
-exports.getReportLeaves = function (indices, breakdown, report) {
- const visitor = new GetLeavesVisitor(indices);
- walk(breakdown, report, visitor);
- return visitor.leaves();
-};
-
-/**
- * Get a list of the individual node IDs that belong to the census report leaves
- * of the given indices.
- *
- * @param {Set<Number>} indices
- * @param {Object} breakdown
- * @param {HeapSnapshot} snapshot
- *
- * @returns {Array<NodeId>}
- */
-exports.getCensusIndividuals = function (indices, countBreakdown, snapshot) {
- const bucketBreakdown = exports.countToBucketBreakdown(countBreakdown);
- const bucketReport = snapshot.takeCensus({ breakdown: bucketBreakdown });
- const buckets = exports.getReportLeaves(indices,
- bucketBreakdown,
- bucketReport);
- return flatten(buckets);
-};
diff --git a/devtools/shared/heapsnapshot/CoreDump.pb.cc b/devtools/shared/heapsnapshot/CoreDump.pb.cc
deleted file mode 100644
index 6c7c0e8a4..000000000
--- a/devtools/shared/heapsnapshot/CoreDump.pb.cc
+++ /dev/null
@@ -1,2542 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: CoreDump.proto
-
-#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
-#include "CoreDump.pb.h"
-
-#include <algorithm>
-
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/once.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format_lite_inl.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/generated_message_reflection.h>
-#include <google/protobuf/reflection_ops.h>
-#include <google/protobuf/wire_format.h>
-// @@protoc_insertion_point(includes)
-
-namespace mozilla {
-namespace devtools {
-namespace protobuf {
-
-namespace {
-
-const ::google::protobuf::Descriptor* Metadata_descriptor_ = NULL;
-const ::google::protobuf::internal::GeneratedMessageReflection*
- Metadata_reflection_ = NULL;
-const ::google::protobuf::Descriptor* StackFrame_descriptor_ = NULL;
-const ::google::protobuf::internal::GeneratedMessageReflection*
- StackFrame_reflection_ = NULL;
-struct StackFrameOneofInstance {
- const ::mozilla::devtools::protobuf::StackFrame_Data* data_;
- ::google::protobuf::uint64 ref_;
-}* StackFrame_default_oneof_instance_ = NULL;
-const ::google::protobuf::Descriptor* StackFrame_Data_descriptor_ = NULL;
-const ::google::protobuf::internal::GeneratedMessageReflection*
- StackFrame_Data_reflection_ = NULL;
-struct StackFrame_DataOneofInstance {
- const ::std::string* source_;
- ::google::protobuf::uint64 sourceref_;
- const ::std::string* functiondisplayname_;
- ::google::protobuf::uint64 functiondisplaynameref_;
-}* StackFrame_Data_default_oneof_instance_ = NULL;
-const ::google::protobuf::Descriptor* Node_descriptor_ = NULL;
-const ::google::protobuf::internal::GeneratedMessageReflection*
- Node_reflection_ = NULL;
-struct NodeOneofInstance {
- const ::std::string* typename__;
- ::google::protobuf::uint64 typenameref_;
- const ::std::string* jsobjectclassname_;
- ::google::protobuf::uint64 jsobjectclassnameref_;
- const ::std::string* scriptfilename_;
- ::google::protobuf::uint64 scriptfilenameref_;
-}* Node_default_oneof_instance_ = NULL;
-const ::google::protobuf::Descriptor* Edge_descriptor_ = NULL;
-const ::google::protobuf::internal::GeneratedMessageReflection*
- Edge_reflection_ = NULL;
-struct EdgeOneofInstance {
- const ::std::string* name_;
- ::google::protobuf::uint64 nameref_;
-}* Edge_default_oneof_instance_ = NULL;
-
-} // namespace
-
-
-void protobuf_AssignDesc_CoreDump_2eproto() {
- protobuf_AddDesc_CoreDump_2eproto();
- const ::google::protobuf::FileDescriptor* file =
- ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
- "CoreDump.proto");
- GOOGLE_CHECK(file != NULL);
- Metadata_descriptor_ = file->message_type(0);
- static const int Metadata_offsets_[1] = {
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metadata, timestamp_),
- };
- Metadata_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
- Metadata_descriptor_,
- Metadata::default_instance_,
- Metadata_offsets_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metadata, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metadata, _unknown_fields_),
- -1,
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(Metadata));
- StackFrame_descriptor_ = file->message_type(1);
- static const int StackFrame_offsets_[3] = {
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_default_oneof_instance_, data_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_default_oneof_instance_, ref_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame, StackFrameType_),
- };
- StackFrame_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
- StackFrame_descriptor_,
- StackFrame::default_instance_,
- StackFrame_offsets_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame, _unknown_fields_),
- -1,
- StackFrame_default_oneof_instance_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame, _oneof_case_[0]),
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(StackFrame));
- StackFrame_Data_descriptor_ = StackFrame_descriptor_->nested_type(0);
- static const int StackFrame_Data_offsets_[12] = {
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, id_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, parent_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, line_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, column_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, source_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, sourceref_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, functiondisplayname_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, functiondisplaynameref_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, issystem_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, isselfhosted_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, SourceOrRef_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, FunctionDisplayNameOrRef_),
- };
- StackFrame_Data_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
- StackFrame_Data_descriptor_,
- StackFrame_Data::default_instance_,
- StackFrame_Data_offsets_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _unknown_fields_),
- -1,
- StackFrame_Data_default_oneof_instance_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _oneof_case_[0]),
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(StackFrame_Data));
- Node_descriptor_ = file->message_type(2);
- static const int Node_offsets_[14] = {
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, id_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typename__),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typenameref_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, size_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, edges_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, allocationstack_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassname_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassnameref_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, coarsetype_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, scriptfilename_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, scriptfilenameref_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, TypeNameOrRef_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, JSObjectClassNameOrRef_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, ScriptFilenameOrRef_),
- };
- Node_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
- Node_descriptor_,
- Node::default_instance_,
- Node_offsets_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _unknown_fields_),
- -1,
- Node_default_oneof_instance_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _oneof_case_[0]),
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(Node));
- Edge_descriptor_ = file->message_type(3);
- static const int Edge_offsets_[4] = {
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, referent_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Edge_default_oneof_instance_, name_),
- PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Edge_default_oneof_instance_, nameref_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, EdgeNameOrRef_),
- };
- Edge_reflection_ =
- new ::google::protobuf::internal::GeneratedMessageReflection(
- Edge_descriptor_,
- Edge::default_instance_,
- Edge_offsets_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _has_bits_[0]),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _unknown_fields_),
- -1,
- Edge_default_oneof_instance_,
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _oneof_case_[0]),
- ::google::protobuf::DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(),
- sizeof(Edge));
-}
-
-namespace {
-
-GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
-inline void protobuf_AssignDescriptorsOnce() {
- ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
- &protobuf_AssignDesc_CoreDump_2eproto);
-}
-
-void protobuf_RegisterTypes(const ::std::string&) {
- protobuf_AssignDescriptorsOnce();
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- Metadata_descriptor_, &Metadata::default_instance());
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- StackFrame_descriptor_, &StackFrame::default_instance());
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- StackFrame_Data_descriptor_, &StackFrame_Data::default_instance());
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- Node_descriptor_, &Node::default_instance());
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- Edge_descriptor_, &Edge::default_instance());
-}
-
-} // namespace
-
-void protobuf_ShutdownFile_CoreDump_2eproto() {
- delete Metadata::default_instance_;
- delete Metadata_reflection_;
- delete StackFrame::default_instance_;
- delete StackFrame_default_oneof_instance_;
- delete StackFrame_reflection_;
- delete StackFrame_Data::default_instance_;
- delete StackFrame_Data_default_oneof_instance_;
- delete StackFrame_Data_reflection_;
- delete Node::default_instance_;
- delete Node_default_oneof_instance_;
- delete Node_reflection_;
- delete Edge::default_instance_;
- delete Edge_default_oneof_instance_;
- delete Edge_reflection_;
-}
-
-void protobuf_AddDesc_CoreDump_2eproto() {
- static bool already_here = false;
- if (already_here) return;
- already_here = true;
- GOOGLE_PROTOBUF_VERIFY_VERSION;
-
- ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
- "\n\016CoreDump.proto\022\031mozilla.devtools.proto"
- "buf\"\035\n\010Metadata\022\021\n\ttimeStamp\030\001 \001(\004\"\216\003\n\nS"
- "tackFrame\022:\n\004data\030\001 \001(\0132*.mozilla.devtoo"
- "ls.protobuf.StackFrame.DataH\000\022\r\n\003ref\030\002 \001"
- "(\004H\000\032\242\002\n\004Data\022\n\n\002id\030\001 \001(\004\0225\n\006parent\030\002 \001("
- "\0132%.mozilla.devtools.protobuf.StackFrame"
- "\022\014\n\004line\030\003 \001(\r\022\016\n\006column\030\004 \001(\r\022\020\n\006source"
- "\030\005 \001(\014H\000\022\023\n\tsourceRef\030\006 \001(\004H\000\022\035\n\023functio"
- "nDisplayName\030\007 \001(\014H\001\022 \n\026functionDisplayN"
- "ameRef\030\010 \001(\004H\001\022\020\n\010isSystem\030\t \001(\010\022\024\n\014isSe"
- "lfHosted\030\n \001(\010B\r\n\013SourceOrRefB\032\n\030Functio"
- "nDisplayNameOrRefB\020\n\016StackFrameType\"\210\003\n\004"
- "Node\022\n\n\002id\030\001 \001(\004\022\022\n\010typeName\030\002 \001(\014H\000\022\025\n\013"
- "typeNameRef\030\003 \001(\004H\000\022\014\n\004size\030\004 \001(\004\022.\n\005edg"
- "es\030\005 \003(\0132\037.mozilla.devtools.protobuf.Edg"
- "e\022>\n\017allocationStack\030\006 \001(\0132%.mozilla.dev"
- "tools.protobuf.StackFrame\022\033\n\021jsObjectCla"
- "ssName\030\007 \001(\014H\001\022\036\n\024jsObjectClassNameRef\030\010"
- " \001(\004H\001\022\025\n\ncoarseType\030\t \001(\r:\0010\022\030\n\016scriptF"
- "ilename\030\n \001(\014H\002\022\033\n\021scriptFilenameRef\030\013 \001"
- "(\004H\002B\017\n\rTypeNameOrRefB\030\n\026JSObjectClassNa"
- "meOrRefB\025\n\023ScriptFilenameOrRef\"L\n\004Edge\022\020"
- "\n\010referent\030\001 \001(\004\022\016\n\004name\030\002 \001(\014H\000\022\021\n\007name"
- "Ref\030\003 \001(\004H\000B\017\n\rEdgeNameOrRef", 948);
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
- "CoreDump.proto", &protobuf_RegisterTypes);
- Metadata::default_instance_ = new Metadata();
- StackFrame::default_instance_ = new StackFrame();
- StackFrame_default_oneof_instance_ = new StackFrameOneofInstance;
- StackFrame_Data::default_instance_ = new StackFrame_Data();
- StackFrame_Data_default_oneof_instance_ = new StackFrame_DataOneofInstance;
- Node::default_instance_ = new Node();
- Node_default_oneof_instance_ = new NodeOneofInstance;
- Edge::default_instance_ = new Edge();
- Edge_default_oneof_instance_ = new EdgeOneofInstance;
- Metadata::default_instance_->InitAsDefaultInstance();
- StackFrame::default_instance_->InitAsDefaultInstance();
- StackFrame_Data::default_instance_->InitAsDefaultInstance();
- Node::default_instance_->InitAsDefaultInstance();
- Edge::default_instance_->InitAsDefaultInstance();
- ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_CoreDump_2eproto);
-}
-
-// Force AddDescriptors() to be called at static initialization time.
-struct StaticDescriptorInitializer_CoreDump_2eproto {
- StaticDescriptorInitializer_CoreDump_2eproto() {
- protobuf_AddDesc_CoreDump_2eproto();
- }
-} static_descriptor_initializer_CoreDump_2eproto_;
-
-// ===================================================================
-
-#ifndef _MSC_VER
-const int Metadata::kTimeStampFieldNumber;
-#endif // !_MSC_VER
-
-Metadata::Metadata()
- : ::google::protobuf::Message() {
- SharedCtor();
- // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Metadata)
-}
-
-void Metadata::InitAsDefaultInstance() {
-}
-
-Metadata::Metadata(const Metadata& from)
- : ::google::protobuf::Message() {
- SharedCtor();
- MergeFrom(from);
- // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Metadata)
-}
-
-void Metadata::SharedCtor() {
- _cached_size_ = 0;
- timestamp_ = GOOGLE_ULONGLONG(0);
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
-}
-
-Metadata::~Metadata() {
- // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Metadata)
- SharedDtor();
-}
-
-void Metadata::SharedDtor() {
- if (this != default_instance_) {
- }
-}
-
-void Metadata::SetCachedSize(int size) const {
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
-}
-const ::google::protobuf::Descriptor* Metadata::descriptor() {
- protobuf_AssignDescriptorsOnce();
- return Metadata_descriptor_;
-}
-
-const Metadata& Metadata::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
- return *default_instance_;
-}
-
-Metadata* Metadata::default_instance_ = NULL;
-
-Metadata* Metadata::New() const {
- return new Metadata;
-}
-
-void Metadata::Clear() {
- timestamp_ = GOOGLE_ULONGLONG(0);
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
-}
-
-bool Metadata::MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
- ::google::protobuf::uint32 tag;
- // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.Metadata)
- for (;;) {
- ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
- tag = p.first;
- if (!p.second) goto handle_unusual;
- switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
- // optional uint64 timeStamp = 1;
- case 1: {
- if (tag == 8) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &timestamp_)));
- set_has_timestamp();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectAtEnd()) goto success;
- break;
- }
-
- default: {
- handle_unusual:
- if (tag == 0 ||
- ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- goto success;
- }
- DO_(::google::protobuf::internal::WireFormat::SkipField(
- input, tag, mutable_unknown_fields()));
- break;
- }
- }
- }
-success:
- // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.Metadata)
- return true;
-failure:
- // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.Metadata)
- return false;
-#undef DO_
-}
-
-void Metadata::SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const {
- // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.Metadata)
- // optional uint64 timeStamp = 1;
- if (has_timestamp()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->timestamp(), output);
- }
-
- if (!unknown_fields().empty()) {
- ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
- unknown_fields(), output);
- }
- // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Metadata)
-}
-
-::google::protobuf::uint8* Metadata::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
- // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.Metadata)
- // optional uint64 timeStamp = 1;
- if (has_timestamp()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->timestamp(), target);
- }
-
- if (!unknown_fields().empty()) {
- target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
- unknown_fields(), target);
- }
- // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Metadata)
- return target;
-}
-
-int Metadata::ByteSize() const {
- int total_size = 0;
-
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // optional uint64 timeStamp = 1;
- if (has_timestamp()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->timestamp());
- }
-
- }
- if (!unknown_fields().empty()) {
- total_size +=
- ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
- unknown_fields());
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = total_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- return total_size;
-}
-
-void Metadata::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const Metadata* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const Metadata*>(
- &from);
- if (source == NULL) {
- ::google::protobuf::internal::ReflectionOps::Merge(from, this);
- } else {
- MergeFrom(*source);
- }
-}
-
-void Metadata::MergeFrom(const Metadata& from) {
- GOOGLE_CHECK_NE(&from, this);
- if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from.has_timestamp()) {
- set_timestamp(from.timestamp());
- }
- }
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
-}
-
-void Metadata::CopyFrom(const ::google::protobuf::Message& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-void Metadata::CopyFrom(const Metadata& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-bool Metadata::IsInitialized() const {
-
- return true;
-}
-
-void Metadata::Swap(Metadata* other) {
- if (other != this) {
- std::swap(timestamp_, other->timestamp_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
-}
-
-::google::protobuf::Metadata Metadata::GetMetadata() const {
- protobuf_AssignDescriptorsOnce();
- ::google::protobuf::Metadata metadata;
- metadata.descriptor = Metadata_descriptor_;
- metadata.reflection = Metadata_reflection_;
- return metadata;
-}
-
-
-// ===================================================================
-
-#ifndef _MSC_VER
-const int StackFrame_Data::kIdFieldNumber;
-const int StackFrame_Data::kParentFieldNumber;
-const int StackFrame_Data::kLineFieldNumber;
-const int StackFrame_Data::kColumnFieldNumber;
-const int StackFrame_Data::kSourceFieldNumber;
-const int StackFrame_Data::kSourceRefFieldNumber;
-const int StackFrame_Data::kFunctionDisplayNameFieldNumber;
-const int StackFrame_Data::kFunctionDisplayNameRefFieldNumber;
-const int StackFrame_Data::kIsSystemFieldNumber;
-const int StackFrame_Data::kIsSelfHostedFieldNumber;
-#endif // !_MSC_VER
-
-StackFrame_Data::StackFrame_Data()
- : ::google::protobuf::Message() {
- SharedCtor();
- // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.StackFrame.Data)
-}
-
-void StackFrame_Data::InitAsDefaultInstance() {
- parent_ = const_cast< ::mozilla::devtools::protobuf::StackFrame*>(&::mozilla::devtools::protobuf::StackFrame::default_instance());
- StackFrame_Data_default_oneof_instance_->source_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
- StackFrame_Data_default_oneof_instance_->sourceref_ = GOOGLE_ULONGLONG(0);
- StackFrame_Data_default_oneof_instance_->functiondisplayname_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
- StackFrame_Data_default_oneof_instance_->functiondisplaynameref_ = GOOGLE_ULONGLONG(0);
-}
-
-StackFrame_Data::StackFrame_Data(const StackFrame_Data& from)
- : ::google::protobuf::Message() {
- SharedCtor();
- MergeFrom(from);
- // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.StackFrame.Data)
-}
-
-void StackFrame_Data::SharedCtor() {
- ::google::protobuf::internal::GetEmptyString();
- _cached_size_ = 0;
- id_ = GOOGLE_ULONGLONG(0);
- parent_ = NULL;
- line_ = 0u;
- column_ = 0u;
- issystem_ = false;
- isselfhosted_ = false;
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- clear_has_SourceOrRef();
- clear_has_FunctionDisplayNameOrRef();
-}
-
-StackFrame_Data::~StackFrame_Data() {
- // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.StackFrame.Data)
- SharedDtor();
-}
-
-void StackFrame_Data::SharedDtor() {
- if (has_SourceOrRef()) {
- clear_SourceOrRef();
- }
- if (has_FunctionDisplayNameOrRef()) {
- clear_FunctionDisplayNameOrRef();
- }
- if (this != default_instance_) {
- delete parent_;
- }
-}
-
-void StackFrame_Data::SetCachedSize(int size) const {
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
-}
-const ::google::protobuf::Descriptor* StackFrame_Data::descriptor() {
- protobuf_AssignDescriptorsOnce();
- return StackFrame_Data_descriptor_;
-}
-
-const StackFrame_Data& StackFrame_Data::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
- return *default_instance_;
-}
-
-StackFrame_Data* StackFrame_Data::default_instance_ = NULL;
-
-StackFrame_Data* StackFrame_Data::New() const {
- return new StackFrame_Data;
-}
-
-void StackFrame_Data::clear_SourceOrRef() {
- switch(SourceOrRef_case()) {
- case kSource: {
- delete SourceOrRef_.source_;
- break;
- }
- case kSourceRef: {
- // No need to clear
- break;
- }
- case SOURCEORREF_NOT_SET: {
- break;
- }
- }
- _oneof_case_[0] = SOURCEORREF_NOT_SET;
-}
-
-void StackFrame_Data::clear_FunctionDisplayNameOrRef() {
- switch(FunctionDisplayNameOrRef_case()) {
- case kFunctionDisplayName: {
- delete FunctionDisplayNameOrRef_.functiondisplayname_;
- break;
- }
- case kFunctionDisplayNameRef: {
- // No need to clear
- break;
- }
- case FUNCTIONDISPLAYNAMEORREF_NOT_SET: {
- break;
- }
- }
- _oneof_case_[1] = FUNCTIONDISPLAYNAMEORREF_NOT_SET;
-}
-
-
-void StackFrame_Data::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<StackFrame_Data*>(16)->f) - \
- reinterpret_cast<char*>(16))
-
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
-
- if (_has_bits_[0 / 32] & 15) {
- ZR_(line_, column_);
- id_ = GOOGLE_ULONGLONG(0);
- if (has_parent()) {
- if (parent_ != NULL) parent_->::mozilla::devtools::protobuf::StackFrame::Clear();
- }
- }
- ZR_(issystem_, isselfhosted_);
-
-#undef OFFSET_OF_FIELD_
-#undef ZR_
-
- clear_SourceOrRef();
- clear_FunctionDisplayNameOrRef();
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
-}
-
-bool StackFrame_Data::MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
- ::google::protobuf::uint32 tag;
- // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.StackFrame.Data)
- for (;;) {
- ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
- tag = p.first;
- if (!p.second) goto handle_unusual;
- switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
- // optional uint64 id = 1;
- case 1: {
- if (tag == 8) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &id_)));
- set_has_id();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(18)) goto parse_parent;
- break;
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame parent = 2;
- case 2: {
- if (tag == 18) {
- parse_parent:
- DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
- input, mutable_parent()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(24)) goto parse_line;
- break;
- }
-
- // optional uint32 line = 3;
- case 3: {
- if (tag == 24) {
- parse_line:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, &line_)));
- set_has_line();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(32)) goto parse_column;
- break;
- }
-
- // optional uint32 column = 4;
- case 4: {
- if (tag == 32) {
- parse_column:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, &column_)));
- set_has_column();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(42)) goto parse_source;
- break;
- }
-
- // optional bytes source = 5;
- case 5: {
- if (tag == 42) {
- parse_source:
- DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
- input, this->mutable_source()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(48)) goto parse_sourceRef;
- break;
- }
-
- // optional uint64 sourceRef = 6;
- case 6: {
- if (tag == 48) {
- parse_sourceRef:
- clear_SourceOrRef();
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &SourceOrRef_.sourceref_)));
- set_has_sourceref();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(58)) goto parse_functionDisplayName;
- break;
- }
-
- // optional bytes functionDisplayName = 7;
- case 7: {
- if (tag == 58) {
- parse_functionDisplayName:
- DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
- input, this->mutable_functiondisplayname()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(64)) goto parse_functionDisplayNameRef;
- break;
- }
-
- // optional uint64 functionDisplayNameRef = 8;
- case 8: {
- if (tag == 64) {
- parse_functionDisplayNameRef:
- clear_FunctionDisplayNameOrRef();
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &FunctionDisplayNameOrRef_.functiondisplaynameref_)));
- set_has_functiondisplaynameref();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(72)) goto parse_isSystem;
- break;
- }
-
- // optional bool isSystem = 9;
- case 9: {
- if (tag == 72) {
- parse_isSystem:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
- input, &issystem_)));
- set_has_issystem();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(80)) goto parse_isSelfHosted;
- break;
- }
-
- // optional bool isSelfHosted = 10;
- case 10: {
- if (tag == 80) {
- parse_isSelfHosted:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
- input, &isselfhosted_)));
- set_has_isselfhosted();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectAtEnd()) goto success;
- break;
- }
-
- default: {
- handle_unusual:
- if (tag == 0 ||
- ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- goto success;
- }
- DO_(::google::protobuf::internal::WireFormat::SkipField(
- input, tag, mutable_unknown_fields()));
- break;
- }
- }
- }
-success:
- // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.StackFrame.Data)
- return true;
-failure:
- // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.StackFrame.Data)
- return false;
-#undef DO_
-}
-
-void StackFrame_Data::SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const {
- // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.StackFrame.Data)
- // optional uint64 id = 1;
- if (has_id()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->id(), output);
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame parent = 2;
- if (has_parent()) {
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
- 2, this->parent(), output);
- }
-
- // optional uint32 line = 3;
- if (has_line()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->line(), output);
- }
-
- // optional uint32 column = 4;
- if (has_column()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->column(), output);
- }
-
- // optional bytes source = 5;
- if (has_source()) {
- ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
- 5, this->source(), output);
- }
-
- // optional uint64 sourceRef = 6;
- if (has_sourceref()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(6, this->sourceref(), output);
- }
-
- // optional bytes functionDisplayName = 7;
- if (has_functiondisplayname()) {
- ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
- 7, this->functiondisplayname(), output);
- }
-
- // optional uint64 functionDisplayNameRef = 8;
- if (has_functiondisplaynameref()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->functiondisplaynameref(), output);
- }
-
- // optional bool isSystem = 9;
- if (has_issystem()) {
- ::google::protobuf::internal::WireFormatLite::WriteBool(9, this->issystem(), output);
- }
-
- // optional bool isSelfHosted = 10;
- if (has_isselfhosted()) {
- ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->isselfhosted(), output);
- }
-
- if (!unknown_fields().empty()) {
- ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
- unknown_fields(), output);
- }
- // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.StackFrame.Data)
-}
-
-::google::protobuf::uint8* StackFrame_Data::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
- // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.StackFrame.Data)
- // optional uint64 id = 1;
- if (has_id()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->id(), target);
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame parent = 2;
- if (has_parent()) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->parent(), target);
- }
-
- // optional uint32 line = 3;
- if (has_line()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->line(), target);
- }
-
- // optional uint32 column = 4;
- if (has_column()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->column(), target);
- }
-
- // optional bytes source = 5;
- if (has_source()) {
- target =
- ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
- 5, this->source(), target);
- }
-
- // optional uint64 sourceRef = 6;
- if (has_sourceref()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(6, this->sourceref(), target);
- }
-
- // optional bytes functionDisplayName = 7;
- if (has_functiondisplayname()) {
- target =
- ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
- 7, this->functiondisplayname(), target);
- }
-
- // optional uint64 functionDisplayNameRef = 8;
- if (has_functiondisplaynameref()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(8, this->functiondisplaynameref(), target);
- }
-
- // optional bool isSystem = 9;
- if (has_issystem()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(9, this->issystem(), target);
- }
-
- // optional bool isSelfHosted = 10;
- if (has_isselfhosted()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->isselfhosted(), target);
- }
-
- if (!unknown_fields().empty()) {
- target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
- unknown_fields(), target);
- }
- // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.StackFrame.Data)
- return target;
-}
-
-int StackFrame_Data::ByteSize() const {
- int total_size = 0;
-
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // optional uint64 id = 1;
- if (has_id()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->id());
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame parent = 2;
- if (has_parent()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
- this->parent());
- }
-
- // optional uint32 line = 3;
- if (has_line()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->line());
- }
-
- // optional uint32 column = 4;
- if (has_column()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->column());
- }
-
- }
- if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
- // optional bool isSystem = 9;
- if (has_issystem()) {
- total_size += 1 + 1;
- }
-
- // optional bool isSelfHosted = 10;
- if (has_isselfhosted()) {
- total_size += 1 + 1;
- }
-
- }
- switch (SourceOrRef_case()) {
- // optional bytes source = 5;
- case kSource: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::BytesSize(
- this->source());
- break;
- }
- // optional uint64 sourceRef = 6;
- case kSourceRef: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->sourceref());
- break;
- }
- case SOURCEORREF_NOT_SET: {
- break;
- }
- }
- switch (FunctionDisplayNameOrRef_case()) {
- // optional bytes functionDisplayName = 7;
- case kFunctionDisplayName: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::BytesSize(
- this->functiondisplayname());
- break;
- }
- // optional uint64 functionDisplayNameRef = 8;
- case kFunctionDisplayNameRef: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->functiondisplaynameref());
- break;
- }
- case FUNCTIONDISPLAYNAMEORREF_NOT_SET: {
- break;
- }
- }
- if (!unknown_fields().empty()) {
- total_size +=
- ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
- unknown_fields());
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = total_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- return total_size;
-}
-
-void StackFrame_Data::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const StackFrame_Data* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const StackFrame_Data*>(
- &from);
- if (source == NULL) {
- ::google::protobuf::internal::ReflectionOps::Merge(from, this);
- } else {
- MergeFrom(*source);
- }
-}
-
-void StackFrame_Data::MergeFrom(const StackFrame_Data& from) {
- GOOGLE_CHECK_NE(&from, this);
- switch (from.SourceOrRef_case()) {
- case kSource: {
- set_source(from.source());
- break;
- }
- case kSourceRef: {
- set_sourceref(from.sourceref());
- break;
- }
- case SOURCEORREF_NOT_SET: {
- break;
- }
- }
- switch (from.FunctionDisplayNameOrRef_case()) {
- case kFunctionDisplayName: {
- set_functiondisplayname(from.functiondisplayname());
- break;
- }
- case kFunctionDisplayNameRef: {
- set_functiondisplaynameref(from.functiondisplaynameref());
- break;
- }
- case FUNCTIONDISPLAYNAMEORREF_NOT_SET: {
- break;
- }
- }
- if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from.has_id()) {
- set_id(from.id());
- }
- if (from.has_parent()) {
- mutable_parent()->::mozilla::devtools::protobuf::StackFrame::MergeFrom(from.parent());
- }
- if (from.has_line()) {
- set_line(from.line());
- }
- if (from.has_column()) {
- set_column(from.column());
- }
- }
- if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
- if (from.has_issystem()) {
- set_issystem(from.issystem());
- }
- if (from.has_isselfhosted()) {
- set_isselfhosted(from.isselfhosted());
- }
- }
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
-}
-
-void StackFrame_Data::CopyFrom(const ::google::protobuf::Message& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-void StackFrame_Data::CopyFrom(const StackFrame_Data& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-bool StackFrame_Data::IsInitialized() const {
-
- return true;
-}
-
-void StackFrame_Data::Swap(StackFrame_Data* other) {
- if (other != this) {
- std::swap(id_, other->id_);
- std::swap(parent_, other->parent_);
- std::swap(line_, other->line_);
- std::swap(column_, other->column_);
- std::swap(issystem_, other->issystem_);
- std::swap(isselfhosted_, other->isselfhosted_);
- std::swap(SourceOrRef_, other->SourceOrRef_);
- std::swap(_oneof_case_[0], other->_oneof_case_[0]);
- std::swap(FunctionDisplayNameOrRef_, other->FunctionDisplayNameOrRef_);
- std::swap(_oneof_case_[1], other->_oneof_case_[1]);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
-}
-
-::google::protobuf::Metadata StackFrame_Data::GetMetadata() const {
- protobuf_AssignDescriptorsOnce();
- ::google::protobuf::Metadata metadata;
- metadata.descriptor = StackFrame_Data_descriptor_;
- metadata.reflection = StackFrame_Data_reflection_;
- return metadata;
-}
-
-
-// -------------------------------------------------------------------
-
-#ifndef _MSC_VER
-const int StackFrame::kDataFieldNumber;
-const int StackFrame::kRefFieldNumber;
-#endif // !_MSC_VER
-
-StackFrame::StackFrame()
- : ::google::protobuf::Message() {
- SharedCtor();
- // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.StackFrame)
-}
-
-void StackFrame::InitAsDefaultInstance() {
- StackFrame_default_oneof_instance_->data_ = const_cast< ::mozilla::devtools::protobuf::StackFrame_Data*>(&::mozilla::devtools::protobuf::StackFrame_Data::default_instance());
- StackFrame_default_oneof_instance_->ref_ = GOOGLE_ULONGLONG(0);
-}
-
-StackFrame::StackFrame(const StackFrame& from)
- : ::google::protobuf::Message() {
- SharedCtor();
- MergeFrom(from);
- // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.StackFrame)
-}
-
-void StackFrame::SharedCtor() {
- _cached_size_ = 0;
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- clear_has_StackFrameType();
-}
-
-StackFrame::~StackFrame() {
- // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.StackFrame)
- SharedDtor();
-}
-
-void StackFrame::SharedDtor() {
- if (has_StackFrameType()) {
- clear_StackFrameType();
- }
- if (this != default_instance_) {
- }
-}
-
-void StackFrame::SetCachedSize(int size) const {
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
-}
-const ::google::protobuf::Descriptor* StackFrame::descriptor() {
- protobuf_AssignDescriptorsOnce();
- return StackFrame_descriptor_;
-}
-
-const StackFrame& StackFrame::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
- return *default_instance_;
-}
-
-StackFrame* StackFrame::default_instance_ = NULL;
-
-StackFrame* StackFrame::New() const {
- return new StackFrame;
-}
-
-void StackFrame::clear_StackFrameType() {
- switch(StackFrameType_case()) {
- case kData: {
- delete StackFrameType_.data_;
- break;
- }
- case kRef: {
- // No need to clear
- break;
- }
- case STACKFRAMETYPE_NOT_SET: {
- break;
- }
- }
- _oneof_case_[0] = STACKFRAMETYPE_NOT_SET;
-}
-
-
-void StackFrame::Clear() {
- clear_StackFrameType();
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
-}
-
-bool StackFrame::MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
- ::google::protobuf::uint32 tag;
- // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.StackFrame)
- for (;;) {
- ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
- tag = p.first;
- if (!p.second) goto handle_unusual;
- switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
- // optional .mozilla.devtools.protobuf.StackFrame.Data data = 1;
- case 1: {
- if (tag == 10) {
- DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
- input, mutable_data()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(16)) goto parse_ref;
- break;
- }
-
- // optional uint64 ref = 2;
- case 2: {
- if (tag == 16) {
- parse_ref:
- clear_StackFrameType();
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &StackFrameType_.ref_)));
- set_has_ref();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectAtEnd()) goto success;
- break;
- }
-
- default: {
- handle_unusual:
- if (tag == 0 ||
- ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- goto success;
- }
- DO_(::google::protobuf::internal::WireFormat::SkipField(
- input, tag, mutable_unknown_fields()));
- break;
- }
- }
- }
-success:
- // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.StackFrame)
- return true;
-failure:
- // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.StackFrame)
- return false;
-#undef DO_
-}
-
-void StackFrame::SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const {
- // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.StackFrame)
- // optional .mozilla.devtools.protobuf.StackFrame.Data data = 1;
- if (has_data()) {
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
- 1, this->data(), output);
- }
-
- // optional uint64 ref = 2;
- if (has_ref()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->ref(), output);
- }
-
- if (!unknown_fields().empty()) {
- ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
- unknown_fields(), output);
- }
- // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.StackFrame)
-}
-
-::google::protobuf::uint8* StackFrame::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
- // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.StackFrame)
- // optional .mozilla.devtools.protobuf.StackFrame.Data data = 1;
- if (has_data()) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 1, this->data(), target);
- }
-
- // optional uint64 ref = 2;
- if (has_ref()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->ref(), target);
- }
-
- if (!unknown_fields().empty()) {
- target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
- unknown_fields(), target);
- }
- // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.StackFrame)
- return target;
-}
-
-int StackFrame::ByteSize() const {
- int total_size = 0;
-
- switch (StackFrameType_case()) {
- // optional .mozilla.devtools.protobuf.StackFrame.Data data = 1;
- case kData: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
- this->data());
- break;
- }
- // optional uint64 ref = 2;
- case kRef: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->ref());
- break;
- }
- case STACKFRAMETYPE_NOT_SET: {
- break;
- }
- }
- if (!unknown_fields().empty()) {
- total_size +=
- ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
- unknown_fields());
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = total_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- return total_size;
-}
-
-void StackFrame::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const StackFrame* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const StackFrame*>(
- &from);
- if (source == NULL) {
- ::google::protobuf::internal::ReflectionOps::Merge(from, this);
- } else {
- MergeFrom(*source);
- }
-}
-
-void StackFrame::MergeFrom(const StackFrame& from) {
- GOOGLE_CHECK_NE(&from, this);
- switch (from.StackFrameType_case()) {
- case kData: {
- mutable_data()->::mozilla::devtools::protobuf::StackFrame_Data::MergeFrom(from.data());
- break;
- }
- case kRef: {
- set_ref(from.ref());
- break;
- }
- case STACKFRAMETYPE_NOT_SET: {
- break;
- }
- }
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
-}
-
-void StackFrame::CopyFrom(const ::google::protobuf::Message& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-void StackFrame::CopyFrom(const StackFrame& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-bool StackFrame::IsInitialized() const {
-
- return true;
-}
-
-void StackFrame::Swap(StackFrame* other) {
- if (other != this) {
- std::swap(StackFrameType_, other->StackFrameType_);
- std::swap(_oneof_case_[0], other->_oneof_case_[0]);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
-}
-
-::google::protobuf::Metadata StackFrame::GetMetadata() const {
- protobuf_AssignDescriptorsOnce();
- ::google::protobuf::Metadata metadata;
- metadata.descriptor = StackFrame_descriptor_;
- metadata.reflection = StackFrame_reflection_;
- return metadata;
-}
-
-
-// ===================================================================
-
-#ifndef _MSC_VER
-const int Node::kIdFieldNumber;
-const int Node::kTypeNameFieldNumber;
-const int Node::kTypeNameRefFieldNumber;
-const int Node::kSizeFieldNumber;
-const int Node::kEdgesFieldNumber;
-const int Node::kAllocationStackFieldNumber;
-const int Node::kJsObjectClassNameFieldNumber;
-const int Node::kJsObjectClassNameRefFieldNumber;
-const int Node::kCoarseTypeFieldNumber;
-const int Node::kScriptFilenameFieldNumber;
-const int Node::kScriptFilenameRefFieldNumber;
-#endif // !_MSC_VER
-
-Node::Node()
- : ::google::protobuf::Message() {
- SharedCtor();
- // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Node)
-}
-
-void Node::InitAsDefaultInstance() {
- Node_default_oneof_instance_->typename__ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
- Node_default_oneof_instance_->typenameref_ = GOOGLE_ULONGLONG(0);
- allocationstack_ = const_cast< ::mozilla::devtools::protobuf::StackFrame*>(&::mozilla::devtools::protobuf::StackFrame::default_instance());
- Node_default_oneof_instance_->jsobjectclassname_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
- Node_default_oneof_instance_->jsobjectclassnameref_ = GOOGLE_ULONGLONG(0);
- Node_default_oneof_instance_->scriptfilename_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
- Node_default_oneof_instance_->scriptfilenameref_ = GOOGLE_ULONGLONG(0);
-}
-
-Node::Node(const Node& from)
- : ::google::protobuf::Message() {
- SharedCtor();
- MergeFrom(from);
- // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Node)
-}
-
-void Node::SharedCtor() {
- ::google::protobuf::internal::GetEmptyString();
- _cached_size_ = 0;
- id_ = GOOGLE_ULONGLONG(0);
- size_ = GOOGLE_ULONGLONG(0);
- allocationstack_ = NULL;
- coarsetype_ = 0u;
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- clear_has_TypeNameOrRef();
- clear_has_JSObjectClassNameOrRef();
- clear_has_ScriptFilenameOrRef();
-}
-
-Node::~Node() {
- // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Node)
- SharedDtor();
-}
-
-void Node::SharedDtor() {
- if (has_TypeNameOrRef()) {
- clear_TypeNameOrRef();
- }
- if (has_JSObjectClassNameOrRef()) {
- clear_JSObjectClassNameOrRef();
- }
- if (has_ScriptFilenameOrRef()) {
- clear_ScriptFilenameOrRef();
- }
- if (this != default_instance_) {
- delete allocationstack_;
- }
-}
-
-void Node::SetCachedSize(int size) const {
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
-}
-const ::google::protobuf::Descriptor* Node::descriptor() {
- protobuf_AssignDescriptorsOnce();
- return Node_descriptor_;
-}
-
-const Node& Node::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
- return *default_instance_;
-}
-
-Node* Node::default_instance_ = NULL;
-
-Node* Node::New() const {
- return new Node;
-}
-
-void Node::clear_TypeNameOrRef() {
- switch(TypeNameOrRef_case()) {
- case kTypeName: {
- delete TypeNameOrRef_.typename__;
- break;
- }
- case kTypeNameRef: {
- // No need to clear
- break;
- }
- case TYPENAMEORREF_NOT_SET: {
- break;
- }
- }
- _oneof_case_[0] = TYPENAMEORREF_NOT_SET;
-}
-
-void Node::clear_JSObjectClassNameOrRef() {
- switch(JSObjectClassNameOrRef_case()) {
- case kJsObjectClassName: {
- delete JSObjectClassNameOrRef_.jsobjectclassname_;
- break;
- }
- case kJsObjectClassNameRef: {
- // No need to clear
- break;
- }
- case JSOBJECTCLASSNAMEORREF_NOT_SET: {
- break;
- }
- }
- _oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET;
-}
-
-void Node::clear_ScriptFilenameOrRef() {
- switch(ScriptFilenameOrRef_case()) {
- case kScriptFilename: {
- delete ScriptFilenameOrRef_.scriptfilename_;
- break;
- }
- case kScriptFilenameRef: {
- // No need to clear
- break;
- }
- case SCRIPTFILENAMEORREF_NOT_SET: {
- break;
- }
- }
- _oneof_case_[2] = SCRIPTFILENAMEORREF_NOT_SET;
-}
-
-
-void Node::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
- &reinterpret_cast<Node*>(16)->f) - \
- reinterpret_cast<char*>(16))
-
-#define ZR_(first, last) do { \
- size_t f = OFFSET_OF_FIELD_(first); \
- size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \
- ::memset(&first, 0, n); \
- } while (0)
-
- if (_has_bits_[0 / 32] & 41) {
- ZR_(id_, size_);
- if (has_allocationstack()) {
- if (allocationstack_ != NULL) allocationstack_->::mozilla::devtools::protobuf::StackFrame::Clear();
- }
- }
- coarsetype_ = 0u;
-
-#undef OFFSET_OF_FIELD_
-#undef ZR_
-
- edges_.Clear();
- clear_TypeNameOrRef();
- clear_JSObjectClassNameOrRef();
- clear_ScriptFilenameOrRef();
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
-}
-
-bool Node::MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
- ::google::protobuf::uint32 tag;
- // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.Node)
- for (;;) {
- ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
- tag = p.first;
- if (!p.second) goto handle_unusual;
- switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
- // optional uint64 id = 1;
- case 1: {
- if (tag == 8) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &id_)));
- set_has_id();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(18)) goto parse_typeName;
- break;
- }
-
- // optional bytes typeName = 2;
- case 2: {
- if (tag == 18) {
- parse_typeName:
- DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
- input, this->mutable_typename_()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(24)) goto parse_typeNameRef;
- break;
- }
-
- // optional uint64 typeNameRef = 3;
- case 3: {
- if (tag == 24) {
- parse_typeNameRef:
- clear_TypeNameOrRef();
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &TypeNameOrRef_.typenameref_)));
- set_has_typenameref();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(32)) goto parse_size;
- break;
- }
-
- // optional uint64 size = 4;
- case 4: {
- if (tag == 32) {
- parse_size:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &size_)));
- set_has_size();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(42)) goto parse_edges;
- break;
- }
-
- // repeated .mozilla.devtools.protobuf.Edge edges = 5;
- case 5: {
- if (tag == 42) {
- parse_edges:
- DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
- input, add_edges()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(42)) goto parse_edges;
- if (input->ExpectTag(50)) goto parse_allocationStack;
- break;
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
- case 6: {
- if (tag == 50) {
- parse_allocationStack:
- DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
- input, mutable_allocationstack()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(58)) goto parse_jsObjectClassName;
- break;
- }
-
- // optional bytes jsObjectClassName = 7;
- case 7: {
- if (tag == 58) {
- parse_jsObjectClassName:
- DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
- input, this->mutable_jsobjectclassname()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(64)) goto parse_jsObjectClassNameRef;
- break;
- }
-
- // optional uint64 jsObjectClassNameRef = 8;
- case 8: {
- if (tag == 64) {
- parse_jsObjectClassNameRef:
- clear_JSObjectClassNameOrRef();
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &JSObjectClassNameOrRef_.jsobjectclassnameref_)));
- set_has_jsobjectclassnameref();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(72)) goto parse_coarseType;
- break;
- }
-
- // optional uint32 coarseType = 9 [default = 0];
- case 9: {
- if (tag == 72) {
- parse_coarseType:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
- input, &coarsetype_)));
- set_has_coarsetype();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(82)) goto parse_scriptFilename;
- break;
- }
-
- // optional bytes scriptFilename = 10;
- case 10: {
- if (tag == 82) {
- parse_scriptFilename:
- DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
- input, this->mutable_scriptfilename()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(88)) goto parse_scriptFilenameRef;
- break;
- }
-
- // optional uint64 scriptFilenameRef = 11;
- case 11: {
- if (tag == 88) {
- parse_scriptFilenameRef:
- clear_ScriptFilenameOrRef();
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &ScriptFilenameOrRef_.scriptfilenameref_)));
- set_has_scriptfilenameref();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectAtEnd()) goto success;
- break;
- }
-
- default: {
- handle_unusual:
- if (tag == 0 ||
- ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- goto success;
- }
- DO_(::google::protobuf::internal::WireFormat::SkipField(
- input, tag, mutable_unknown_fields()));
- break;
- }
- }
- }
-success:
- // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.Node)
- return true;
-failure:
- // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.Node)
- return false;
-#undef DO_
-}
-
-void Node::SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const {
- // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.Node)
- // optional uint64 id = 1;
- if (has_id()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->id(), output);
- }
-
- // optional bytes typeName = 2;
- if (has_typename_()) {
- ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
- 2, this->typename_(), output);
- }
-
- // optional uint64 typeNameRef = 3;
- if (has_typenameref()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->typenameref(), output);
- }
-
- // optional uint64 size = 4;
- if (has_size()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->size(), output);
- }
-
- // repeated .mozilla.devtools.protobuf.Edge edges = 5;
- for (int i = 0; i < this->edges_size(); i++) {
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
- 5, this->edges(i), output);
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
- if (has_allocationstack()) {
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
- 6, this->allocationstack(), output);
- }
-
- // optional bytes jsObjectClassName = 7;
- if (has_jsobjectclassname()) {
- ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
- 7, this->jsobjectclassname(), output);
- }
-
- // optional uint64 jsObjectClassNameRef = 8;
- if (has_jsobjectclassnameref()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->jsobjectclassnameref(), output);
- }
-
- // optional uint32 coarseType = 9 [default = 0];
- if (has_coarsetype()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->coarsetype(), output);
- }
-
- // optional bytes scriptFilename = 10;
- if (has_scriptfilename()) {
- ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
- 10, this->scriptfilename(), output);
- }
-
- // optional uint64 scriptFilenameRef = 11;
- if (has_scriptfilenameref()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(11, this->scriptfilenameref(), output);
- }
-
- if (!unknown_fields().empty()) {
- ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
- unknown_fields(), output);
- }
- // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Node)
-}
-
-::google::protobuf::uint8* Node::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
- // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.Node)
- // optional uint64 id = 1;
- if (has_id()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->id(), target);
- }
-
- // optional bytes typeName = 2;
- if (has_typename_()) {
- target =
- ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
- 2, this->typename_(), target);
- }
-
- // optional uint64 typeNameRef = 3;
- if (has_typenameref()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->typenameref(), target);
- }
-
- // optional uint64 size = 4;
- if (has_size()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->size(), target);
- }
-
- // repeated .mozilla.devtools.protobuf.Edge edges = 5;
- for (int i = 0; i < this->edges_size(); i++) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 5, this->edges(i), target);
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
- if (has_allocationstack()) {
- target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 6, this->allocationstack(), target);
- }
-
- // optional bytes jsObjectClassName = 7;
- if (has_jsobjectclassname()) {
- target =
- ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
- 7, this->jsobjectclassname(), target);
- }
-
- // optional uint64 jsObjectClassNameRef = 8;
- if (has_jsobjectclassnameref()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(8, this->jsobjectclassnameref(), target);
- }
-
- // optional uint32 coarseType = 9 [default = 0];
- if (has_coarsetype()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(9, this->coarsetype(), target);
- }
-
- // optional bytes scriptFilename = 10;
- if (has_scriptfilename()) {
- target =
- ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
- 10, this->scriptfilename(), target);
- }
-
- // optional uint64 scriptFilenameRef = 11;
- if (has_scriptfilenameref()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(11, this->scriptfilenameref(), target);
- }
-
- if (!unknown_fields().empty()) {
- target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
- unknown_fields(), target);
- }
- // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Node)
- return target;
-}
-
-int Node::ByteSize() const {
- int total_size = 0;
-
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // optional uint64 id = 1;
- if (has_id()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->id());
- }
-
- // optional uint64 size = 4;
- if (has_size()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->size());
- }
-
- // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
- if (has_allocationstack()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
- this->allocationstack());
- }
-
- }
- if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
- // optional uint32 coarseType = 9 [default = 0];
- if (has_coarsetype()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt32Size(
- this->coarsetype());
- }
-
- }
- // repeated .mozilla.devtools.protobuf.Edge edges = 5;
- total_size += 1 * this->edges_size();
- for (int i = 0; i < this->edges_size(); i++) {
- total_size +=
- ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
- this->edges(i));
- }
-
- switch (TypeNameOrRef_case()) {
- // optional bytes typeName = 2;
- case kTypeName: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::BytesSize(
- this->typename_());
- break;
- }
- // optional uint64 typeNameRef = 3;
- case kTypeNameRef: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->typenameref());
- break;
- }
- case TYPENAMEORREF_NOT_SET: {
- break;
- }
- }
- switch (JSObjectClassNameOrRef_case()) {
- // optional bytes jsObjectClassName = 7;
- case kJsObjectClassName: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::BytesSize(
- this->jsobjectclassname());
- break;
- }
- // optional uint64 jsObjectClassNameRef = 8;
- case kJsObjectClassNameRef: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->jsobjectclassnameref());
- break;
- }
- case JSOBJECTCLASSNAMEORREF_NOT_SET: {
- break;
- }
- }
- switch (ScriptFilenameOrRef_case()) {
- // optional bytes scriptFilename = 10;
- case kScriptFilename: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::BytesSize(
- this->scriptfilename());
- break;
- }
- // optional uint64 scriptFilenameRef = 11;
- case kScriptFilenameRef: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->scriptfilenameref());
- break;
- }
- case SCRIPTFILENAMEORREF_NOT_SET: {
- break;
- }
- }
- if (!unknown_fields().empty()) {
- total_size +=
- ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
- unknown_fields());
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = total_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- return total_size;
-}
-
-void Node::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const Node* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const Node*>(
- &from);
- if (source == NULL) {
- ::google::protobuf::internal::ReflectionOps::Merge(from, this);
- } else {
- MergeFrom(*source);
- }
-}
-
-void Node::MergeFrom(const Node& from) {
- GOOGLE_CHECK_NE(&from, this);
- edges_.MergeFrom(from.edges_);
- switch (from.TypeNameOrRef_case()) {
- case kTypeName: {
- set_typename_(from.typename_());
- break;
- }
- case kTypeNameRef: {
- set_typenameref(from.typenameref());
- break;
- }
- case TYPENAMEORREF_NOT_SET: {
- break;
- }
- }
- switch (from.JSObjectClassNameOrRef_case()) {
- case kJsObjectClassName: {
- set_jsobjectclassname(from.jsobjectclassname());
- break;
- }
- case kJsObjectClassNameRef: {
- set_jsobjectclassnameref(from.jsobjectclassnameref());
- break;
- }
- case JSOBJECTCLASSNAMEORREF_NOT_SET: {
- break;
- }
- }
- switch (from.ScriptFilenameOrRef_case()) {
- case kScriptFilename: {
- set_scriptfilename(from.scriptfilename());
- break;
- }
- case kScriptFilenameRef: {
- set_scriptfilenameref(from.scriptfilenameref());
- break;
- }
- case SCRIPTFILENAMEORREF_NOT_SET: {
- break;
- }
- }
- if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from.has_id()) {
- set_id(from.id());
- }
- if (from.has_size()) {
- set_size(from.size());
- }
- if (from.has_allocationstack()) {
- mutable_allocationstack()->::mozilla::devtools::protobuf::StackFrame::MergeFrom(from.allocationstack());
- }
- }
- if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
- if (from.has_coarsetype()) {
- set_coarsetype(from.coarsetype());
- }
- }
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
-}
-
-void Node::CopyFrom(const ::google::protobuf::Message& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-void Node::CopyFrom(const Node& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-bool Node::IsInitialized() const {
-
- return true;
-}
-
-void Node::Swap(Node* other) {
- if (other != this) {
- std::swap(id_, other->id_);
- std::swap(size_, other->size_);
- edges_.Swap(&other->edges_);
- std::swap(allocationstack_, other->allocationstack_);
- std::swap(coarsetype_, other->coarsetype_);
- std::swap(TypeNameOrRef_, other->TypeNameOrRef_);
- std::swap(_oneof_case_[0], other->_oneof_case_[0]);
- std::swap(JSObjectClassNameOrRef_, other->JSObjectClassNameOrRef_);
- std::swap(_oneof_case_[1], other->_oneof_case_[1]);
- std::swap(ScriptFilenameOrRef_, other->ScriptFilenameOrRef_);
- std::swap(_oneof_case_[2], other->_oneof_case_[2]);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
-}
-
-::google::protobuf::Metadata Node::GetMetadata() const {
- protobuf_AssignDescriptorsOnce();
- ::google::protobuf::Metadata metadata;
- metadata.descriptor = Node_descriptor_;
- metadata.reflection = Node_reflection_;
- return metadata;
-}
-
-
-// ===================================================================
-
-#ifndef _MSC_VER
-const int Edge::kReferentFieldNumber;
-const int Edge::kNameFieldNumber;
-const int Edge::kNameRefFieldNumber;
-#endif // !_MSC_VER
-
-Edge::Edge()
- : ::google::protobuf::Message() {
- SharedCtor();
- // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Edge)
-}
-
-void Edge::InitAsDefaultInstance() {
- Edge_default_oneof_instance_->name_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
- Edge_default_oneof_instance_->nameref_ = GOOGLE_ULONGLONG(0);
-}
-
-Edge::Edge(const Edge& from)
- : ::google::protobuf::Message() {
- SharedCtor();
- MergeFrom(from);
- // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Edge)
-}
-
-void Edge::SharedCtor() {
- ::google::protobuf::internal::GetEmptyString();
- _cached_size_ = 0;
- referent_ = GOOGLE_ULONGLONG(0);
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- clear_has_EdgeNameOrRef();
-}
-
-Edge::~Edge() {
- // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Edge)
- SharedDtor();
-}
-
-void Edge::SharedDtor() {
- if (has_EdgeNameOrRef()) {
- clear_EdgeNameOrRef();
- }
- if (this != default_instance_) {
- }
-}
-
-void Edge::SetCachedSize(int size) const {
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
-}
-const ::google::protobuf::Descriptor* Edge::descriptor() {
- protobuf_AssignDescriptorsOnce();
- return Edge_descriptor_;
-}
-
-const Edge& Edge::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
- return *default_instance_;
-}
-
-Edge* Edge::default_instance_ = NULL;
-
-Edge* Edge::New() const {
- return new Edge;
-}
-
-void Edge::clear_EdgeNameOrRef() {
- switch(EdgeNameOrRef_case()) {
- case kName: {
- delete EdgeNameOrRef_.name_;
- break;
- }
- case kNameRef: {
- // No need to clear
- break;
- }
- case EDGENAMEORREF_NOT_SET: {
- break;
- }
- }
- _oneof_case_[0] = EDGENAMEORREF_NOT_SET;
-}
-
-
-void Edge::Clear() {
- referent_ = GOOGLE_ULONGLONG(0);
- clear_EdgeNameOrRef();
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
- mutable_unknown_fields()->Clear();
-}
-
-bool Edge::MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
- ::google::protobuf::uint32 tag;
- // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.Edge)
- for (;;) {
- ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
- tag = p.first;
- if (!p.second) goto handle_unusual;
- switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
- // optional uint64 referent = 1;
- case 1: {
- if (tag == 8) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &referent_)));
- set_has_referent();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(18)) goto parse_name;
- break;
- }
-
- // optional bytes name = 2;
- case 2: {
- if (tag == 18) {
- parse_name:
- DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
- input, this->mutable_name()));
- } else {
- goto handle_unusual;
- }
- if (input->ExpectTag(24)) goto parse_nameRef;
- break;
- }
-
- // optional uint64 nameRef = 3;
- case 3: {
- if (tag == 24) {
- parse_nameRef:
- clear_EdgeNameOrRef();
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
- input, &EdgeNameOrRef_.nameref_)));
- set_has_nameref();
- } else {
- goto handle_unusual;
- }
- if (input->ExpectAtEnd()) goto success;
- break;
- }
-
- default: {
- handle_unusual:
- if (tag == 0 ||
- ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- goto success;
- }
- DO_(::google::protobuf::internal::WireFormat::SkipField(
- input, tag, mutable_unknown_fields()));
- break;
- }
- }
- }
-success:
- // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.Edge)
- return true;
-failure:
- // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.Edge)
- return false;
-#undef DO_
-}
-
-void Edge::SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const {
- // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.Edge)
- // optional uint64 referent = 1;
- if (has_referent()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->referent(), output);
- }
-
- // optional bytes name = 2;
- if (has_name()) {
- ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
- 2, this->name(), output);
- }
-
- // optional uint64 nameRef = 3;
- if (has_nameref()) {
- ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->nameref(), output);
- }
-
- if (!unknown_fields().empty()) {
- ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
- unknown_fields(), output);
- }
- // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Edge)
-}
-
-::google::protobuf::uint8* Edge::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
- // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.Edge)
- // optional uint64 referent = 1;
- if (has_referent()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->referent(), target);
- }
-
- // optional bytes name = 2;
- if (has_name()) {
- target =
- ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
- 2, this->name(), target);
- }
-
- // optional uint64 nameRef = 3;
- if (has_nameref()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->nameref(), target);
- }
-
- if (!unknown_fields().empty()) {
- target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
- unknown_fields(), target);
- }
- // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Edge)
- return target;
-}
-
-int Edge::ByteSize() const {
- int total_size = 0;
-
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // optional uint64 referent = 1;
- if (has_referent()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->referent());
- }
-
- }
- switch (EdgeNameOrRef_case()) {
- // optional bytes name = 2;
- case kName: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::BytesSize(
- this->name());
- break;
- }
- // optional uint64 nameRef = 3;
- case kNameRef: {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::UInt64Size(
- this->nameref());
- break;
- }
- case EDGENAMEORREF_NOT_SET: {
- break;
- }
- }
- if (!unknown_fields().empty()) {
- total_size +=
- ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
- unknown_fields());
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = total_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- return total_size;
-}
-
-void Edge::MergeFrom(const ::google::protobuf::Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- const Edge* source =
- ::google::protobuf::internal::dynamic_cast_if_available<const Edge*>(
- &from);
- if (source == NULL) {
- ::google::protobuf::internal::ReflectionOps::Merge(from, this);
- } else {
- MergeFrom(*source);
- }
-}
-
-void Edge::MergeFrom(const Edge& from) {
- GOOGLE_CHECK_NE(&from, this);
- switch (from.EdgeNameOrRef_case()) {
- case kName: {
- set_name(from.name());
- break;
- }
- case kNameRef: {
- set_nameref(from.nameref());
- break;
- }
- case EDGENAMEORREF_NOT_SET: {
- break;
- }
- }
- if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from.has_referent()) {
- set_referent(from.referent());
- }
- }
- mutable_unknown_fields()->MergeFrom(from.unknown_fields());
-}
-
-void Edge::CopyFrom(const ::google::protobuf::Message& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-void Edge::CopyFrom(const Edge& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-bool Edge::IsInitialized() const {
-
- return true;
-}
-
-void Edge::Swap(Edge* other) {
- if (other != this) {
- std::swap(referent_, other->referent_);
- std::swap(EdgeNameOrRef_, other->EdgeNameOrRef_);
- std::swap(_oneof_case_[0], other->_oneof_case_[0]);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- _unknown_fields_.Swap(&other->_unknown_fields_);
- std::swap(_cached_size_, other->_cached_size_);
- }
-}
-
-::google::protobuf::Metadata Edge::GetMetadata() const {
- protobuf_AssignDescriptorsOnce();
- ::google::protobuf::Metadata metadata;
- metadata.descriptor = Edge_descriptor_;
- metadata.reflection = Edge_reflection_;
- return metadata;
-}
-
-
-// @@protoc_insertion_point(namespace_scope)
-
-} // namespace protobuf
-} // namespace devtools
-} // namespace mozilla
-
-// @@protoc_insertion_point(global_scope)
diff --git a/devtools/shared/heapsnapshot/CoreDump.pb.h b/devtools/shared/heapsnapshot/CoreDump.pb.h
deleted file mode 100644
index 584c2e379..000000000
--- a/devtools/shared/heapsnapshot/CoreDump.pb.h
+++ /dev/null
@@ -1,1893 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: CoreDump.proto
-
-#ifndef PROTOBUF_CoreDump_2eproto__INCLUDED
-#define PROTOBUF_CoreDump_2eproto__INCLUDED
-
-#include <string>
-
-#include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 2006000
-#error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers. Please update
-#error your headers.
-#endif
-#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
-#error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers. Please
-#error regenerate this file with a newer version of protoc.
-#endif
-
-#include <google/protobuf/generated_message_util.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/repeated_field.h>
-#include <google/protobuf/extension_set.h>
-#include <google/protobuf/unknown_field_set.h>
-// @@protoc_insertion_point(includes)
-
-namespace mozilla {
-namespace devtools {
-namespace protobuf {
-
-// Internal implementation detail -- do not call these.
-void protobuf_AddDesc_CoreDump_2eproto();
-void protobuf_AssignDesc_CoreDump_2eproto();
-void protobuf_ShutdownFile_CoreDump_2eproto();
-
-class Metadata;
-class StackFrame;
-class StackFrame_Data;
-class Node;
-class Edge;
-
-// ===================================================================
-
-class Metadata : public ::google::protobuf::Message {
- public:
- Metadata();
- virtual ~Metadata();
-
- Metadata(const Metadata& from);
-
- inline Metadata& operator=(const Metadata& from) {
- CopyFrom(from);
- return *this;
- }
-
- inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
- }
-
- inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
- }
-
- static const ::google::protobuf::Descriptor* descriptor();
- static const Metadata& default_instance();
-
- void Swap(Metadata* other);
-
- // implements Message ----------------------------------------------
-
- Metadata* New() const;
- void CopyFrom(const ::google::protobuf::Message& from);
- void MergeFrom(const ::google::protobuf::Message& from);
- void CopyFrom(const Metadata& from);
- void MergeFrom(const Metadata& from);
- void Clear();
- bool IsInitialized() const;
-
- int ByteSize() const;
- bool MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input);
- void SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
- int GetCachedSize() const { return _cached_size_; }
- private:
- void SharedCtor();
- void SharedDtor();
- void SetCachedSize(int size) const;
- public:
- ::google::protobuf::Metadata GetMetadata() const;
-
- // nested types ----------------------------------------------------
-
- // accessors -------------------------------------------------------
-
- // optional uint64 timeStamp = 1;
- inline bool has_timestamp() const;
- inline void clear_timestamp();
- static const int kTimeStampFieldNumber = 1;
- inline ::google::protobuf::uint64 timestamp() const;
- inline void set_timestamp(::google::protobuf::uint64 value);
-
- // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Metadata)
- private:
- inline void set_has_timestamp();
- inline void clear_has_timestamp();
-
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
- ::google::protobuf::uint32 _has_bits_[1];
- mutable int _cached_size_;
- ::google::protobuf::uint64 timestamp_;
- friend void protobuf_AddDesc_CoreDump_2eproto();
- friend void protobuf_AssignDesc_CoreDump_2eproto();
- friend void protobuf_ShutdownFile_CoreDump_2eproto();
-
- void InitAsDefaultInstance();
- static Metadata* default_instance_;
-};
-// -------------------------------------------------------------------
-
-class StackFrame_Data : public ::google::protobuf::Message {
- public:
- StackFrame_Data();
- virtual ~StackFrame_Data();
-
- StackFrame_Data(const StackFrame_Data& from);
-
- inline StackFrame_Data& operator=(const StackFrame_Data& from) {
- CopyFrom(from);
- return *this;
- }
-
- inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
- }
-
- inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
- }
-
- static const ::google::protobuf::Descriptor* descriptor();
- static const StackFrame_Data& default_instance();
-
- enum SourceOrRefCase {
- kSource = 5,
- kSourceRef = 6,
- SOURCEORREF_NOT_SET = 0,
- };
-
- enum FunctionDisplayNameOrRefCase {
- kFunctionDisplayName = 7,
- kFunctionDisplayNameRef = 8,
- FUNCTIONDISPLAYNAMEORREF_NOT_SET = 0,
- };
-
- void Swap(StackFrame_Data* other);
-
- // implements Message ----------------------------------------------
-
- StackFrame_Data* New() const;
- void CopyFrom(const ::google::protobuf::Message& from);
- void MergeFrom(const ::google::protobuf::Message& from);
- void CopyFrom(const StackFrame_Data& from);
- void MergeFrom(const StackFrame_Data& from);
- void Clear();
- bool IsInitialized() const;
-
- int ByteSize() const;
- bool MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input);
- void SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
- int GetCachedSize() const { return _cached_size_; }
- private:
- void SharedCtor();
- void SharedDtor();
- void SetCachedSize(int size) const;
- public:
- ::google::protobuf::Metadata GetMetadata() const;
-
- // nested types ----------------------------------------------------
-
- // accessors -------------------------------------------------------
-
- // optional uint64 id = 1;
- inline bool has_id() const;
- inline void clear_id();
- static const int kIdFieldNumber = 1;
- inline ::google::protobuf::uint64 id() const;
- inline void set_id(::google::protobuf::uint64 value);
-
- // optional .mozilla.devtools.protobuf.StackFrame parent = 2;
- inline bool has_parent() const;
- inline void clear_parent();
- static const int kParentFieldNumber = 2;
- inline const ::mozilla::devtools::protobuf::StackFrame& parent() const;
- inline ::mozilla::devtools::protobuf::StackFrame* mutable_parent();
- inline ::mozilla::devtools::protobuf::StackFrame* release_parent();
- inline void set_allocated_parent(::mozilla::devtools::protobuf::StackFrame* parent);
-
- // optional uint32 line = 3;
- inline bool has_line() const;
- inline void clear_line();
- static const int kLineFieldNumber = 3;
- inline ::google::protobuf::uint32 line() const;
- inline void set_line(::google::protobuf::uint32 value);
-
- // optional uint32 column = 4;
- inline bool has_column() const;
- inline void clear_column();
- static const int kColumnFieldNumber = 4;
- inline ::google::protobuf::uint32 column() const;
- inline void set_column(::google::protobuf::uint32 value);
-
- // optional bytes source = 5;
- inline bool has_source() const;
- inline void clear_source();
- static const int kSourceFieldNumber = 5;
- inline const ::std::string& source() const;
- inline void set_source(const ::std::string& value);
- inline void set_source(const char* value);
- inline void set_source(const void* value, size_t size);
- inline ::std::string* mutable_source();
- inline ::std::string* release_source();
- inline void set_allocated_source(::std::string* source);
-
- // optional uint64 sourceRef = 6;
- inline bool has_sourceref() const;
- inline void clear_sourceref();
- static const int kSourceRefFieldNumber = 6;
- inline ::google::protobuf::uint64 sourceref() const;
- inline void set_sourceref(::google::protobuf::uint64 value);
-
- // optional bytes functionDisplayName = 7;
- inline bool has_functiondisplayname() const;
- inline void clear_functiondisplayname();
- static const int kFunctionDisplayNameFieldNumber = 7;
- inline const ::std::string& functiondisplayname() const;
- inline void set_functiondisplayname(const ::std::string& value);
- inline void set_functiondisplayname(const char* value);
- inline void set_functiondisplayname(const void* value, size_t size);
- inline ::std::string* mutable_functiondisplayname();
- inline ::std::string* release_functiondisplayname();
- inline void set_allocated_functiondisplayname(::std::string* functiondisplayname);
-
- // optional uint64 functionDisplayNameRef = 8;
- inline bool has_functiondisplaynameref() const;
- inline void clear_functiondisplaynameref();
- static const int kFunctionDisplayNameRefFieldNumber = 8;
- inline ::google::protobuf::uint64 functiondisplaynameref() const;
- inline void set_functiondisplaynameref(::google::protobuf::uint64 value);
-
- // optional bool isSystem = 9;
- inline bool has_issystem() const;
- inline void clear_issystem();
- static const int kIsSystemFieldNumber = 9;
- inline bool issystem() const;
- inline void set_issystem(bool value);
-
- // optional bool isSelfHosted = 10;
- inline bool has_isselfhosted() const;
- inline void clear_isselfhosted();
- static const int kIsSelfHostedFieldNumber = 10;
- inline bool isselfhosted() const;
- inline void set_isselfhosted(bool value);
-
- inline SourceOrRefCase SourceOrRef_case() const;
- inline FunctionDisplayNameOrRefCase FunctionDisplayNameOrRef_case() const;
- // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.StackFrame.Data)
- private:
- inline void set_has_id();
- inline void clear_has_id();
- inline void set_has_parent();
- inline void clear_has_parent();
- inline void set_has_line();
- inline void clear_has_line();
- inline void set_has_column();
- inline void clear_has_column();
- inline void set_has_source();
- inline void set_has_sourceref();
- inline void set_has_functiondisplayname();
- inline void set_has_functiondisplaynameref();
- inline void set_has_issystem();
- inline void clear_has_issystem();
- inline void set_has_isselfhosted();
- inline void clear_has_isselfhosted();
-
- inline bool has_SourceOrRef();
- void clear_SourceOrRef();
- inline void clear_has_SourceOrRef();
-
- inline bool has_FunctionDisplayNameOrRef();
- void clear_FunctionDisplayNameOrRef();
- inline void clear_has_FunctionDisplayNameOrRef();
-
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
- ::google::protobuf::uint32 _has_bits_[1];
- mutable int _cached_size_;
- ::google::protobuf::uint64 id_;
- ::mozilla::devtools::protobuf::StackFrame* parent_;
- ::google::protobuf::uint32 line_;
- ::google::protobuf::uint32 column_;
- bool issystem_;
- bool isselfhosted_;
- union SourceOrRefUnion {
- ::std::string* source_;
- ::google::protobuf::uint64 sourceref_;
- } SourceOrRef_;
- union FunctionDisplayNameOrRefUnion {
- ::std::string* functiondisplayname_;
- ::google::protobuf::uint64 functiondisplaynameref_;
- } FunctionDisplayNameOrRef_;
- ::google::protobuf::uint32 _oneof_case_[2];
-
- friend void protobuf_AddDesc_CoreDump_2eproto();
- friend void protobuf_AssignDesc_CoreDump_2eproto();
- friend void protobuf_ShutdownFile_CoreDump_2eproto();
-
- void InitAsDefaultInstance();
- static StackFrame_Data* default_instance_;
-};
-// -------------------------------------------------------------------
-
-class StackFrame : public ::google::protobuf::Message {
- public:
- StackFrame();
- virtual ~StackFrame();
-
- StackFrame(const StackFrame& from);
-
- inline StackFrame& operator=(const StackFrame& from) {
- CopyFrom(from);
- return *this;
- }
-
- inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
- }
-
- inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
- }
-
- static const ::google::protobuf::Descriptor* descriptor();
- static const StackFrame& default_instance();
-
- enum StackFrameTypeCase {
- kData = 1,
- kRef = 2,
- STACKFRAMETYPE_NOT_SET = 0,
- };
-
- void Swap(StackFrame* other);
-
- // implements Message ----------------------------------------------
-
- StackFrame* New() const;
- void CopyFrom(const ::google::protobuf::Message& from);
- void MergeFrom(const ::google::protobuf::Message& from);
- void CopyFrom(const StackFrame& from);
- void MergeFrom(const StackFrame& from);
- void Clear();
- bool IsInitialized() const;
-
- int ByteSize() const;
- bool MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input);
- void SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
- int GetCachedSize() const { return _cached_size_; }
- private:
- void SharedCtor();
- void SharedDtor();
- void SetCachedSize(int size) const;
- public:
- ::google::protobuf::Metadata GetMetadata() const;
-
- // nested types ----------------------------------------------------
-
- typedef StackFrame_Data Data;
-
- // accessors -------------------------------------------------------
-
- // optional .mozilla.devtools.protobuf.StackFrame.Data data = 1;
- inline bool has_data() const;
- inline void clear_data();
- static const int kDataFieldNumber = 1;
- inline const ::mozilla::devtools::protobuf::StackFrame_Data& data() const;
- inline ::mozilla::devtools::protobuf::StackFrame_Data* mutable_data();
- inline ::mozilla::devtools::protobuf::StackFrame_Data* release_data();
- inline void set_allocated_data(::mozilla::devtools::protobuf::StackFrame_Data* data);
-
- // optional uint64 ref = 2;
- inline bool has_ref() const;
- inline void clear_ref();
- static const int kRefFieldNumber = 2;
- inline ::google::protobuf::uint64 ref() const;
- inline void set_ref(::google::protobuf::uint64 value);
-
- inline StackFrameTypeCase StackFrameType_case() const;
- // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.StackFrame)
- private:
- inline void set_has_data();
- inline void set_has_ref();
-
- inline bool has_StackFrameType();
- void clear_StackFrameType();
- inline void clear_has_StackFrameType();
-
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
- ::google::protobuf::uint32 _has_bits_[1];
- mutable int _cached_size_;
- union StackFrameTypeUnion {
- ::mozilla::devtools::protobuf::StackFrame_Data* data_;
- ::google::protobuf::uint64 ref_;
- } StackFrameType_;
- ::google::protobuf::uint32 _oneof_case_[1];
-
- friend void protobuf_AddDesc_CoreDump_2eproto();
- friend void protobuf_AssignDesc_CoreDump_2eproto();
- friend void protobuf_ShutdownFile_CoreDump_2eproto();
-
- void InitAsDefaultInstance();
- static StackFrame* default_instance_;
-};
-// -------------------------------------------------------------------
-
-class Node : public ::google::protobuf::Message {
- public:
- Node();
- virtual ~Node();
-
- Node(const Node& from);
-
- inline Node& operator=(const Node& from) {
- CopyFrom(from);
- return *this;
- }
-
- inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
- }
-
- inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
- }
-
- static const ::google::protobuf::Descriptor* descriptor();
- static const Node& default_instance();
-
- enum TypeNameOrRefCase {
- kTypeName = 2,
- kTypeNameRef = 3,
- TYPENAMEORREF_NOT_SET = 0,
- };
-
- enum JSObjectClassNameOrRefCase {
- kJsObjectClassName = 7,
- kJsObjectClassNameRef = 8,
- JSOBJECTCLASSNAMEORREF_NOT_SET = 0,
- };
-
- enum ScriptFilenameOrRefCase {
- kScriptFilename = 10,
- kScriptFilenameRef = 11,
- SCRIPTFILENAMEORREF_NOT_SET = 0,
- };
-
- void Swap(Node* other);
-
- // implements Message ----------------------------------------------
-
- Node* New() const;
- void CopyFrom(const ::google::protobuf::Message& from);
- void MergeFrom(const ::google::protobuf::Message& from);
- void CopyFrom(const Node& from);
- void MergeFrom(const Node& from);
- void Clear();
- bool IsInitialized() const;
-
- int ByteSize() const;
- bool MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input);
- void SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
- int GetCachedSize() const { return _cached_size_; }
- private:
- void SharedCtor();
- void SharedDtor();
- void SetCachedSize(int size) const;
- public:
- ::google::protobuf::Metadata GetMetadata() const;
-
- // nested types ----------------------------------------------------
-
- // accessors -------------------------------------------------------
-
- // optional uint64 id = 1;
- inline bool has_id() const;
- inline void clear_id();
- static const int kIdFieldNumber = 1;
- inline ::google::protobuf::uint64 id() const;
- inline void set_id(::google::protobuf::uint64 value);
-
- // optional bytes typeName = 2;
- inline bool has_typename_() const;
- inline void clear_typename_();
- static const int kTypeNameFieldNumber = 2;
- inline const ::std::string& typename_() const;
- inline void set_typename_(const ::std::string& value);
- inline void set_typename_(const char* value);
- inline void set_typename_(const void* value, size_t size);
- inline ::std::string* mutable_typename_();
- inline ::std::string* release_typename_();
- inline void set_allocated_typename_(::std::string* typename_);
-
- // optional uint64 typeNameRef = 3;
- inline bool has_typenameref() const;
- inline void clear_typenameref();
- static const int kTypeNameRefFieldNumber = 3;
- inline ::google::protobuf::uint64 typenameref() const;
- inline void set_typenameref(::google::protobuf::uint64 value);
-
- // optional uint64 size = 4;
- inline bool has_size() const;
- inline void clear_size();
- static const int kSizeFieldNumber = 4;
- inline ::google::protobuf::uint64 size() const;
- inline void set_size(::google::protobuf::uint64 value);
-
- // repeated .mozilla.devtools.protobuf.Edge edges = 5;
- inline int edges_size() const;
- inline void clear_edges();
- static const int kEdgesFieldNumber = 5;
- inline const ::mozilla::devtools::protobuf::Edge& edges(int index) const;
- inline ::mozilla::devtools::protobuf::Edge* mutable_edges(int index);
- inline ::mozilla::devtools::protobuf::Edge* add_edges();
- inline const ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >&
- edges() const;
- inline ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >*
- mutable_edges();
-
- // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
- inline bool has_allocationstack() const;
- inline void clear_allocationstack();
- static const int kAllocationStackFieldNumber = 6;
- inline const ::mozilla::devtools::protobuf::StackFrame& allocationstack() const;
- inline ::mozilla::devtools::protobuf::StackFrame* mutable_allocationstack();
- inline ::mozilla::devtools::protobuf::StackFrame* release_allocationstack();
- inline void set_allocated_allocationstack(::mozilla::devtools::protobuf::StackFrame* allocationstack);
-
- // optional bytes jsObjectClassName = 7;
- inline bool has_jsobjectclassname() const;
- inline void clear_jsobjectclassname();
- static const int kJsObjectClassNameFieldNumber = 7;
- inline const ::std::string& jsobjectclassname() const;
- inline void set_jsobjectclassname(const ::std::string& value);
- inline void set_jsobjectclassname(const char* value);
- inline void set_jsobjectclassname(const void* value, size_t size);
- inline ::std::string* mutable_jsobjectclassname();
- inline ::std::string* release_jsobjectclassname();
- inline void set_allocated_jsobjectclassname(::std::string* jsobjectclassname);
-
- // optional uint64 jsObjectClassNameRef = 8;
- inline bool has_jsobjectclassnameref() const;
- inline void clear_jsobjectclassnameref();
- static const int kJsObjectClassNameRefFieldNumber = 8;
- inline ::google::protobuf::uint64 jsobjectclassnameref() const;
- inline void set_jsobjectclassnameref(::google::protobuf::uint64 value);
-
- // optional uint32 coarseType = 9 [default = 0];
- inline bool has_coarsetype() const;
- inline void clear_coarsetype();
- static const int kCoarseTypeFieldNumber = 9;
- inline ::google::protobuf::uint32 coarsetype() const;
- inline void set_coarsetype(::google::protobuf::uint32 value);
-
- // optional bytes scriptFilename = 10;
- inline bool has_scriptfilename() const;
- inline void clear_scriptfilename();
- static const int kScriptFilenameFieldNumber = 10;
- inline const ::std::string& scriptfilename() const;
- inline void set_scriptfilename(const ::std::string& value);
- inline void set_scriptfilename(const char* value);
- inline void set_scriptfilename(const void* value, size_t size);
- inline ::std::string* mutable_scriptfilename();
- inline ::std::string* release_scriptfilename();
- inline void set_allocated_scriptfilename(::std::string* scriptfilename);
-
- // optional uint64 scriptFilenameRef = 11;
- inline bool has_scriptfilenameref() const;
- inline void clear_scriptfilenameref();
- static const int kScriptFilenameRefFieldNumber = 11;
- inline ::google::protobuf::uint64 scriptfilenameref() const;
- inline void set_scriptfilenameref(::google::protobuf::uint64 value);
-
- inline TypeNameOrRefCase TypeNameOrRef_case() const;
- inline JSObjectClassNameOrRefCase JSObjectClassNameOrRef_case() const;
- inline ScriptFilenameOrRefCase ScriptFilenameOrRef_case() const;
- // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Node)
- private:
- inline void set_has_id();
- inline void clear_has_id();
- inline void set_has_typename_();
- inline void set_has_typenameref();
- inline void set_has_size();
- inline void clear_has_size();
- inline void set_has_allocationstack();
- inline void clear_has_allocationstack();
- inline void set_has_jsobjectclassname();
- inline void set_has_jsobjectclassnameref();
- inline void set_has_coarsetype();
- inline void clear_has_coarsetype();
- inline void set_has_scriptfilename();
- inline void set_has_scriptfilenameref();
-
- inline bool has_TypeNameOrRef();
- void clear_TypeNameOrRef();
- inline void clear_has_TypeNameOrRef();
-
- inline bool has_JSObjectClassNameOrRef();
- void clear_JSObjectClassNameOrRef();
- inline void clear_has_JSObjectClassNameOrRef();
-
- inline bool has_ScriptFilenameOrRef();
- void clear_ScriptFilenameOrRef();
- inline void clear_has_ScriptFilenameOrRef();
-
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
- ::google::protobuf::uint32 _has_bits_[1];
- mutable int _cached_size_;
- ::google::protobuf::uint64 id_;
- ::google::protobuf::uint64 size_;
- ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge > edges_;
- ::mozilla::devtools::protobuf::StackFrame* allocationstack_;
- ::google::protobuf::uint32 coarsetype_;
- union TypeNameOrRefUnion {
- ::std::string* typename__;
- ::google::protobuf::uint64 typenameref_;
- } TypeNameOrRef_;
- union JSObjectClassNameOrRefUnion {
- ::std::string* jsobjectclassname_;
- ::google::protobuf::uint64 jsobjectclassnameref_;
- } JSObjectClassNameOrRef_;
- union ScriptFilenameOrRefUnion {
- ::std::string* scriptfilename_;
- ::google::protobuf::uint64 scriptfilenameref_;
- } ScriptFilenameOrRef_;
- ::google::protobuf::uint32 _oneof_case_[3];
-
- friend void protobuf_AddDesc_CoreDump_2eproto();
- friend void protobuf_AssignDesc_CoreDump_2eproto();
- friend void protobuf_ShutdownFile_CoreDump_2eproto();
-
- void InitAsDefaultInstance();
- static Node* default_instance_;
-};
-// -------------------------------------------------------------------
-
-class Edge : public ::google::protobuf::Message {
- public:
- Edge();
- virtual ~Edge();
-
- Edge(const Edge& from);
-
- inline Edge& operator=(const Edge& from) {
- CopyFrom(from);
- return *this;
- }
-
- inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
- return _unknown_fields_;
- }
-
- inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
- return &_unknown_fields_;
- }
-
- static const ::google::protobuf::Descriptor* descriptor();
- static const Edge& default_instance();
-
- enum EdgeNameOrRefCase {
- kName = 2,
- kNameRef = 3,
- EDGENAMEORREF_NOT_SET = 0,
- };
-
- void Swap(Edge* other);
-
- // implements Message ----------------------------------------------
-
- Edge* New() const;
- void CopyFrom(const ::google::protobuf::Message& from);
- void MergeFrom(const ::google::protobuf::Message& from);
- void CopyFrom(const Edge& from);
- void MergeFrom(const Edge& from);
- void Clear();
- bool IsInitialized() const;
-
- int ByteSize() const;
- bool MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input);
- void SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
- int GetCachedSize() const { return _cached_size_; }
- private:
- void SharedCtor();
- void SharedDtor();
- void SetCachedSize(int size) const;
- public:
- ::google::protobuf::Metadata GetMetadata() const;
-
- // nested types ----------------------------------------------------
-
- // accessors -------------------------------------------------------
-
- // optional uint64 referent = 1;
- inline bool has_referent() const;
- inline void clear_referent();
- static const int kReferentFieldNumber = 1;
- inline ::google::protobuf::uint64 referent() const;
- inline void set_referent(::google::protobuf::uint64 value);
-
- // optional bytes name = 2;
- inline bool has_name() const;
- inline void clear_name();
- static const int kNameFieldNumber = 2;
- inline const ::std::string& name() const;
- inline void set_name(const ::std::string& value);
- inline void set_name(const char* value);
- inline void set_name(const void* value, size_t size);
- inline ::std::string* mutable_name();
- inline ::std::string* release_name();
- inline void set_allocated_name(::std::string* name);
-
- // optional uint64 nameRef = 3;
- inline bool has_nameref() const;
- inline void clear_nameref();
- static const int kNameRefFieldNumber = 3;
- inline ::google::protobuf::uint64 nameref() const;
- inline void set_nameref(::google::protobuf::uint64 value);
-
- inline EdgeNameOrRefCase EdgeNameOrRef_case() const;
- // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Edge)
- private:
- inline void set_has_referent();
- inline void clear_has_referent();
- inline void set_has_name();
- inline void set_has_nameref();
-
- inline bool has_EdgeNameOrRef();
- void clear_EdgeNameOrRef();
- inline void clear_has_EdgeNameOrRef();
-
- ::google::protobuf::UnknownFieldSet _unknown_fields_;
-
- ::google::protobuf::uint32 _has_bits_[1];
- mutable int _cached_size_;
- ::google::protobuf::uint64 referent_;
- union EdgeNameOrRefUnion {
- ::std::string* name_;
- ::google::protobuf::uint64 nameref_;
- } EdgeNameOrRef_;
- ::google::protobuf::uint32 _oneof_case_[1];
-
- friend void protobuf_AddDesc_CoreDump_2eproto();
- friend void protobuf_AssignDesc_CoreDump_2eproto();
- friend void protobuf_ShutdownFile_CoreDump_2eproto();
-
- void InitAsDefaultInstance();
- static Edge* default_instance_;
-};
-// ===================================================================
-
-
-// ===================================================================
-
-// Metadata
-
-// optional uint64 timeStamp = 1;
-inline bool Metadata::has_timestamp() const {
- return (_has_bits_[0] & 0x00000001u) != 0;
-}
-inline void Metadata::set_has_timestamp() {
- _has_bits_[0] |= 0x00000001u;
-}
-inline void Metadata::clear_has_timestamp() {
- _has_bits_[0] &= ~0x00000001u;
-}
-inline void Metadata::clear_timestamp() {
- timestamp_ = GOOGLE_ULONGLONG(0);
- clear_has_timestamp();
-}
-inline ::google::protobuf::uint64 Metadata::timestamp() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Metadata.timeStamp)
- return timestamp_;
-}
-inline void Metadata::set_timestamp(::google::protobuf::uint64 value) {
- set_has_timestamp();
- timestamp_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Metadata.timeStamp)
-}
-
-// -------------------------------------------------------------------
-
-// StackFrame_Data
-
-// optional uint64 id = 1;
-inline bool StackFrame_Data::has_id() const {
- return (_has_bits_[0] & 0x00000001u) != 0;
-}
-inline void StackFrame_Data::set_has_id() {
- _has_bits_[0] |= 0x00000001u;
-}
-inline void StackFrame_Data::clear_has_id() {
- _has_bits_[0] &= ~0x00000001u;
-}
-inline void StackFrame_Data::clear_id() {
- id_ = GOOGLE_ULONGLONG(0);
- clear_has_id();
-}
-inline ::google::protobuf::uint64 StackFrame_Data::id() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.id)
- return id_;
-}
-inline void StackFrame_Data::set_id(::google::protobuf::uint64 value) {
- set_has_id();
- id_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.id)
-}
-
-// optional .mozilla.devtools.protobuf.StackFrame parent = 2;
-inline bool StackFrame_Data::has_parent() const {
- return (_has_bits_[0] & 0x00000002u) != 0;
-}
-inline void StackFrame_Data::set_has_parent() {
- _has_bits_[0] |= 0x00000002u;
-}
-inline void StackFrame_Data::clear_has_parent() {
- _has_bits_[0] &= ~0x00000002u;
-}
-inline void StackFrame_Data::clear_parent() {
- if (parent_ != NULL) parent_->::mozilla::devtools::protobuf::StackFrame::Clear();
- clear_has_parent();
-}
-inline const ::mozilla::devtools::protobuf::StackFrame& StackFrame_Data::parent() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.parent)
- return parent_ != NULL ? *parent_ : *default_instance_->parent_;
-}
-inline ::mozilla::devtools::protobuf::StackFrame* StackFrame_Data::mutable_parent() {
- set_has_parent();
- if (parent_ == NULL) parent_ = new ::mozilla::devtools::protobuf::StackFrame;
- // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.StackFrame.Data.parent)
- return parent_;
-}
-inline ::mozilla::devtools::protobuf::StackFrame* StackFrame_Data::release_parent() {
- clear_has_parent();
- ::mozilla::devtools::protobuf::StackFrame* temp = parent_;
- parent_ = NULL;
- return temp;
-}
-inline void StackFrame_Data::set_allocated_parent(::mozilla::devtools::protobuf::StackFrame* parent) {
- delete parent_;
- parent_ = parent;
- if (parent) {
- set_has_parent();
- } else {
- clear_has_parent();
- }
- // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.StackFrame.Data.parent)
-}
-
-// optional uint32 line = 3;
-inline bool StackFrame_Data::has_line() const {
- return (_has_bits_[0] & 0x00000004u) != 0;
-}
-inline void StackFrame_Data::set_has_line() {
- _has_bits_[0] |= 0x00000004u;
-}
-inline void StackFrame_Data::clear_has_line() {
- _has_bits_[0] &= ~0x00000004u;
-}
-inline void StackFrame_Data::clear_line() {
- line_ = 0u;
- clear_has_line();
-}
-inline ::google::protobuf::uint32 StackFrame_Data::line() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.line)
- return line_;
-}
-inline void StackFrame_Data::set_line(::google::protobuf::uint32 value) {
- set_has_line();
- line_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.line)
-}
-
-// optional uint32 column = 4;
-inline bool StackFrame_Data::has_column() const {
- return (_has_bits_[0] & 0x00000008u) != 0;
-}
-inline void StackFrame_Data::set_has_column() {
- _has_bits_[0] |= 0x00000008u;
-}
-inline void StackFrame_Data::clear_has_column() {
- _has_bits_[0] &= ~0x00000008u;
-}
-inline void StackFrame_Data::clear_column() {
- column_ = 0u;
- clear_has_column();
-}
-inline ::google::protobuf::uint32 StackFrame_Data::column() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.column)
- return column_;
-}
-inline void StackFrame_Data::set_column(::google::protobuf::uint32 value) {
- set_has_column();
- column_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.column)
-}
-
-// optional bytes source = 5;
-inline bool StackFrame_Data::has_source() const {
- return SourceOrRef_case() == kSource;
-}
-inline void StackFrame_Data::set_has_source() {
- _oneof_case_[0] = kSource;
-}
-inline void StackFrame_Data::clear_source() {
- if (has_source()) {
- delete SourceOrRef_.source_;
- clear_has_SourceOrRef();
- }
-}
-inline const ::std::string& StackFrame_Data::source() const {
- if (has_source()) {
- return *SourceOrRef_.source_;
- }
- return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
-}
-inline void StackFrame_Data::set_source(const ::std::string& value) {
- if (!has_source()) {
- clear_SourceOrRef();
- set_has_source();
- SourceOrRef_.source_ = new ::std::string;
- }
- SourceOrRef_.source_->assign(value);
-}
-inline void StackFrame_Data::set_source(const char* value) {
- if (!has_source()) {
- clear_SourceOrRef();
- set_has_source();
- SourceOrRef_.source_ = new ::std::string;
- }
- SourceOrRef_.source_->assign(value);
-}
-inline void StackFrame_Data::set_source(const void* value, size_t size) {
- if (!has_source()) {
- clear_SourceOrRef();
- set_has_source();
- SourceOrRef_.source_ = new ::std::string;
- }
- SourceOrRef_.source_->assign(
- reinterpret_cast<const char*>(value), size);
-}
-inline ::std::string* StackFrame_Data::mutable_source() {
- if (!has_source()) {
- clear_SourceOrRef();
- set_has_source();
- SourceOrRef_.source_ = new ::std::string;
- }
- return SourceOrRef_.source_;
-}
-inline ::std::string* StackFrame_Data::release_source() {
- if (has_source()) {
- clear_has_SourceOrRef();
- ::std::string* temp = SourceOrRef_.source_;
- SourceOrRef_.source_ = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-inline void StackFrame_Data::set_allocated_source(::std::string* source) {
- clear_SourceOrRef();
- if (source) {
- set_has_source();
- SourceOrRef_.source_ = source;
- }
-}
-
-// optional uint64 sourceRef = 6;
-inline bool StackFrame_Data::has_sourceref() const {
- return SourceOrRef_case() == kSourceRef;
-}
-inline void StackFrame_Data::set_has_sourceref() {
- _oneof_case_[0] = kSourceRef;
-}
-inline void StackFrame_Data::clear_sourceref() {
- if (has_sourceref()) {
- SourceOrRef_.sourceref_ = GOOGLE_ULONGLONG(0);
- clear_has_SourceOrRef();
- }
-}
-inline ::google::protobuf::uint64 StackFrame_Data::sourceref() const {
- if (has_sourceref()) {
- return SourceOrRef_.sourceref_;
- }
- return GOOGLE_ULONGLONG(0);
-}
-inline void StackFrame_Data::set_sourceref(::google::protobuf::uint64 value) {
- if (!has_sourceref()) {
- clear_SourceOrRef();
- set_has_sourceref();
- }
- SourceOrRef_.sourceref_ = value;
-}
-
-// optional bytes functionDisplayName = 7;
-inline bool StackFrame_Data::has_functiondisplayname() const {
- return FunctionDisplayNameOrRef_case() == kFunctionDisplayName;
-}
-inline void StackFrame_Data::set_has_functiondisplayname() {
- _oneof_case_[1] = kFunctionDisplayName;
-}
-inline void StackFrame_Data::clear_functiondisplayname() {
- if (has_functiondisplayname()) {
- delete FunctionDisplayNameOrRef_.functiondisplayname_;
- clear_has_FunctionDisplayNameOrRef();
- }
-}
-inline const ::std::string& StackFrame_Data::functiondisplayname() const {
- if (has_functiondisplayname()) {
- return *FunctionDisplayNameOrRef_.functiondisplayname_;
- }
- return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
-}
-inline void StackFrame_Data::set_functiondisplayname(const ::std::string& value) {
- if (!has_functiondisplayname()) {
- clear_FunctionDisplayNameOrRef();
- set_has_functiondisplayname();
- FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
- }
- FunctionDisplayNameOrRef_.functiondisplayname_->assign(value);
-}
-inline void StackFrame_Data::set_functiondisplayname(const char* value) {
- if (!has_functiondisplayname()) {
- clear_FunctionDisplayNameOrRef();
- set_has_functiondisplayname();
- FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
- }
- FunctionDisplayNameOrRef_.functiondisplayname_->assign(value);
-}
-inline void StackFrame_Data::set_functiondisplayname(const void* value, size_t size) {
- if (!has_functiondisplayname()) {
- clear_FunctionDisplayNameOrRef();
- set_has_functiondisplayname();
- FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
- }
- FunctionDisplayNameOrRef_.functiondisplayname_->assign(
- reinterpret_cast<const char*>(value), size);
-}
-inline ::std::string* StackFrame_Data::mutable_functiondisplayname() {
- if (!has_functiondisplayname()) {
- clear_FunctionDisplayNameOrRef();
- set_has_functiondisplayname();
- FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
- }
- return FunctionDisplayNameOrRef_.functiondisplayname_;
-}
-inline ::std::string* StackFrame_Data::release_functiondisplayname() {
- if (has_functiondisplayname()) {
- clear_has_FunctionDisplayNameOrRef();
- ::std::string* temp = FunctionDisplayNameOrRef_.functiondisplayname_;
- FunctionDisplayNameOrRef_.functiondisplayname_ = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-inline void StackFrame_Data::set_allocated_functiondisplayname(::std::string* functiondisplayname) {
- clear_FunctionDisplayNameOrRef();
- if (functiondisplayname) {
- set_has_functiondisplayname();
- FunctionDisplayNameOrRef_.functiondisplayname_ = functiondisplayname;
- }
-}
-
-// optional uint64 functionDisplayNameRef = 8;
-inline bool StackFrame_Data::has_functiondisplaynameref() const {
- return FunctionDisplayNameOrRef_case() == kFunctionDisplayNameRef;
-}
-inline void StackFrame_Data::set_has_functiondisplaynameref() {
- _oneof_case_[1] = kFunctionDisplayNameRef;
-}
-inline void StackFrame_Data::clear_functiondisplaynameref() {
- if (has_functiondisplaynameref()) {
- FunctionDisplayNameOrRef_.functiondisplaynameref_ = GOOGLE_ULONGLONG(0);
- clear_has_FunctionDisplayNameOrRef();
- }
-}
-inline ::google::protobuf::uint64 StackFrame_Data::functiondisplaynameref() const {
- if (has_functiondisplaynameref()) {
- return FunctionDisplayNameOrRef_.functiondisplaynameref_;
- }
- return GOOGLE_ULONGLONG(0);
-}
-inline void StackFrame_Data::set_functiondisplaynameref(::google::protobuf::uint64 value) {
- if (!has_functiondisplaynameref()) {
- clear_FunctionDisplayNameOrRef();
- set_has_functiondisplaynameref();
- }
- FunctionDisplayNameOrRef_.functiondisplaynameref_ = value;
-}
-
-// optional bool isSystem = 9;
-inline bool StackFrame_Data::has_issystem() const {
- return (_has_bits_[0] & 0x00000100u) != 0;
-}
-inline void StackFrame_Data::set_has_issystem() {
- _has_bits_[0] |= 0x00000100u;
-}
-inline void StackFrame_Data::clear_has_issystem() {
- _has_bits_[0] &= ~0x00000100u;
-}
-inline void StackFrame_Data::clear_issystem() {
- issystem_ = false;
- clear_has_issystem();
-}
-inline bool StackFrame_Data::issystem() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.isSystem)
- return issystem_;
-}
-inline void StackFrame_Data::set_issystem(bool value) {
- set_has_issystem();
- issystem_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.isSystem)
-}
-
-// optional bool isSelfHosted = 10;
-inline bool StackFrame_Data::has_isselfhosted() const {
- return (_has_bits_[0] & 0x00000200u) != 0;
-}
-inline void StackFrame_Data::set_has_isselfhosted() {
- _has_bits_[0] |= 0x00000200u;
-}
-inline void StackFrame_Data::clear_has_isselfhosted() {
- _has_bits_[0] &= ~0x00000200u;
-}
-inline void StackFrame_Data::clear_isselfhosted() {
- isselfhosted_ = false;
- clear_has_isselfhosted();
-}
-inline bool StackFrame_Data::isselfhosted() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.isSelfHosted)
- return isselfhosted_;
-}
-inline void StackFrame_Data::set_isselfhosted(bool value) {
- set_has_isselfhosted();
- isselfhosted_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.isSelfHosted)
-}
-
-inline bool StackFrame_Data::has_SourceOrRef() {
- return SourceOrRef_case() != SOURCEORREF_NOT_SET;
-}
-inline void StackFrame_Data::clear_has_SourceOrRef() {
- _oneof_case_[0] = SOURCEORREF_NOT_SET;
-}
-inline bool StackFrame_Data::has_FunctionDisplayNameOrRef() {
- return FunctionDisplayNameOrRef_case() != FUNCTIONDISPLAYNAMEORREF_NOT_SET;
-}
-inline void StackFrame_Data::clear_has_FunctionDisplayNameOrRef() {
- _oneof_case_[1] = FUNCTIONDISPLAYNAMEORREF_NOT_SET;
-}
-inline StackFrame_Data::SourceOrRefCase StackFrame_Data::SourceOrRef_case() const {
- return StackFrame_Data::SourceOrRefCase(_oneof_case_[0]);
-}
-inline StackFrame_Data::FunctionDisplayNameOrRefCase StackFrame_Data::FunctionDisplayNameOrRef_case() const {
- return StackFrame_Data::FunctionDisplayNameOrRefCase(_oneof_case_[1]);
-}
-// -------------------------------------------------------------------
-
-// StackFrame
-
-// optional .mozilla.devtools.protobuf.StackFrame.Data data = 1;
-inline bool StackFrame::has_data() const {
- return StackFrameType_case() == kData;
-}
-inline void StackFrame::set_has_data() {
- _oneof_case_[0] = kData;
-}
-inline void StackFrame::clear_data() {
- if (has_data()) {
- delete StackFrameType_.data_;
- clear_has_StackFrameType();
- }
-}
-inline const ::mozilla::devtools::protobuf::StackFrame_Data& StackFrame::data() const {
- return has_data() ? *StackFrameType_.data_
- : ::mozilla::devtools::protobuf::StackFrame_Data::default_instance();
-}
-inline ::mozilla::devtools::protobuf::StackFrame_Data* StackFrame::mutable_data() {
- if (!has_data()) {
- clear_StackFrameType();
- set_has_data();
- StackFrameType_.data_ = new ::mozilla::devtools::protobuf::StackFrame_Data;
- }
- return StackFrameType_.data_;
-}
-inline ::mozilla::devtools::protobuf::StackFrame_Data* StackFrame::release_data() {
- if (has_data()) {
- clear_has_StackFrameType();
- ::mozilla::devtools::protobuf::StackFrame_Data* temp = StackFrameType_.data_;
- StackFrameType_.data_ = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-inline void StackFrame::set_allocated_data(::mozilla::devtools::protobuf::StackFrame_Data* data) {
- clear_StackFrameType();
- if (data) {
- set_has_data();
- StackFrameType_.data_ = data;
- }
-}
-
-// optional uint64 ref = 2;
-inline bool StackFrame::has_ref() const {
- return StackFrameType_case() == kRef;
-}
-inline void StackFrame::set_has_ref() {
- _oneof_case_[0] = kRef;
-}
-inline void StackFrame::clear_ref() {
- if (has_ref()) {
- StackFrameType_.ref_ = GOOGLE_ULONGLONG(0);
- clear_has_StackFrameType();
- }
-}
-inline ::google::protobuf::uint64 StackFrame::ref() const {
- if (has_ref()) {
- return StackFrameType_.ref_;
- }
- return GOOGLE_ULONGLONG(0);
-}
-inline void StackFrame::set_ref(::google::protobuf::uint64 value) {
- if (!has_ref()) {
- clear_StackFrameType();
- set_has_ref();
- }
- StackFrameType_.ref_ = value;
-}
-
-inline bool StackFrame::has_StackFrameType() {
- return StackFrameType_case() != STACKFRAMETYPE_NOT_SET;
-}
-inline void StackFrame::clear_has_StackFrameType() {
- _oneof_case_[0] = STACKFRAMETYPE_NOT_SET;
-}
-inline StackFrame::StackFrameTypeCase StackFrame::StackFrameType_case() const {
- return StackFrame::StackFrameTypeCase(_oneof_case_[0]);
-}
-// -------------------------------------------------------------------
-
-// Node
-
-// optional uint64 id = 1;
-inline bool Node::has_id() const {
- return (_has_bits_[0] & 0x00000001u) != 0;
-}
-inline void Node::set_has_id() {
- _has_bits_[0] |= 0x00000001u;
-}
-inline void Node::clear_has_id() {
- _has_bits_[0] &= ~0x00000001u;
-}
-inline void Node::clear_id() {
- id_ = GOOGLE_ULONGLONG(0);
- clear_has_id();
-}
-inline ::google::protobuf::uint64 Node::id() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.id)
- return id_;
-}
-inline void Node::set_id(::google::protobuf::uint64 value) {
- set_has_id();
- id_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.id)
-}
-
-// optional bytes typeName = 2;
-inline bool Node::has_typename_() const {
- return TypeNameOrRef_case() == kTypeName;
-}
-inline void Node::set_has_typename_() {
- _oneof_case_[0] = kTypeName;
-}
-inline void Node::clear_typename_() {
- if (has_typename_()) {
- delete TypeNameOrRef_.typename__;
- clear_has_TypeNameOrRef();
- }
-}
-inline const ::std::string& Node::typename_() const {
- if (has_typename_()) {
- return *TypeNameOrRef_.typename__;
- }
- return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
-}
-inline void Node::set_typename_(const ::std::string& value) {
- if (!has_typename_()) {
- clear_TypeNameOrRef();
- set_has_typename_();
- TypeNameOrRef_.typename__ = new ::std::string;
- }
- TypeNameOrRef_.typename__->assign(value);
-}
-inline void Node::set_typename_(const char* value) {
- if (!has_typename_()) {
- clear_TypeNameOrRef();
- set_has_typename_();
- TypeNameOrRef_.typename__ = new ::std::string;
- }
- TypeNameOrRef_.typename__->assign(value);
-}
-inline void Node::set_typename_(const void* value, size_t size) {
- if (!has_typename_()) {
- clear_TypeNameOrRef();
- set_has_typename_();
- TypeNameOrRef_.typename__ = new ::std::string;
- }
- TypeNameOrRef_.typename__->assign(
- reinterpret_cast<const char*>(value), size);
-}
-inline ::std::string* Node::mutable_typename_() {
- if (!has_typename_()) {
- clear_TypeNameOrRef();
- set_has_typename_();
- TypeNameOrRef_.typename__ = new ::std::string;
- }
- return TypeNameOrRef_.typename__;
-}
-inline ::std::string* Node::release_typename_() {
- if (has_typename_()) {
- clear_has_TypeNameOrRef();
- ::std::string* temp = TypeNameOrRef_.typename__;
- TypeNameOrRef_.typename__ = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-inline void Node::set_allocated_typename_(::std::string* typename_) {
- clear_TypeNameOrRef();
- if (typename_) {
- set_has_typename_();
- TypeNameOrRef_.typename__ = typename_;
- }
-}
-
-// optional uint64 typeNameRef = 3;
-inline bool Node::has_typenameref() const {
- return TypeNameOrRef_case() == kTypeNameRef;
-}
-inline void Node::set_has_typenameref() {
- _oneof_case_[0] = kTypeNameRef;
-}
-inline void Node::clear_typenameref() {
- if (has_typenameref()) {
- TypeNameOrRef_.typenameref_ = GOOGLE_ULONGLONG(0);
- clear_has_TypeNameOrRef();
- }
-}
-inline ::google::protobuf::uint64 Node::typenameref() const {
- if (has_typenameref()) {
- return TypeNameOrRef_.typenameref_;
- }
- return GOOGLE_ULONGLONG(0);
-}
-inline void Node::set_typenameref(::google::protobuf::uint64 value) {
- if (!has_typenameref()) {
- clear_TypeNameOrRef();
- set_has_typenameref();
- }
- TypeNameOrRef_.typenameref_ = value;
-}
-
-// optional uint64 size = 4;
-inline bool Node::has_size() const {
- return (_has_bits_[0] & 0x00000008u) != 0;
-}
-inline void Node::set_has_size() {
- _has_bits_[0] |= 0x00000008u;
-}
-inline void Node::clear_has_size() {
- _has_bits_[0] &= ~0x00000008u;
-}
-inline void Node::clear_size() {
- size_ = GOOGLE_ULONGLONG(0);
- clear_has_size();
-}
-inline ::google::protobuf::uint64 Node::size() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.size)
- return size_;
-}
-inline void Node::set_size(::google::protobuf::uint64 value) {
- set_has_size();
- size_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.size)
-}
-
-// repeated .mozilla.devtools.protobuf.Edge edges = 5;
-inline int Node::edges_size() const {
- return edges_.size();
-}
-inline void Node::clear_edges() {
- edges_.Clear();
-}
-inline const ::mozilla::devtools::protobuf::Edge& Node::edges(int index) const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.edges)
- return edges_.Get(index);
-}
-inline ::mozilla::devtools::protobuf::Edge* Node::mutable_edges(int index) {
- // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.edges)
- return edges_.Mutable(index);
-}
-inline ::mozilla::devtools::protobuf::Edge* Node::add_edges() {
- // @@protoc_insertion_point(field_add:mozilla.devtools.protobuf.Node.edges)
- return edges_.Add();
-}
-inline const ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >&
-Node::edges() const {
- // @@protoc_insertion_point(field_list:mozilla.devtools.protobuf.Node.edges)
- return edges_;
-}
-inline ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >*
-Node::mutable_edges() {
- // @@protoc_insertion_point(field_mutable_list:mozilla.devtools.protobuf.Node.edges)
- return &edges_;
-}
-
-// optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
-inline bool Node::has_allocationstack() const {
- return (_has_bits_[0] & 0x00000020u) != 0;
-}
-inline void Node::set_has_allocationstack() {
- _has_bits_[0] |= 0x00000020u;
-}
-inline void Node::clear_has_allocationstack() {
- _has_bits_[0] &= ~0x00000020u;
-}
-inline void Node::clear_allocationstack() {
- if (allocationstack_ != NULL) allocationstack_->::mozilla::devtools::protobuf::StackFrame::Clear();
- clear_has_allocationstack();
-}
-inline const ::mozilla::devtools::protobuf::StackFrame& Node::allocationstack() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.allocationStack)
- return allocationstack_ != NULL ? *allocationstack_ : *default_instance_->allocationstack_;
-}
-inline ::mozilla::devtools::protobuf::StackFrame* Node::mutable_allocationstack() {
- set_has_allocationstack();
- if (allocationstack_ == NULL) allocationstack_ = new ::mozilla::devtools::protobuf::StackFrame;
- // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.allocationStack)
- return allocationstack_;
-}
-inline ::mozilla::devtools::protobuf::StackFrame* Node::release_allocationstack() {
- clear_has_allocationstack();
- ::mozilla::devtools::protobuf::StackFrame* temp = allocationstack_;
- allocationstack_ = NULL;
- return temp;
-}
-inline void Node::set_allocated_allocationstack(::mozilla::devtools::protobuf::StackFrame* allocationstack) {
- delete allocationstack_;
- allocationstack_ = allocationstack;
- if (allocationstack) {
- set_has_allocationstack();
- } else {
- clear_has_allocationstack();
- }
- // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.allocationStack)
-}
-
-// optional bytes jsObjectClassName = 7;
-inline bool Node::has_jsobjectclassname() const {
- return JSObjectClassNameOrRef_case() == kJsObjectClassName;
-}
-inline void Node::set_has_jsobjectclassname() {
- _oneof_case_[1] = kJsObjectClassName;
-}
-inline void Node::clear_jsobjectclassname() {
- if (has_jsobjectclassname()) {
- delete JSObjectClassNameOrRef_.jsobjectclassname_;
- clear_has_JSObjectClassNameOrRef();
- }
-}
-inline const ::std::string& Node::jsobjectclassname() const {
- if (has_jsobjectclassname()) {
- return *JSObjectClassNameOrRef_.jsobjectclassname_;
- }
- return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
-}
-inline void Node::set_jsobjectclassname(const ::std::string& value) {
- if (!has_jsobjectclassname()) {
- clear_JSObjectClassNameOrRef();
- set_has_jsobjectclassname();
- JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
- }
- JSObjectClassNameOrRef_.jsobjectclassname_->assign(value);
-}
-inline void Node::set_jsobjectclassname(const char* value) {
- if (!has_jsobjectclassname()) {
- clear_JSObjectClassNameOrRef();
- set_has_jsobjectclassname();
- JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
- }
- JSObjectClassNameOrRef_.jsobjectclassname_->assign(value);
-}
-inline void Node::set_jsobjectclassname(const void* value, size_t size) {
- if (!has_jsobjectclassname()) {
- clear_JSObjectClassNameOrRef();
- set_has_jsobjectclassname();
- JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
- }
- JSObjectClassNameOrRef_.jsobjectclassname_->assign(
- reinterpret_cast<const char*>(value), size);
-}
-inline ::std::string* Node::mutable_jsobjectclassname() {
- if (!has_jsobjectclassname()) {
- clear_JSObjectClassNameOrRef();
- set_has_jsobjectclassname();
- JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
- }
- return JSObjectClassNameOrRef_.jsobjectclassname_;
-}
-inline ::std::string* Node::release_jsobjectclassname() {
- if (has_jsobjectclassname()) {
- clear_has_JSObjectClassNameOrRef();
- ::std::string* temp = JSObjectClassNameOrRef_.jsobjectclassname_;
- JSObjectClassNameOrRef_.jsobjectclassname_ = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-inline void Node::set_allocated_jsobjectclassname(::std::string* jsobjectclassname) {
- clear_JSObjectClassNameOrRef();
- if (jsobjectclassname) {
- set_has_jsobjectclassname();
- JSObjectClassNameOrRef_.jsobjectclassname_ = jsobjectclassname;
- }
-}
-
-// optional uint64 jsObjectClassNameRef = 8;
-inline bool Node::has_jsobjectclassnameref() const {
- return JSObjectClassNameOrRef_case() == kJsObjectClassNameRef;
-}
-inline void Node::set_has_jsobjectclassnameref() {
- _oneof_case_[1] = kJsObjectClassNameRef;
-}
-inline void Node::clear_jsobjectclassnameref() {
- if (has_jsobjectclassnameref()) {
- JSObjectClassNameOrRef_.jsobjectclassnameref_ = GOOGLE_ULONGLONG(0);
- clear_has_JSObjectClassNameOrRef();
- }
-}
-inline ::google::protobuf::uint64 Node::jsobjectclassnameref() const {
- if (has_jsobjectclassnameref()) {
- return JSObjectClassNameOrRef_.jsobjectclassnameref_;
- }
- return GOOGLE_ULONGLONG(0);
-}
-inline void Node::set_jsobjectclassnameref(::google::protobuf::uint64 value) {
- if (!has_jsobjectclassnameref()) {
- clear_JSObjectClassNameOrRef();
- set_has_jsobjectclassnameref();
- }
- JSObjectClassNameOrRef_.jsobjectclassnameref_ = value;
-}
-
-// optional uint32 coarseType = 9 [default = 0];
-inline bool Node::has_coarsetype() const {
- return (_has_bits_[0] & 0x00000100u) != 0;
-}
-inline void Node::set_has_coarsetype() {
- _has_bits_[0] |= 0x00000100u;
-}
-inline void Node::clear_has_coarsetype() {
- _has_bits_[0] &= ~0x00000100u;
-}
-inline void Node::clear_coarsetype() {
- coarsetype_ = 0u;
- clear_has_coarsetype();
-}
-inline ::google::protobuf::uint32 Node::coarsetype() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.coarseType)
- return coarsetype_;
-}
-inline void Node::set_coarsetype(::google::protobuf::uint32 value) {
- set_has_coarsetype();
- coarsetype_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.coarseType)
-}
-
-// optional bytes scriptFilename = 10;
-inline bool Node::has_scriptfilename() const {
- return ScriptFilenameOrRef_case() == kScriptFilename;
-}
-inline void Node::set_has_scriptfilename() {
- _oneof_case_[2] = kScriptFilename;
-}
-inline void Node::clear_scriptfilename() {
- if (has_scriptfilename()) {
- delete ScriptFilenameOrRef_.scriptfilename_;
- clear_has_ScriptFilenameOrRef();
- }
-}
-inline const ::std::string& Node::scriptfilename() const {
- if (has_scriptfilename()) {
- return *ScriptFilenameOrRef_.scriptfilename_;
- }
- return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
-}
-inline void Node::set_scriptfilename(const ::std::string& value) {
- if (!has_scriptfilename()) {
- clear_ScriptFilenameOrRef();
- set_has_scriptfilename();
- ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
- }
- ScriptFilenameOrRef_.scriptfilename_->assign(value);
-}
-inline void Node::set_scriptfilename(const char* value) {
- if (!has_scriptfilename()) {
- clear_ScriptFilenameOrRef();
- set_has_scriptfilename();
- ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
- }
- ScriptFilenameOrRef_.scriptfilename_->assign(value);
-}
-inline void Node::set_scriptfilename(const void* value, size_t size) {
- if (!has_scriptfilename()) {
- clear_ScriptFilenameOrRef();
- set_has_scriptfilename();
- ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
- }
- ScriptFilenameOrRef_.scriptfilename_->assign(
- reinterpret_cast<const char*>(value), size);
-}
-inline ::std::string* Node::mutable_scriptfilename() {
- if (!has_scriptfilename()) {
- clear_ScriptFilenameOrRef();
- set_has_scriptfilename();
- ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
- }
- return ScriptFilenameOrRef_.scriptfilename_;
-}
-inline ::std::string* Node::release_scriptfilename() {
- if (has_scriptfilename()) {
- clear_has_ScriptFilenameOrRef();
- ::std::string* temp = ScriptFilenameOrRef_.scriptfilename_;
- ScriptFilenameOrRef_.scriptfilename_ = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-inline void Node::set_allocated_scriptfilename(::std::string* scriptfilename) {
- clear_ScriptFilenameOrRef();
- if (scriptfilename) {
- set_has_scriptfilename();
- ScriptFilenameOrRef_.scriptfilename_ = scriptfilename;
- }
-}
-
-// optional uint64 scriptFilenameRef = 11;
-inline bool Node::has_scriptfilenameref() const {
- return ScriptFilenameOrRef_case() == kScriptFilenameRef;
-}
-inline void Node::set_has_scriptfilenameref() {
- _oneof_case_[2] = kScriptFilenameRef;
-}
-inline void Node::clear_scriptfilenameref() {
- if (has_scriptfilenameref()) {
- ScriptFilenameOrRef_.scriptfilenameref_ = GOOGLE_ULONGLONG(0);
- clear_has_ScriptFilenameOrRef();
- }
-}
-inline ::google::protobuf::uint64 Node::scriptfilenameref() const {
- if (has_scriptfilenameref()) {
- return ScriptFilenameOrRef_.scriptfilenameref_;
- }
- return GOOGLE_ULONGLONG(0);
-}
-inline void Node::set_scriptfilenameref(::google::protobuf::uint64 value) {
- if (!has_scriptfilenameref()) {
- clear_ScriptFilenameOrRef();
- set_has_scriptfilenameref();
- }
- ScriptFilenameOrRef_.scriptfilenameref_ = value;
-}
-
-inline bool Node::has_TypeNameOrRef() {
- return TypeNameOrRef_case() != TYPENAMEORREF_NOT_SET;
-}
-inline void Node::clear_has_TypeNameOrRef() {
- _oneof_case_[0] = TYPENAMEORREF_NOT_SET;
-}
-inline bool Node::has_JSObjectClassNameOrRef() {
- return JSObjectClassNameOrRef_case() != JSOBJECTCLASSNAMEORREF_NOT_SET;
-}
-inline void Node::clear_has_JSObjectClassNameOrRef() {
- _oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET;
-}
-inline bool Node::has_ScriptFilenameOrRef() {
- return ScriptFilenameOrRef_case() != SCRIPTFILENAMEORREF_NOT_SET;
-}
-inline void Node::clear_has_ScriptFilenameOrRef() {
- _oneof_case_[2] = SCRIPTFILENAMEORREF_NOT_SET;
-}
-inline Node::TypeNameOrRefCase Node::TypeNameOrRef_case() const {
- return Node::TypeNameOrRefCase(_oneof_case_[0]);
-}
-inline Node::JSObjectClassNameOrRefCase Node::JSObjectClassNameOrRef_case() const {
- return Node::JSObjectClassNameOrRefCase(_oneof_case_[1]);
-}
-inline Node::ScriptFilenameOrRefCase Node::ScriptFilenameOrRef_case() const {
- return Node::ScriptFilenameOrRefCase(_oneof_case_[2]);
-}
-// -------------------------------------------------------------------
-
-// Edge
-
-// optional uint64 referent = 1;
-inline bool Edge::has_referent() const {
- return (_has_bits_[0] & 0x00000001u) != 0;
-}
-inline void Edge::set_has_referent() {
- _has_bits_[0] |= 0x00000001u;
-}
-inline void Edge::clear_has_referent() {
- _has_bits_[0] &= ~0x00000001u;
-}
-inline void Edge::clear_referent() {
- referent_ = GOOGLE_ULONGLONG(0);
- clear_has_referent();
-}
-inline ::google::protobuf::uint64 Edge::referent() const {
- // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Edge.referent)
- return referent_;
-}
-inline void Edge::set_referent(::google::protobuf::uint64 value) {
- set_has_referent();
- referent_ = value;
- // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Edge.referent)
-}
-
-// optional bytes name = 2;
-inline bool Edge::has_name() const {
- return EdgeNameOrRef_case() == kName;
-}
-inline void Edge::set_has_name() {
- _oneof_case_[0] = kName;
-}
-inline void Edge::clear_name() {
- if (has_name()) {
- delete EdgeNameOrRef_.name_;
- clear_has_EdgeNameOrRef();
- }
-}
-inline const ::std::string& Edge::name() const {
- if (has_name()) {
- return *EdgeNameOrRef_.name_;
- }
- return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
-}
-inline void Edge::set_name(const ::std::string& value) {
- if (!has_name()) {
- clear_EdgeNameOrRef();
- set_has_name();
- EdgeNameOrRef_.name_ = new ::std::string;
- }
- EdgeNameOrRef_.name_->assign(value);
-}
-inline void Edge::set_name(const char* value) {
- if (!has_name()) {
- clear_EdgeNameOrRef();
- set_has_name();
- EdgeNameOrRef_.name_ = new ::std::string;
- }
- EdgeNameOrRef_.name_->assign(value);
-}
-inline void Edge::set_name(const void* value, size_t size) {
- if (!has_name()) {
- clear_EdgeNameOrRef();
- set_has_name();
- EdgeNameOrRef_.name_ = new ::std::string;
- }
- EdgeNameOrRef_.name_->assign(
- reinterpret_cast<const char*>(value), size);
-}
-inline ::std::string* Edge::mutable_name() {
- if (!has_name()) {
- clear_EdgeNameOrRef();
- set_has_name();
- EdgeNameOrRef_.name_ = new ::std::string;
- }
- return EdgeNameOrRef_.name_;
-}
-inline ::std::string* Edge::release_name() {
- if (has_name()) {
- clear_has_EdgeNameOrRef();
- ::std::string* temp = EdgeNameOrRef_.name_;
- EdgeNameOrRef_.name_ = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-inline void Edge::set_allocated_name(::std::string* name) {
- clear_EdgeNameOrRef();
- if (name) {
- set_has_name();
- EdgeNameOrRef_.name_ = name;
- }
-}
-
-// optional uint64 nameRef = 3;
-inline bool Edge::has_nameref() const {
- return EdgeNameOrRef_case() == kNameRef;
-}
-inline void Edge::set_has_nameref() {
- _oneof_case_[0] = kNameRef;
-}
-inline void Edge::clear_nameref() {
- if (has_nameref()) {
- EdgeNameOrRef_.nameref_ = GOOGLE_ULONGLONG(0);
- clear_has_EdgeNameOrRef();
- }
-}
-inline ::google::protobuf::uint64 Edge::nameref() const {
- if (has_nameref()) {
- return EdgeNameOrRef_.nameref_;
- }
- return GOOGLE_ULONGLONG(0);
-}
-inline void Edge::set_nameref(::google::protobuf::uint64 value) {
- if (!has_nameref()) {
- clear_EdgeNameOrRef();
- set_has_nameref();
- }
- EdgeNameOrRef_.nameref_ = value;
-}
-
-inline bool Edge::has_EdgeNameOrRef() {
- return EdgeNameOrRef_case() != EDGENAMEORREF_NOT_SET;
-}
-inline void Edge::clear_has_EdgeNameOrRef() {
- _oneof_case_[0] = EDGENAMEORREF_NOT_SET;
-}
-inline Edge::EdgeNameOrRefCase Edge::EdgeNameOrRef_case() const {
- return Edge::EdgeNameOrRefCase(_oneof_case_[0]);
-}
-
-// @@protoc_insertion_point(namespace_scope)
-
-} // namespace protobuf
-} // namespace devtools
-} // namespace mozilla
-
-#ifndef SWIG
-namespace google {
-namespace protobuf {
-
-
-} // namespace google
-} // namespace protobuf
-#endif // SWIG
-
-// @@protoc_insertion_point(global_scope)
-
-#endif // PROTOBUF_CoreDump_2eproto__INCLUDED
diff --git a/devtools/shared/heapsnapshot/CoreDump.proto b/devtools/shared/heapsnapshot/CoreDump.proto
deleted file mode 100644
index 24a223e11..000000000
--- a/devtools/shared/heapsnapshot/CoreDump.proto
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode: protobuf; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// # Core Dumps
-//
-// A core dump is a serialized snapshot of the heap graph. We serialize the heap
-// as a series of protobuf messages with each message prefixed by its Varint32
-// byte size so we can delimit individual protobuf messages (protobuf parsers
-// cannot determine where a message ends on their own).
-//
-// The first protobuf message is an instance of the `Metadata` message. All
-// subsequent messages will be instances of the `Node` message. The first of
-// these `Node` messages is the root node of the serialized heap graph. Here is
-// a diagram of our core dump format:
-//
-// +-----------------------------------------------------------------------+
-// | Varint32: The size of following `Metadata` message. |
-// +-----------------------------------------------------------------------+
-// | message: The core dump `Metadata` message. |
-// +-----------------------------------------------------------------------+
-// | Varint32: The size of the following `Node` message. |
-// +-----------------------------------------------------------------------+
-// | message: The first `Node` message. This is the root node. |
-// +-----------------------------------------------------------------------+
-// | Varint32: The size of the following `Node` message. |
-// +-----------------------------------------------------------------------+
-// | message: A `Node` message. |
-// +-----------------------------------------------------------------------+
-// | Varint32: The size of the following `Node` message. |
-// +-----------------------------------------------------------------------+
-// | message: A `Node` message. |
-// +-----------------------------------------------------------------------+
-// | . |
-// | . |
-// | . |
-// +-----------------------------------------------------------------------+
-//
-// Core dumps should always be written with a
-// `google::protobuf::io::GzipOutputStream` and read from a
-// `google::protobuf::io::GzipInputStream`.
-//
-// Note that all strings are de-duplicated. The first time the N^th unique
-// string is encountered, the full string is serialized. Subsequent times that
-// same string is encountered, it is referenced by N. This de-duplication
-// happens across string properties, not on a per-property basis. For example,
-// if the same K^th unique string is first used as an Edge::EdgeNameOrRef and
-// then as a StackFrame::Data::FunctionDisplayNameOrRef, the first will be the
-// actual string as the functionDisplayName oneof property, and the second will
-// be a reference to the first as the edgeNameRef oneof property whose value is
-// K.
-//
-// We would ordinarily abstract these de-duplicated strings with messages of
-// their own, but unfortunately, the protobuf compiler does not have a way to
-// inline a messsage within another message and the child message must be
-// referenced by pointer. This leads to extra mallocs that we wish to avoid.
-
-
-package mozilla.devtools.protobuf;
-
-// A collection of metadata about this core dump.
-message Metadata {
- // Number of microseconds since midnight (00:00:00) 1 January 1970 UTC.
- optional uint64 timeStamp = 1;
-}
-
-// A serialized version of `JS::ubi::StackFrame`. Older parent frame tails are
-// de-duplicated to cut down on [de]serialization and size costs.
-message StackFrame {
- oneof StackFrameType {
- // This is the first time this stack frame has been serialized, and so
- // here is all of its data.
- Data data = 1;
- // A reference to a stack frame that has already been serialized and has
- // the given number as its id.
- uint64 ref = 2;
- }
-
- message Data {
- optional uint64 id = 1;
- optional StackFrame parent = 2;
- optional uint32 line = 3;
- optional uint32 column = 4;
-
- // De-duplicated two-byte string.
- oneof SourceOrRef {
- bytes source = 5;
- uint64 sourceRef = 6;
- }
-
- // De-duplicated two-byte string.
- oneof FunctionDisplayNameOrRef {
- bytes functionDisplayName = 7;
- uint64 functionDisplayNameRef = 8;
- }
-
- optional bool isSystem = 9;
- optional bool isSelfHosted = 10;
- }
-}
-
-// A serialized version of `JS::ubi::Node` and its outgoing edges.
-message Node {
- optional uint64 id = 1;
-
- // De-duplicated two-byte string.
- oneof TypeNameOrRef {
- bytes typeName = 2;
- uint64 typeNameRef = 3;
- }
-
- optional uint64 size = 4;
- repeated Edge edges = 5;
- optional StackFrame allocationStack = 6;
-
- // De-duplicated one-byte string.
- oneof JSObjectClassNameOrRef {
- bytes jsObjectClassName = 7;
- uint64 jsObjectClassNameRef = 8;
- }
-
- // JS::ubi::CoarseType. Defaults to Other.
- optional uint32 coarseType = 9 [default = 0];
-
- // De-duplicated one-byte string.
- oneof ScriptFilenameOrRef {
- bytes scriptFilename = 10;
- uint64 scriptFilenameRef = 11;
- }
-}
-
-// A serialized edge from the heap graph.
-message Edge {
- optional uint64 referent = 1;
-
- // De-duplicated two-byte string.
- oneof EdgeNameOrRef {
- bytes name = 2;
- uint64 nameRef = 3;
- }
-}
diff --git a/devtools/shared/heapsnapshot/DeserializedNode.cpp b/devtools/shared/heapsnapshot/DeserializedNode.cpp
deleted file mode 100644
index fac4cccb9..000000000
--- a/devtools/shared/heapsnapshot/DeserializedNode.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/devtools/DeserializedNode.h"
-#include "mozilla/devtools/HeapSnapshot.h"
-#include "nsCRTGlue.h"
-
-namespace mozilla {
-namespace devtools {
-
-DeserializedEdge::DeserializedEdge(DeserializedEdge&& rhs)
-{
- referent = rhs.referent;
- name = rhs.name;
-}
-
-DeserializedEdge& DeserializedEdge::operator=(DeserializedEdge&& rhs)
-{
- MOZ_ASSERT(&rhs != this);
- this->~DeserializedEdge();
- new(this) DeserializedEdge(Move(rhs));
- return *this;
-}
-
-JS::ubi::Node
-DeserializedNode::getEdgeReferent(const DeserializedEdge& edge)
-{
- auto ptr = owner->nodes.lookup(edge.referent);
- MOZ_ASSERT(ptr);
-
- // `HashSets` only provide const access to their values, because mutating a
- // value might change its hash, rendering it unfindable in the set.
- // Unfortunately, the `ubi::Node` constructor requires a non-const pointer to
- // its referent. However, the only aspect of a `DeserializedNode` we hash on
- // is its id, which can't be changed via `ubi::Node`, so this cast can't cause
- // the trouble `HashSet` is concerned a non-const reference would cause.
- return JS::ubi::Node(const_cast<DeserializedNode*>(&*ptr));
-}
-
-JS::ubi::StackFrame
-DeserializedStackFrame::getParentStackFrame() const
-{
- MOZ_ASSERT(parent.isSome());
- auto ptr = owner->frames.lookup(parent.ref());
- MOZ_ASSERT(ptr);
- // See above comment in DeserializedNode::getEdgeReferent about why this
- // const_cast is needed and safe.
- return JS::ubi::StackFrame(const_cast<DeserializedStackFrame*>(&*ptr));
-}
-
-} // namespace devtools
-} // namespace mozilla
-
-namespace JS {
-namespace ubi {
-
-using mozilla::devtools::DeserializedEdge;
-
-const char16_t Concrete<DeserializedNode>::concreteTypeName[] =
- u"mozilla::devtools::DeserializedNode";
-
-const char16_t*
-Concrete<DeserializedNode>::typeName() const
-{
- return get().typeName;
-}
-
-Node::Size
-Concrete<DeserializedNode>::size(mozilla::MallocSizeOf mallocSizeof) const
-{
- return get().size;
-}
-
-class DeserializedEdgeRange : public EdgeRange
-{
- DeserializedNode* node;
- Edge currentEdge;
- size_t i;
-
- void settle() {
- if (i >= node->edges.length()) {
- front_ = nullptr;
- return;
- }
-
- auto& edge = node->edges[i];
- auto referent = node->getEdgeReferent(edge);
- currentEdge = mozilla::Move(Edge(edge.name ? NS_strdup(edge.name) : nullptr,
- referent));
- front_ = &currentEdge;
- }
-
-public:
- explicit DeserializedEdgeRange(DeserializedNode& node)
- : node(&node)
- , i(0)
- {
- settle();
- }
-
- void popFront() override
- {
- i++;
- settle();
- }
-};
-
-StackFrame
-Concrete<DeserializedNode>::allocationStack() const
-{
- MOZ_ASSERT(hasAllocationStack());
- auto id = get().allocationStack.ref();
- auto ptr = get().owner->frames.lookup(id);
- MOZ_ASSERT(ptr);
- // See above comment in DeserializedNode::getEdgeReferent about why this
- // const_cast is needed and safe.
- return JS::ubi::StackFrame(const_cast<DeserializedStackFrame*>(&*ptr));
-}
-
-
-js::UniquePtr<EdgeRange>
-Concrete<DeserializedNode>::edges(JSContext* cx, bool) const
-{
- js::UniquePtr<DeserializedEdgeRange> range(js_new<DeserializedEdgeRange>(get()));
-
- if (!range)
- return nullptr;
-
- return js::UniquePtr<EdgeRange>(range.release());
-}
-
-StackFrame
-ConcreteStackFrame<DeserializedStackFrame>::parent() const
-{
- return get().parent.isNothing() ? StackFrame() : get().getParentStackFrame();
-}
-
-bool
-ConcreteStackFrame<DeserializedStackFrame>::constructSavedFrameStack(
- JSContext* cx,
- MutableHandleObject outSavedFrameStack) const
-{
- StackFrame f(&get());
- return ConstructSavedFrameStackSlow(cx, f, outSavedFrameStack);
-}
-
-} // namespace ubi
-} // namespace JS
diff --git a/devtools/shared/heapsnapshot/DeserializedNode.h b/devtools/shared/heapsnapshot/DeserializedNode.h
deleted file mode 100644
index 60d1fb408..000000000
--- a/devtools/shared/heapsnapshot/DeserializedNode.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_DeserializedNode__
-#define mozilla_devtools_DeserializedNode__
-
-#include "js/UbiNode.h"
-#include "js/UniquePtr.h"
-#include "mozilla/devtools/CoreDump.pb.h"
-#include "mozilla/Maybe.h"
-#include "mozilla/Move.h"
-#include "mozilla/Vector.h"
-
-// `Deserialized{Node,Edge}` translate protobuf messages from our core dump
-// format into structures we can rely upon for implementing `JS::ubi::Node`
-// specializations on top of. All of the properties of the protobuf messages are
-// optional for future compatibility, and this is the layer where we validate
-// that the properties that do actually exist in any given message fulfill our
-// semantic requirements.
-//
-// Both `DeserializedNode` and `DeserializedEdge` are always owned by a
-// `HeapSnapshot` instance, and their lifetimes must not extend after that of
-// their owning `HeapSnapshot`.
-
-namespace mozilla {
-namespace devtools {
-
-class HeapSnapshot;
-
-using NodeId = uint64_t;
-using StackFrameId = uint64_t;
-
-// A `DeserializedEdge` represents an edge in the heap graph pointing to the
-// node with id equal to `DeserializedEdge::referent` that we deserialized from
-// a core dump.
-struct DeserializedEdge {
- NodeId referent;
- // A borrowed reference to a string owned by this node's owning HeapSnapshot.
- const char16_t* name;
-
- explicit DeserializedEdge(NodeId referent, const char16_t* edgeName = nullptr)
- : referent(referent)
- , name(edgeName)
- { }
- DeserializedEdge(DeserializedEdge&& rhs);
- DeserializedEdge& operator=(DeserializedEdge&& rhs);
-
-private:
- DeserializedEdge(const DeserializedEdge&) = delete;
- DeserializedEdge& operator=(const DeserializedEdge&) = delete;
-};
-
-// A `DeserializedNode` is a node in the heap graph that we deserialized from a
-// core dump.
-struct DeserializedNode {
- using EdgeVector = Vector<DeserializedEdge>;
- using UniqueStringPtr = UniquePtr<char16_t[]>;
-
- NodeId id;
- JS::ubi::CoarseType coarseType;
- // A borrowed reference to a string owned by this node's owning HeapSnapshot.
- const char16_t* typeName;
- uint64_t size;
- EdgeVector edges;
- Maybe<StackFrameId> allocationStack;
- // A borrowed reference to a string owned by this node's owning HeapSnapshot.
- const char* jsObjectClassName;
- // A borrowed reference to a string owned by this node's owning HeapSnapshot.
- const char* scriptFilename;
- // A weak pointer to this node's owning `HeapSnapshot`. Safe without
- // AddRef'ing because this node's lifetime is equal to that of its owner.
- HeapSnapshot* owner;
-
- DeserializedNode(NodeId id,
- JS::ubi::CoarseType coarseType,
- const char16_t* typeName,
- uint64_t size,
- EdgeVector&& edges,
- Maybe<StackFrameId> allocationStack,
- const char* className,
- const char* filename,
- HeapSnapshot& owner)
- : id(id)
- , coarseType(coarseType)
- , typeName(typeName)
- , size(size)
- , edges(Move(edges))
- , allocationStack(allocationStack)
- , jsObjectClassName(className)
- , scriptFilename(filename)
- , owner(&owner)
- { }
- virtual ~DeserializedNode() { }
-
- DeserializedNode(DeserializedNode&& rhs)
- : id(rhs.id)
- , coarseType(rhs.coarseType)
- , typeName(rhs.typeName)
- , size(rhs.size)
- , edges(Move(rhs.edges))
- , allocationStack(rhs.allocationStack)
- , jsObjectClassName(rhs.jsObjectClassName)
- , scriptFilename(rhs.scriptFilename)
- , owner(rhs.owner)
- { }
-
- DeserializedNode& operator=(DeserializedNode&& rhs)
- {
- MOZ_ASSERT(&rhs != this);
- this->~DeserializedNode();
- new(this) DeserializedNode(Move(rhs));
- return *this;
- }
-
- // Get a borrowed reference to the given edge's referent. This method is
- // virtual to provide a hook for gmock and gtest.
- virtual JS::ubi::Node getEdgeReferent(const DeserializedEdge& edge);
-
- struct HashPolicy;
-
-protected:
- // This is only for use with `MockDeserializedNode` in testing.
- DeserializedNode(NodeId id, const char16_t* typeName, uint64_t size)
- : id(id)
- , coarseType(JS::ubi::CoarseType::Other)
- , typeName(typeName)
- , size(size)
- , edges()
- , allocationStack(Nothing())
- , jsObjectClassName(nullptr)
- , scriptFilename(nullptr)
- , owner(nullptr)
- { }
-
-private:
- DeserializedNode(const DeserializedNode&) = delete;
- DeserializedNode& operator=(const DeserializedNode&) = delete;
-};
-
-static inline js::HashNumber
-hashIdDerivedFromPtr(uint64_t id)
-{
- // NodeIds and StackFrameIds are always 64 bits, but they are derived from
- // the original referents' addresses, which could have been either 32 or 64
- // bits long. As such, NodeId and StackFrameId have little entropy in their
- // bottom three bits, and may or may not have entropy in their upper 32
- // bits. This hash should manage both cases well.
- id >>= 3;
- return js::HashNumber((id >> 32) ^ id);
-}
-
-struct DeserializedNode::HashPolicy
-{
- using Lookup = NodeId;
-
- static js::HashNumber hash(const Lookup& lookup) {
- return hashIdDerivedFromPtr(lookup);
- }
-
- static bool match(const DeserializedNode& existing, const Lookup& lookup) {
- return existing.id == lookup;
- }
-};
-
-// A `DeserializedStackFrame` is a stack frame referred to by a thing in the
-// heap graph that we deserialized from a core dump.
-struct DeserializedStackFrame {
- StackFrameId id;
- Maybe<StackFrameId> parent;
- uint32_t line;
- uint32_t column;
- // Borrowed references to strings owned by this DeserializedStackFrame's
- // owning HeapSnapshot.
- const char16_t* source;
- const char16_t* functionDisplayName;
- bool isSystem;
- bool isSelfHosted;
- // A weak pointer to this frame's owning `HeapSnapshot`. Safe without
- // AddRef'ing because this frame's lifetime is equal to that of its owner.
- HeapSnapshot* owner;
-
- explicit DeserializedStackFrame(StackFrameId id,
- const Maybe<StackFrameId>& parent,
- uint32_t line,
- uint32_t column,
- const char16_t* source,
- const char16_t* functionDisplayName,
- bool isSystem,
- bool isSelfHosted,
- HeapSnapshot& owner)
- : id(id)
- , parent(parent)
- , line(line)
- , column(column)
- , source(source)
- , functionDisplayName(functionDisplayName)
- , isSystem(isSystem)
- , isSelfHosted(isSelfHosted)
- , owner(&owner)
- {
- MOZ_ASSERT(source);
- }
-
- JS::ubi::StackFrame getParentStackFrame() const;
-
- struct HashPolicy;
-
-protected:
- // This is exposed only for MockDeserializedStackFrame in the gtests.
- explicit DeserializedStackFrame()
- : id(0)
- , parent(Nothing())
- , line(0)
- , column(0)
- , source(nullptr)
- , functionDisplayName(nullptr)
- , isSystem(false)
- , isSelfHosted(false)
- , owner(nullptr)
- { };
-};
-
-struct DeserializedStackFrame::HashPolicy {
- using Lookup = StackFrameId;
-
- static js::HashNumber hash(const Lookup& lookup) {
- return hashIdDerivedFromPtr(lookup);
- }
-
- static bool match(const DeserializedStackFrame& existing, const Lookup& lookup) {
- return existing.id == lookup;
- }
-};
-
-} // namespace devtools
-} // namespace mozilla
-
-namespace JS {
-namespace ubi {
-
-using mozilla::devtools::DeserializedNode;
-using mozilla::devtools::DeserializedStackFrame;
-
-template<>
-class Concrete<DeserializedNode> : public Base
-{
-protected:
- explicit Concrete(DeserializedNode* ptr) : Base(ptr) { }
- DeserializedNode& get() const {
- return *static_cast<DeserializedNode*>(ptr);
- }
-
-public:
- static void construct(void* storage, DeserializedNode* ptr) {
- new (storage) Concrete(ptr);
- }
-
- CoarseType coarseType() const final { return get().coarseType; }
- Id identifier() const override { return get().id; }
- bool isLive() const override { return false; }
- const char16_t* typeName() const override;
- Node::Size size(mozilla::MallocSizeOf mallocSizeof) const override;
- const char* jsObjectClassName() const override { return get().jsObjectClassName; }
- const char* scriptFilename() const final { return get().scriptFilename; }
-
- bool hasAllocationStack() const override { return get().allocationStack.isSome(); }
- StackFrame allocationStack() const override;
-
- // We ignore the `bool wantNames` parameter because we can't control whether
- // the core dump was serialized with edge names or not.
- js::UniquePtr<EdgeRange> edges(JSContext* cx, bool) const override;
-
- static const char16_t concreteTypeName[];
-};
-
-template<>
-class ConcreteStackFrame<DeserializedStackFrame> : public BaseStackFrame
-{
-protected:
- explicit ConcreteStackFrame(DeserializedStackFrame* ptr)
- : BaseStackFrame(ptr)
- { }
-
- DeserializedStackFrame& get() const {
- return *static_cast<DeserializedStackFrame*>(ptr);
- }
-
-public:
- static void construct(void* storage, DeserializedStackFrame* ptr) {
- new (storage) ConcreteStackFrame(ptr);
- }
-
- uint64_t identifier() const override { return get().id; }
- uint32_t line() const override { return get().line; }
- uint32_t column() const override { return get().column; }
- bool isSystem() const override { return get().isSystem; }
- bool isSelfHosted(JSContext* cx) const override { return get().isSelfHosted; }
- void trace(JSTracer* trc) override { }
- AtomOrTwoByteChars source() const override {
- return AtomOrTwoByteChars(get().source);
- }
- AtomOrTwoByteChars functionDisplayName() const override {
- return AtomOrTwoByteChars(get().functionDisplayName);
- }
-
- StackFrame parent() const override;
- bool constructSavedFrameStack(JSContext* cx,
- MutableHandleObject outSavedFrameStack)
- const override;
-};
-
-} // namespace ubi
-} // namespace JS
-
-#endif // mozilla_devtools_DeserializedNode__
diff --git a/devtools/shared/heapsnapshot/DominatorTree.cpp b/devtools/shared/heapsnapshot/DominatorTree.cpp
deleted file mode 100644
index e53c196cf..000000000
--- a/devtools/shared/heapsnapshot/DominatorTree.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/devtools/DominatorTree.h"
-#include "mozilla/dom/DominatorTreeBinding.h"
-
-namespace mozilla {
-namespace devtools {
-
-dom::Nullable<uint64_t>
-DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv)
-{
- JS::ubi::Node::Id id(aNodeId);
- auto node = mHeapSnapshot->getNodeById(id);
- if (node.isNothing())
- return dom::Nullable<uint64_t>();
-
- auto mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf();
- JS::ubi::Node::Size size = 0;
- if (!mDominatorTree.getRetainedSize(*node, mallocSizeOf, size)) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return dom::Nullable<uint64_t>();
- }
-
- MOZ_ASSERT(size != 0,
- "The node should not have been unknown since we got it from the heap snapshot.");
- return dom::Nullable<uint64_t>(size);
-}
-
-struct NodeAndRetainedSize
-{
- JS::ubi::Node mNode;
- JS::ubi::Node::Size mSize;
-
- NodeAndRetainedSize(const JS::ubi::Node& aNode, JS::ubi::Node::Size aSize)
- : mNode(aNode)
- , mSize(aSize)
- { }
-
- struct Comparator
- {
- static bool
- Equals(const NodeAndRetainedSize& aLhs, const NodeAndRetainedSize& aRhs)
- {
- return aLhs.mSize == aRhs.mSize;
- }
-
- static bool
- LessThan(const NodeAndRetainedSize& aLhs, const NodeAndRetainedSize& aRhs)
- {
- // Use > because we want to sort from greatest to least retained size.
- return aLhs.mSize > aRhs.mSize;
- }
- };
-};
-
-void
-DominatorTree::GetImmediatelyDominated(uint64_t aNodeId,
- dom::Nullable<nsTArray<uint64_t>>& aOutResult,
- ErrorResult& aRv)
-{
- MOZ_ASSERT(aOutResult.IsNull());
-
- JS::ubi::Node::Id id(aNodeId);
- Maybe<JS::ubi::Node> node = mHeapSnapshot->getNodeById(id);
- if (node.isNothing())
- return;
-
- // Get all immediately dominated nodes and their retained sizes.
- MallocSizeOf mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf();
- Maybe<JS::ubi::DominatorTree::DominatedSetRange> range = mDominatorTree.getDominatedSet(*node);
- MOZ_ASSERT(range.isSome(), "The node should be known, since we got it from the heap snapshot.");
- size_t length = range->length();
- nsTArray<NodeAndRetainedSize> dominatedNodes(length);
- for (const JS::ubi::Node& dominatedNode : *range) {
- JS::ubi::Node::Size retainedSize = 0;
- if (NS_WARN_IF(!mDominatorTree.getRetainedSize(dominatedNode, mallocSizeOf, retainedSize))) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
- MOZ_ASSERT(retainedSize != 0,
- "retainedSize should not be zero since we know the node is in the dominator tree.");
-
- dominatedNodes.AppendElement(NodeAndRetainedSize(dominatedNode, retainedSize));
- }
-
- // Sort them by retained size.
- NodeAndRetainedSize::Comparator comparator;
- dominatedNodes.Sort(comparator);
-
- // Fill the result with the nodes' ids.
- JS::ubi::Node root = mDominatorTree.root();
- aOutResult.SetValue(nsTArray<uint64_t>(length));
- for (const NodeAndRetainedSize& entry : dominatedNodes) {
- // The root dominates itself, but we don't want to expose that to JS.
- if (entry.mNode == root)
- continue;
-
- aOutResult.Value().AppendElement(entry.mNode.identifier());
- }
-}
-
-dom::Nullable<uint64_t>
-DominatorTree::GetImmediateDominator(uint64_t aNodeId) const
-{
- JS::ubi::Node::Id id(aNodeId);
- Maybe<JS::ubi::Node> node = mHeapSnapshot->getNodeById(id);
- if (node.isNothing())
- return dom::Nullable<uint64_t>();
-
- JS::ubi::Node dominator = mDominatorTree.getImmediateDominator(*node);
- if (!dominator || dominator == *node)
- return dom::Nullable<uint64_t>();
-
- return dom::Nullable<uint64_t>(dominator.identifier());
-}
-
-
-/*** Cycle Collection Boilerplate *****************************************************************/
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DominatorTree, mParent, mHeapSnapshot)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(DominatorTree)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(DominatorTree)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DominatorTree)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-/* virtual */ JSObject*
-DominatorTree::WrapObject(JSContext* aCx, JS::HandleObject aGivenProto)
-{
- return dom::DominatorTreeBinding::Wrap(aCx, this, aGivenProto);
-}
-
-} // namespace devtools
-} // namespace mozilla
diff --git a/devtools/shared/heapsnapshot/DominatorTree.h b/devtools/shared/heapsnapshot/DominatorTree.h
deleted file mode 100644
index f785d4916..000000000
--- a/devtools/shared/heapsnapshot/DominatorTree.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_DominatorTree__
-#define mozilla_devtools_DominatorTree__
-
-#include "mozilla/devtools/HeapSnapshot.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/RefCounted.h"
-#include "js/UbiNodeDominatorTree.h"
-#include "nsWrapperCache.h"
-
-namespace mozilla {
-namespace devtools {
-
-class DominatorTree final : public nsISupports
- , public nsWrapperCache
-{
-protected:
- nsCOMPtr<nsISupports> mParent;
-
- virtual ~DominatorTree() { }
-
-private:
- JS::ubi::DominatorTree mDominatorTree;
- RefPtr<HeapSnapshot> mHeapSnapshot;
-
-public:
- explicit DominatorTree(JS::ubi::DominatorTree&& aDominatorTree, HeapSnapshot* aHeapSnapshot,
- nsISupports* aParent)
- : mParent(aParent)
- , mDominatorTree(Move(aDominatorTree))
- , mHeapSnapshot(aHeapSnapshot)
- {
- MOZ_ASSERT(aParent);
- MOZ_ASSERT(aHeapSnapshot);
- };
-
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS;
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DominatorTree);
-
- nsISupports* GetParentObject() const { return mParent; }
-
- virtual JSObject* WrapObject(JSContext* aCx,
- JS::Handle<JSObject*> aGivenProto) override;
-
- // readonly attribute NodeId root
- uint64_t Root() const { return mDominatorTree.root().identifier(); }
-
- // [Throws] NodeSize getRetainedSize(NodeId node)
- dom::Nullable<uint64_t> GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv);
-
- // [Throws] sequence<NodeId>? getImmediatelyDominated(NodeId node);
- void GetImmediatelyDominated(uint64_t aNodeId, dom::Nullable<nsTArray<uint64_t>>& aOutDominated,
- ErrorResult& aRv);
-
- // NodeId? getImmediateDominator(NodeId node);
- dom::Nullable<uint64_t> GetImmediateDominator(uint64_t aNodeId) const;
-};
-
-} // namespace devtools
-} // namespace mozilla
-
-#endif // mozilla_devtools_DominatorTree__
diff --git a/devtools/shared/heapsnapshot/DominatorTreeNode.js b/devtools/shared/heapsnapshot/DominatorTreeNode.js
deleted file mode 100644
index 13a847fd0..000000000
--- a/devtools/shared/heapsnapshot/DominatorTreeNode.js
+++ /dev/null
@@ -1,336 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { immutableUpdate } = require("resource://devtools/shared/ThreadSafeDevToolsUtils.js");
-const { Visitor, walk } = require("resource://devtools/shared/heapsnapshot/CensusUtils.js");
-const { deduplicatePaths } = require("resource://devtools/shared/heapsnapshot/shortest-paths");
-
-const DEFAULT_MAX_DEPTH = 4;
-const DEFAULT_MAX_SIBLINGS = 15;
-const DEFAULT_MAX_NUM_PATHS = 5;
-
-/**
- * A single node in a dominator tree.
- *
- * @param {NodeId} nodeId
- * @param {NodeSize} retainedSize
- */
-function DominatorTreeNode(nodeId, label, shallowSize, retainedSize) {
- // The id of this node.
- this.nodeId = nodeId;
-
- // The label structure generated by describing the given node.
- this.label = label;
-
- // The shallow size of this node.
- this.shallowSize = shallowSize;
-
- // The retained size of this node.
- this.retainedSize = retainedSize;
-
- // The id of this node's parent or undefined if this node is the root.
- this.parentId = undefined;
-
- // An array of immediately dominated child `DominatorTreeNode`s, or undefined.
- this.children = undefined;
-
- // An object of the form returned by `deduplicatePaths`, encoding the set of
- // the N shortest retaining paths for this node as a graph.
- this.shortestPaths = undefined;
-
- // True iff the `children` property does not contain every immediately
- // dominated node.
- //
- // * If children is an array and this property is true: the array does not
- // contain the complete set of immediately dominated children.
- // * If children is an array and this property is false: the array contains
- // the complete set of immediately dominated children.
- // * If children is undefined and this property is true: there exist
- // immediately dominated children for this node, but they have not been
- // loaded yet.
- // * If children is undefined and this property is false: this node does not
- // dominate any others and therefore has no children.
- this.moreChildrenAvailable = true;
-}
-
-DominatorTreeNode.prototype = null;
-
-module.exports = DominatorTreeNode;
-
-/**
- * Add `child` to the `parent`'s set of children.
- *
- * @param {DominatorTreeNode} parent
- * @param {DominatorTreeNode} child
- */
-DominatorTreeNode.addChild = function (parent, child) {
- if (parent.children === undefined) {
- parent.children = [];
- }
-
- parent.children.push(child);
- child.parentId = parent.nodeId;
-};
-
-/**
- * A Visitor that is used to generate a label for a node in the heap snapshot
- * and get its shallow size as well while we are at it.
- */
-function LabelAndShallowSizeVisitor() {
- // As we walk the description, we accumulate edges in this array.
- this._labelPieces = [];
-
- // Once we reach the non-zero count leaf node in the description, we move the
- // labelPieces here to signify that we no longer need to accumulate edges.
- this._label = undefined;
-
- // Once we reach the non-zero count leaf node in the description, we grab the
- // shallow size and place it here.
- this._shallowSize = 0;
-}
-
-DominatorTreeNode.LabelAndShallowSizeVisitor = LabelAndShallowSizeVisitor;
-
-LabelAndShallowSizeVisitor.prototype = Object.create(Visitor);
-
-/**
- * @overrides Visitor.prototype.enter
- */
-LabelAndShallowSizeVisitor.prototype.enter = function (breakdown, report, edge) {
- if (this._labelPieces && edge) {
- this._labelPieces.push(edge);
- }
-};
-
-/**
- * @overrides Visitor.prototype.exit
- */
-LabelAndShallowSizeVisitor.prototype.exit = function (breakdown, report, edge) {
- if (this._labelPieces && edge) {
- this._labelPieces.pop();
- }
-};
-
-/**
- * @overrides Visitor.prototype.count
- */
-LabelAndShallowSizeVisitor.prototype.count = function (breakdown, report, edge) {
- if (report.count === 0) {
- return;
- }
-
- this._label = this._labelPieces;
- this._labelPieces = undefined;
-
- this._shallowSize = report.bytes;
-};
-
-/**
- * Get the generated label structure accumulated by this visitor.
- *
- * @returns {Object}
- */
-LabelAndShallowSizeVisitor.prototype.label = function () {
- return this._label;
-};
-
-/**
- * Get the shallow size of the node this visitor visited.
- *
- * @returns {Number}
- */
-LabelAndShallowSizeVisitor.prototype.shallowSize = function () {
- return this._shallowSize;
-};
-
-/**
- * Generate a label structure for the node with the given id and grab its
- * shallow size.
- *
- * What is a "label" structure? HeapSnapshot.describeNode essentially takes a
- * census of a single node rather than the whole heap graph. The resulting
- * report has only one count leaf that is non-zero. The label structure is the
- * path in this report from the root to the non-zero count leaf.
- *
- * @param {Number} nodeId
- * @param {HeapSnapshot} snapshot
- * @param {Object} breakdown
- *
- * @returns {Object}
- * An object with the following properties:
- * - {Number} shallowSize
- * - {Object} label
- */
-DominatorTreeNode.getLabelAndShallowSize = function (nodeId,
- snapshot,
- breakdown) {
- const description = snapshot.describeNode(breakdown, nodeId);
-
- const visitor = new LabelAndShallowSizeVisitor();
- walk(breakdown, description, visitor);
-
- return {
- label: visitor.label(),
- shallowSize: visitor.shallowSize(),
- };
-};
-
-/**
- * Do a partial traversal of the given dominator tree and convert it into a tree
- * of `DominatorTreeNode`s. Dominator trees have a node for every node in the
- * snapshot's heap graph, so we must not allocate a JS object for every node. It
- * would be way too many and the node count is effectively unbounded.
- *
- * Go no deeper down the tree than `maxDepth` and only consider at most
- * `maxSiblings` within any single node's children.
- *
- * @param {DominatorTree} dominatorTree
- * @param {HeapSnapshot} snapshot
- * @param {Object} breakdown
- * @param {Number} maxDepth
- * @param {Number} maxSiblings
- *
- * @returns {DominatorTreeNode}
- */
-DominatorTreeNode.partialTraversal = function (dominatorTree,
- snapshot,
- breakdown,
- maxDepth = DEFAULT_MAX_DEPTH,
- maxSiblings = DEFAULT_MAX_SIBLINGS) {
- function dfs(nodeId, depth) {
- const { label, shallowSize } =
- DominatorTreeNode.getLabelAndShallowSize(nodeId, snapshot, breakdown);
- const retainedSize = dominatorTree.getRetainedSize(nodeId);
- const node = new DominatorTreeNode(nodeId, label, shallowSize, retainedSize);
- const childNodeIds = dominatorTree.getImmediatelyDominated(nodeId);
-
- const newDepth = depth + 1;
- if (newDepth < maxDepth) {
- const endIdx = Math.min(childNodeIds.length, maxSiblings);
- for (let i = 0; i < endIdx; i++) {
- DominatorTreeNode.addChild(node, dfs(childNodeIds[i], newDepth));
- }
- node.moreChildrenAvailable = endIdx < childNodeIds.length;
- } else {
- node.moreChildrenAvailable = childNodeIds.length > 0;
- }
-
- return node;
- }
-
- return dfs(dominatorTree.root, 0);
-};
-
-/**
- * Insert more children into the given (partially complete) dominator tree.
- *
- * The tree is updated in an immutable and persistent manner: a new tree is
- * returned, but all unmodified subtrees (which is most) are shared with the
- * original tree. Only the modified nodes are re-allocated.
- *
- * @param {DominatorTreeNode} tree
- * @param {Array<NodeId>} path
- * @param {Array<DominatorTreeNode>} newChildren
- * @param {Boolean} moreChildrenAvailable
- *
- * @returns {DominatorTreeNode}
- */
-DominatorTreeNode.insert = function (tree, path, newChildren, moreChildrenAvailable) {
- function insert(tree, i) {
- if (tree.nodeId !== path[i]) {
- return tree;
- }
-
- if (i == path.length - 1) {
- return immutableUpdate(tree, {
- children: (tree.children || []).concat(newChildren),
- moreChildrenAvailable,
- });
- }
-
- return tree.children
- ? immutableUpdate(tree, {
- children: tree.children.map(c => insert(c, i + 1))
- })
- : tree;
- }
-
- return insert(tree, 0);
-};
-
-/**
- * Get the new canonical node with the given `id` in `tree` that exists along
- * `path`. If there is no such node along `path`, return null.
- *
- * This is useful if we have a reference to a now-outdated DominatorTreeNode due
- * to a recent call to DominatorTreeNode.insert and want to get the up-to-date
- * version. We don't have to walk the whole tree: if there is an updated version
- * of the node then it *must* be along the path.
- *
- * @param {NodeId} id
- * @param {DominatorTreeNode} tree
- * @param {Array<NodeId>} path
- *
- * @returns {DominatorTreeNode|null}
- */
-DominatorTreeNode.getNodeByIdAlongPath = function (id, tree, path) {
- function find(node, i) {
- if (!node || node.nodeId !== path[i]) {
- return null;
- }
-
- if (node.nodeId === id) {
- return node;
- }
-
- if (i === path.length - 1 || !node.children) {
- return null;
- }
-
- const nextId = path[i + 1];
- return find(node.children.find(c => c.nodeId === nextId), i + 1);
- }
-
- return find(tree, 0);
-};
-
-/**
- * Find the shortest retaining paths for the given set of DominatorTreeNodes,
- * and populate each node's `shortestPaths` property with them in place.
- *
- * @param {HeapSnapshot} snapshot
- * @param {Object} breakdown
- * @param {NodeId} start
- * @param {Array<DominatorTreeNode>} treeNodes
- * @param {Number} maxNumPaths
- */
-DominatorTreeNode.attachShortestPaths = function (snapshot,
- breakdown,
- start,
- treeNodes,
- maxNumPaths = DEFAULT_MAX_NUM_PATHS) {
- const idToTreeNode = new Map();
- const targets = [];
- for (let node of treeNodes) {
- const id = node.nodeId;
- idToTreeNode.set(id, node);
- targets.push(id);
- }
-
- const shortestPaths = snapshot.computeShortestPaths(start,
- targets,
- maxNumPaths);
-
- for (let [target, paths] of shortestPaths) {
- const deduped = deduplicatePaths(target, paths);
- deduped.nodes = deduped.nodes.map(id => {
- const { label } =
- DominatorTreeNode.getLabelAndShallowSize(id, snapshot, breakdown);
- return { id, label };
- });
-
- idToTreeNode.get(target).shortestPaths = deduped;
- }
-};
diff --git a/devtools/shared/heapsnapshot/FileDescriptorOutputStream.cpp b/devtools/shared/heapsnapshot/FileDescriptorOutputStream.cpp
deleted file mode 100644
index 72a289558..000000000
--- a/devtools/shared/heapsnapshot/FileDescriptorOutputStream.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/devtools/FileDescriptorOutputStream.h"
-#include "private/pprio.h"
-
-namespace mozilla {
-namespace devtools {
-
-/* static */ already_AddRefed<FileDescriptorOutputStream>
-FileDescriptorOutputStream::Create(const ipc::FileDescriptor& fileDescriptor)
-{
- if (NS_WARN_IF(!fileDescriptor.IsValid()))
- return nullptr;
-
- auto rawFD = fileDescriptor.ClonePlatformHandle();
- PRFileDesc* prfd = PR_ImportFile(PROsfd(rawFD.release()));
- if (NS_WARN_IF(!prfd))
- return nullptr;
-
- RefPtr<FileDescriptorOutputStream> stream = new FileDescriptorOutputStream(prfd);
- return stream.forget();
-}
-
-NS_IMPL_ISUPPORTS(FileDescriptorOutputStream, nsIOutputStream);
-
-NS_IMETHODIMP
-FileDescriptorOutputStream::Close()
-{
- // Repeatedly closing is idempotent.
- if (!fd)
- return NS_OK;
-
- if (PR_Close(fd) != PR_SUCCESS)
- return NS_ERROR_FAILURE;
- fd = nullptr;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-FileDescriptorOutputStream::Write(const char* buf, uint32_t count, uint32_t* retval)
-{
- if (NS_WARN_IF(!fd))
- return NS_ERROR_FAILURE;
-
- auto written = PR_Write(fd, buf, count);
- if (written < 0)
- return NS_ERROR_FAILURE;
- *retval = written;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-FileDescriptorOutputStream::Flush()
-{
- if (NS_WARN_IF(!fd))
- return NS_ERROR_FAILURE;
-
- return PR_Sync(fd) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
-FileDescriptorOutputStream::WriteFrom(nsIInputStream* fromStream, uint32_t count,
- uint32_t* retval)
-{
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-FileDescriptorOutputStream::WriteSegments(nsReadSegmentFun reader, void* closure,
- uint32_t count, uint32_t* retval)
-{
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-FileDescriptorOutputStream::IsNonBlocking(bool* retval)
-{
- *retval = false;
- return NS_OK;
-}
-
-} // namespace devtools
-} // namespace mozilla
diff --git a/devtools/shared/heapsnapshot/FileDescriptorOutputStream.h b/devtools/shared/heapsnapshot/FileDescriptorOutputStream.h
deleted file mode 100644
index 6990f1fc3..000000000
--- a/devtools/shared/heapsnapshot/FileDescriptorOutputStream.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_FileDescriptorOutputStream_h
-#define mozilla_devtools_FileDescriptorOutputStream_h
-
-#include <prio.h>
-
-#include "mozilla/AlreadyAddRefed.h"
-#include "mozilla/ipc/FileDescriptor.h"
-#include "nsIOutputStream.h"
-
-namespace mozilla {
-namespace devtools {
-
-class FileDescriptorOutputStream final : public nsIOutputStream
-{
-private:
- PRFileDesc* fd;
-
-public:
- static already_AddRefed<FileDescriptorOutputStream>
- Create(const ipc::FileDescriptor& fileDescriptor);
-
-private:
- explicit FileDescriptorOutputStream(PRFileDesc* prfd)
- : fd(prfd)
- { }
-
- virtual ~FileDescriptorOutputStream() { }
-
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIOUTPUTSTREAM
-};
-
-} // namespace devtools
-} // namespace mozilla
-
-#endif // mozilla_devtools_FileDescriptorOutputStream_h
diff --git a/devtools/shared/heapsnapshot/HeapAnalysesClient.js b/devtools/shared/heapsnapshot/HeapAnalysesClient.js
deleted file mode 100644
index 98601a2b1..000000000
--- a/devtools/shared/heapsnapshot/HeapAnalysesClient.js
+++ /dev/null
@@ -1,277 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const DevToolsUtils = require("devtools/shared/DevToolsUtils");
-const { DevToolsWorker } = require("devtools/shared/worker/worker");
-
-const WORKER_URL =
- "resource://devtools/shared/heapsnapshot/HeapAnalysesWorker.js";
-var workerCounter = 0;
-
-/**
- * A HeapAnalysesClient instance provides a developer-friendly interface for
- * interacting with a HeapAnalysesWorker. This enables users to be ignorant of
- * the message passing protocol used to communicate with the worker. The
- * HeapAnalysesClient owns the worker, and terminating the worker is done by
- * terminating the client (see the `destroy` method).
- */
-const HeapAnalysesClient = module.exports = function () {
- this._worker = new DevToolsWorker(WORKER_URL, {
- name: `HeapAnalyses-${workerCounter++}`,
- verbose: DevToolsUtils.dumpv.wantVerbose
- });
-};
-
-/**
- * Destroy the worker, causing it to release its resources (such as heap
- * snapshots it has deserialized and read into memory). The client is no longer
- * usable after calling this method.
- */
-HeapAnalysesClient.prototype.destroy = function () {
- this._worker.destroy();
- this._worker = null;
-};
-
-/**
- * Tell the worker to read into memory the heap snapshot at the given file
- * path. This is a prerequisite for asking the worker to perform various
- * analyses on a heap snapshot.
- *
- * @param {String} snapshotFilePath
- *
- * @returns Promise
- * The promise is fulfilled if the heap snapshot is successfully
- * deserialized and read into memory. The promise is rejected if that
- * does not happen, eg due to a bad file path or malformed heap
- * snapshot file.
- */
-HeapAnalysesClient.prototype.readHeapSnapshot = function (snapshotFilePath) {
- return this._worker.performTask("readHeapSnapshot", { snapshotFilePath });
-};
-
-/**
- * Tell the worker to delete all references to the snapshot and dominator trees
- * linked to the provided snapshot file path.
- *
- * @param {String} snapshotFilePath
- * @return Promise<undefined>
- */
-HeapAnalysesClient.prototype.deleteHeapSnapshot = function (snapshotFilePath) {
- return this._worker.performTask("deleteHeapSnapshot", { snapshotFilePath });
-};
-
-/**
- * Request the creation time given a snapshot file path. Returns `null`
- * if snapshot does not exist.
- *
- * @param {String} snapshotFilePath
- * The path to the snapshot.
- * @return {Number?}
- * The unix timestamp of the creation time of the snapshot, or null if
- * snapshot does not exist.
- */
-HeapAnalysesClient.prototype.getCreationTime = function (snapshotFilePath) {
- return this._worker.performTask("getCreationTime", snapshotFilePath);
-};
-
-/** * Censuses *****************************************************************/
-
-/**
- * Ask the worker to perform a census analysis on the heap snapshot with the
- * given path. The heap snapshot at the given path must have already been read
- * into memory by the worker (see `readHeapSnapshot`).
- *
- * @param {String} snapshotFilePath
- *
- * @param {Object} censusOptions
- * A structured-cloneable object specifying the requested census's
- * breakdown. See the "takeCensus" section of
- * `js/src/doc/Debugger/Debugger.Memory.md` for detailed documentation.
- *
- * @param {Object} requestOptions
- * An object specifying options of this worker request.
- * - {Boolean} asTreeNode
- * Whether or not the census is returned as a CensusTreeNode,
- * or just a breakdown report. Defaults to false.
- * @see `devtools/shared/heapsnapshot/census-tree-node.js`
- * - {Boolean} asInvertedTreeNode
- * Whether or not the census is returned as an inverted
- * CensusTreeNode. Defaults to false.
- * - {String} filter
- * A filter string to prune the resulting tree with. Only applies if
- * either asTreeNode or asInvertedTreeNode is true.
- *
- * @returns Promise<Object>
- * An object with the following properties:
- * - report:
- * The report generated by the given census breakdown, or a
- * CensusTreeNode generated by the given census breakdown if
- * `asTreeNode` is true.
- * - parentMap:
- * The result of calling CensusUtils.createParentMap on the generated
- * report. Only exists if asTreeNode or asInvertedTreeNode are set.
- */
-HeapAnalysesClient.prototype.takeCensus = function (snapshotFilePath,
- censusOptions,
- requestOptions = {}) {
- return this._worker.performTask("takeCensus", {
- snapshotFilePath,
- censusOptions,
- requestOptions,
- });
-};
-
-/**
- * Get the individual nodes that correspond to the given census report leaf
- * indices.
- *
- * @param {Object} opts
- * An object with the following properties:
- * - {DominatorTreeId} dominatorTreeId: The id of the dominator tree.
- * - {Set<Number>} indices: The indices of the census report leaves we
- * would like to get the individuals for.
- * - {Object} censusBreakdown: The breakdown used to generate the census.
- * - {Object} labelBreakdown: The breakdown we would like to use when
- * labeling the resulting nodes.
- * - {Number} maxRetainingPaths: The maximum number of retaining paths to
- * compute for each node.
- * - {Number} maxIndividuals: The maximum number of individual nodes to
- * return.
- *
- * @returns {Promise<Object>}
- * A promise of an object with the following properties:
- * - {Array<DominatorTreeNode>} nodes: An array of `DominatorTreeNode`s
- * with their shortest paths attached, and without any dominator tree
- * child/parent information attached. The results are sorted by
- * retained size.
- *
- */
-HeapAnalysesClient.prototype.getCensusIndividuals = function (opts) {
- return this._worker.performTask("getCensusIndividuals", opts);
-};
-
-/**
- * Request that the worker take a census on the heap snapshots with the given
- * paths and then return the difference between them. Both heap snapshots must
- * have already been read into memory by the worker (see `readHeapSnapshot`).
- *
- * @param {String} firstSnapshotFilePath
- * The first snapshot file path.
- *
- * @param {String} secondSnapshotFilePath
- * The second snapshot file path.
- *
- * @param {Object} censusOptions
- * A structured-cloneable object specifying the requested census's
- * breakdown. See the "takeCensus" section of
- * `js/src/doc/Debugger/Debugger.Memory.md` for detailed documentation.
- *
- * @param {Object} requestOptions
- * An object specifying options for this request.
- * - {Boolean} asTreeNode
- * Whether the resulting delta report should be converted to a census
- * tree node before returned. Defaults to false.
- * - {Boolean} asInvertedTreeNode
- * Whether or not the census is returned as an inverted
- * CensusTreeNode. Defaults to false.
- * - {String} filter
- * A filter string to prune the resulting tree with. Only applies if
- * either asTreeNode or asInvertedTreeNode is true.
- *
- * @returns Promise<Object>
- * - delta:
- * The delta report generated by diffing the two census reports, or a
- * CensusTreeNode generated from the delta report if
- * `requestOptions.asTreeNode` was true.
- * - parentMap:
- * The result of calling CensusUtils.createParentMap on the generated
- * delta. Only exists if asTreeNode or asInvertedTreeNode are set.
- */
-HeapAnalysesClient.prototype.takeCensusDiff = function (firstSnapshotFilePath,
- secondSnapshotFilePath,
- censusOptions,
- requestOptions = {}) {
- return this._worker.performTask("takeCensusDiff", {
- firstSnapshotFilePath,
- secondSnapshotFilePath,
- censusOptions,
- requestOptions
- });
-};
-
-/** * Dominator Trees **********************************************************/
-
-/**
- * Compute the dominator tree of the heap snapshot loaded from the given file
- * path. Returns the id of the computed dominator tree.
- *
- * @param {String} snapshotFilePath
- *
- * @returns {Promise<DominatorTreeId>}
- */
-HeapAnalysesClient.prototype.computeDominatorTree = function (snapshotFilePath) {
- return this._worker.performTask("computeDominatorTree", snapshotFilePath);
-};
-
-/**
- * Get the initial, partial view of the dominator tree with the given id.
- *
- * @param {Object} opts
- * An object specifying options for this request.
- * - {DominatorTreeId} dominatorTreeId
- * The id of the dominator tree.
- * - {Object} breakdown
- * The breakdown used to generate node labels.
- * - {Number} maxDepth
- * The maximum depth to traverse down the tree to create this initial
- * view.
- * - {Number} maxSiblings
- * The maximum number of siblings to visit within each traversed node's
- * children.
- * - {Number} maxRetainingPaths
- * The maximum number of retaining paths to find for each node.
- *
- * @returns {Promise<DominatorTreeNode>}
- */
-HeapAnalysesClient.prototype.getDominatorTree = function (opts) {
- return this._worker.performTask("getDominatorTree", opts);
-};
-
-/**
- * Get a subset of a nodes children in the dominator tree.
- *
- * @param {Object} opts
- * An object specifying options for this request.
- * - {DominatorTreeId} dominatorTreeId
- * The id of the dominator tree.
- * - {NodeId} nodeId
- * The id of the node whose children are being found.
- * - {Object} breakdown
- * The breakdown used to generate node labels.
- * - {Number} startIndex
- * The starting index within the full set of immediately dominated
- * children of the children being requested. Children are always sorted
- * by greatest to least retained size.
- * - {Number} maxCount
- * The maximum number of children to return.
- * - {Number} maxRetainingPaths
- * The maximum number of retaining paths to find for each node.
- *
- * @returns {Promise<Object>}
- * A promise of an object with the following properties:
- * - {Array<DominatorTreeNode>} nodes
- * The requested nodes that are immediately dominated by the node
- * identified by `opts.nodeId`.
- * - {Boolean} moreChildrenAvailable
- * True iff there are more children available after the returned
- * nodes.
- * - {Array<NodeId>} path
- * The path through the tree from the root to these node's parent, eg
- * [root's id, child of root's id, child of child of root's id, ..., `nodeId`].
- */
-HeapAnalysesClient.prototype.getImmediatelyDominated = function (opts) {
- return this._worker.performTask("getImmediatelyDominated", opts);
-};
diff --git a/devtools/shared/heapsnapshot/HeapAnalysesWorker.js b/devtools/shared/heapsnapshot/HeapAnalysesWorker.js
deleted file mode 100644
index d07d67f80..000000000
--- a/devtools/shared/heapsnapshot/HeapAnalysesWorker.js
+++ /dev/null
@@ -1,303 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* global ThreadSafeChromeUtils*/
-
-// This is a worker which reads offline heap snapshots into memory and performs
-// heavyweight analyses on them without blocking the main thread. A
-// HeapAnalysesWorker is owned and communicated with by a HeapAnalysesClient
-// instance. See HeapAnalysesClient.js.
-
-"use strict";
-
-importScripts("resource://gre/modules/workers/require.js");
-importScripts("resource://devtools/shared/worker/helper.js");
-const { censusReportToCensusTreeNode } = require("resource://devtools/shared/heapsnapshot/census-tree-node.js");
-const DominatorTreeNode = require("resource://devtools/shared/heapsnapshot/DominatorTreeNode.js");
-const CensusUtils = require("resource://devtools/shared/heapsnapshot/CensusUtils.js");
-
-const DEFAULT_START_INDEX = 0;
-const DEFAULT_MAX_COUNT = 50;
-
-/**
- * The set of HeapSnapshot instances this worker has read into memory. Keyed by
- * snapshot file path.
- */
-const snapshots = Object.create(null);
-
-/**
- * The set of `DominatorTree`s that have been computed, mapped by their id (aka
- * the index into this array).
- *
- * @see /dom/webidl/DominatorTree.webidl
- */
-const dominatorTrees = [];
-
-/**
- * The i^th HeapSnapshot in this array is the snapshot used to generate the i^th
- * dominator tree in `dominatorTrees` above. This lets us map from a dominator
- * tree id to the snapshot it came from.
- */
-const dominatorTreeSnapshots = [];
-
-/**
- * @see HeapAnalysesClient.prototype.readHeapSnapshot
- */
-workerHelper.createTask(self, "readHeapSnapshot", ({ snapshotFilePath }) => {
- snapshots[snapshotFilePath] =
- ThreadSafeChromeUtils.readHeapSnapshot(snapshotFilePath);
- return true;
-});
-
-/**
- * @see HeapAnalysesClient.prototype.deleteHeapSnapshot
- */
-workerHelper.createTask(self, "deleteHeapSnapshot", ({ snapshotFilePath }) => {
- let snapshot = snapshots[snapshotFilePath];
- if (!snapshot) {
- throw new Error(`No known heap snapshot for '${snapshotFilePath}'`);
- }
-
- snapshots[snapshotFilePath] = undefined;
-
- let dominatorTreeId = dominatorTreeSnapshots.indexOf(snapshot);
- if (dominatorTreeId != -1) {
- dominatorTreeSnapshots[dominatorTreeId] = undefined;
- dominatorTrees[dominatorTreeId] = undefined;
- }
-});
-
-/**
- * @see HeapAnalysesClient.prototype.takeCensus
- */
-workerHelper.createTask(self, "takeCensus", ({ snapshotFilePath, censusOptions, requestOptions }) => {
- if (!snapshots[snapshotFilePath]) {
- throw new Error(`No known heap snapshot for '${snapshotFilePath}'`);
- }
-
- let report = snapshots[snapshotFilePath].takeCensus(censusOptions);
- let parentMap;
-
- if (requestOptions.asTreeNode || requestOptions.asInvertedTreeNode) {
- const opts = { filter: requestOptions.filter || null };
- if (requestOptions.asInvertedTreeNode) {
- opts.invert = true;
- }
- report = censusReportToCensusTreeNode(censusOptions.breakdown, report, opts);
- parentMap = CensusUtils.createParentMap(report);
- }
-
- return { report, parentMap };
-});
-
-/**
- * @see HeapAnalysesClient.prototype.getCensusIndividuals
- */
-workerHelper.createTask(self, "getCensusIndividuals", request => {
- const {
- dominatorTreeId,
- indices,
- censusBreakdown,
- labelBreakdown,
- maxRetainingPaths,
- maxIndividuals,
- } = request;
-
- const dominatorTree = dominatorTrees[dominatorTreeId];
- if (!dominatorTree) {
- throw new Error(
- `There does not exist a DominatorTree with the id ${dominatorTreeId}`);
- }
-
- const snapshot = dominatorTreeSnapshots[dominatorTreeId];
- const nodeIds = CensusUtils.getCensusIndividuals(indices, censusBreakdown, snapshot);
-
- const nodes = nodeIds
- .sort((a, b) => dominatorTree.getRetainedSize(b) - dominatorTree.getRetainedSize(a))
- .slice(0, maxIndividuals)
- .map(id => {
- const { label, shallowSize } =
- DominatorTreeNode.getLabelAndShallowSize(id, snapshot, labelBreakdown);
- const retainedSize = dominatorTree.getRetainedSize(id);
- const node = new DominatorTreeNode(id, label, shallowSize, retainedSize);
- node.moreChildrenAvailable = false;
- return node;
- });
-
- DominatorTreeNode.attachShortestPaths(snapshot,
- labelBreakdown,
- dominatorTree.root,
- nodes,
- maxRetainingPaths);
-
- return { nodes };
-});
-
-/**
- * @see HeapAnalysesClient.prototype.takeCensusDiff
- */
-workerHelper.createTask(self, "takeCensusDiff", request => {
- const {
- firstSnapshotFilePath,
- secondSnapshotFilePath,
- censusOptions,
- requestOptions
- } = request;
-
- if (!snapshots[firstSnapshotFilePath]) {
- throw new Error(`No known heap snapshot for '${firstSnapshotFilePath}'`);
- }
-
- if (!snapshots[secondSnapshotFilePath]) {
- throw new Error(`No known heap snapshot for '${secondSnapshotFilePath}'`);
- }
-
- const first = snapshots[firstSnapshotFilePath].takeCensus(censusOptions);
- const second = snapshots[secondSnapshotFilePath].takeCensus(censusOptions);
- let delta = CensusUtils.diff(censusOptions.breakdown, first, second);
- let parentMap;
-
- if (requestOptions.asTreeNode || requestOptions.asInvertedTreeNode) {
- const opts = { filter: requestOptions.filter || null };
- if (requestOptions.asInvertedTreeNode) {
- opts.invert = true;
- }
- delta = censusReportToCensusTreeNode(censusOptions.breakdown, delta, opts);
- parentMap = CensusUtils.createParentMap(delta);
- }
-
- return { delta, parentMap };
-});
-
-/**
- * @see HeapAnalysesClient.prototype.getCreationTime
- */
-workerHelper.createTask(self, "getCreationTime", snapshotFilePath => {
- if (!snapshots[snapshotFilePath]) {
- throw new Error(`No known heap snapshot for '${snapshotFilePath}'`);
- }
- return snapshots[snapshotFilePath].creationTime;
-});
-
-/**
- * @see HeapAnalysesClient.prototype.computeDominatorTree
- */
-workerHelper.createTask(self, "computeDominatorTree", snapshotFilePath => {
- const snapshot = snapshots[snapshotFilePath];
- if (!snapshot) {
- throw new Error(`No known heap snapshot for '${snapshotFilePath}'`);
- }
-
- const id = dominatorTrees.length;
- dominatorTrees.push(snapshot.computeDominatorTree());
- dominatorTreeSnapshots.push(snapshot);
- return id;
-});
-
-/**
- * @see HeapAnalysesClient.prototype.getDominatorTree
- */
-workerHelper.createTask(self, "getDominatorTree", request => {
- const {
- dominatorTreeId,
- breakdown,
- maxDepth,
- maxSiblings,
- maxRetainingPaths,
- } = request;
-
- if (!(0 <= dominatorTreeId && dominatorTreeId < dominatorTrees.length)) {
- throw new Error(
- `There does not exist a DominatorTree with the id ${dominatorTreeId}`);
- }
-
- const dominatorTree = dominatorTrees[dominatorTreeId];
- const snapshot = dominatorTreeSnapshots[dominatorTreeId];
-
- const tree = DominatorTreeNode.partialTraversal(dominatorTree,
- snapshot,
- breakdown,
- maxDepth,
- maxSiblings);
-
- const nodes = [];
- (function getNodes(node) {
- nodes.push(node);
- if (node.children) {
- for (let i = 0, length = node.children.length; i < length; i++) {
- getNodes(node.children[i]);
- }
- }
- }(tree));
-
- DominatorTreeNode.attachShortestPaths(snapshot,
- breakdown,
- dominatorTree.root,
- nodes,
- maxRetainingPaths);
-
- return tree;
-});
-
-/**
- * @see HeapAnalysesClient.prototype.getImmediatelyDominated
- */
-workerHelper.createTask(self, "getImmediatelyDominated", request => {
- const {
- dominatorTreeId,
- nodeId,
- breakdown,
- startIndex,
- maxCount,
- maxRetainingPaths,
- } = request;
-
- if (!(0 <= dominatorTreeId && dominatorTreeId < dominatorTrees.length)) {
- throw new Error(
- `There does not exist a DominatorTree with the id ${dominatorTreeId}`);
- }
-
- const dominatorTree = dominatorTrees[dominatorTreeId];
- const snapshot = dominatorTreeSnapshots[dominatorTreeId];
-
- const childIds = dominatorTree.getImmediatelyDominated(nodeId);
- if (!childIds) {
- throw new Error(`${nodeId} is not a node id in the dominator tree`);
- }
-
- const start = startIndex || DEFAULT_START_INDEX;
- const count = maxCount || DEFAULT_MAX_COUNT;
- const end = start + count;
-
- const nodes = childIds
- .slice(start, end)
- .map(id => {
- const { label, shallowSize } =
- DominatorTreeNode.getLabelAndShallowSize(id, snapshot, breakdown);
- const retainedSize = dominatorTree.getRetainedSize(id);
- const node = new DominatorTreeNode(id, label, shallowSize, retainedSize);
- node.parentId = nodeId;
- // DominatorTree.getImmediatelyDominated will always return non-null here
- // because we got the id directly from the dominator tree.
- node.moreChildrenAvailable = dominatorTree.getImmediatelyDominated(id).length > 0;
- return node;
- });
-
- const path = [];
- let id = nodeId;
- do {
- path.push(id);
- id = dominatorTree.getImmediateDominator(id);
- } while (id !== null);
- path.reverse();
-
- const moreChildrenAvailable = childIds.length > end;
-
- DominatorTreeNode.attachShortestPaths(snapshot,
- breakdown,
- dominatorTree.root,
- nodes,
- maxRetainingPaths);
-
- return { nodes, moreChildrenAvailable, path };
-});
diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.cpp b/devtools/shared/heapsnapshot/HeapSnapshot.cpp
deleted file mode 100644
index 299a96a9c..000000000
--- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp
+++ /dev/null
@@ -1,1619 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "HeapSnapshot.h"
-
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/gzip_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-
-#include "js/Debug.h"
-#include "js/TypeDecls.h"
-#include "js/UbiNodeBreadthFirst.h"
-#include "js/UbiNodeCensus.h"
-#include "js/UbiNodeDominatorTree.h"
-#include "js/UbiNodeShortestPaths.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/CycleCollectedJSContext.h"
-#include "mozilla/devtools/AutoMemMap.h"
-#include "mozilla/devtools/CoreDump.pb.h"
-#include "mozilla/devtools/DeserializedNode.h"
-#include "mozilla/devtools/DominatorTree.h"
-#include "mozilla/devtools/FileDescriptorOutputStream.h"
-#include "mozilla/devtools/HeapSnapshotTempFileHelperChild.h"
-#include "mozilla/devtools/ZeroCopyNSIOutputStream.h"
-#include "mozilla/dom/ChromeUtils.h"
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/HeapSnapshotBinding.h"
-#include "mozilla/RangedPtr.h"
-#include "mozilla/Unused.h"
-
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsCRTGlue.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsIFile.h"
-#include "nsIOutputStream.h"
-#include "nsISupportsImpl.h"
-#include "nsNetUtil.h"
-#include "nsPrintfCString.h"
-#include "prerror.h"
-#include "prio.h"
-#include "prtypes.h"
-
-namespace mozilla {
-namespace devtools {
-
-using namespace JS;
-using namespace dom;
-
-using ::google::protobuf::io::ArrayInputStream;
-using ::google::protobuf::io::CodedInputStream;
-using ::google::protobuf::io::GzipInputStream;
-using ::google::protobuf::io::ZeroCopyInputStream;
-
-using JS::ubi::AtomOrTwoByteChars;
-using JS::ubi::ShortestPaths;
-
-MallocSizeOf
-GetCurrentThreadDebuggerMallocSizeOf()
-{
- auto ccjscx = CycleCollectedJSContext::Get();
- MOZ_ASSERT(ccjscx);
- auto cx = ccjscx->Context();
- MOZ_ASSERT(cx);
- auto mallocSizeOf = JS::dbg::GetDebuggerMallocSizeOf(cx);
- MOZ_ASSERT(mallocSizeOf);
- return mallocSizeOf;
-}
-
-/*** Cycle Collection Boilerplate *****************************************************************/
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HeapSnapshot, mParent)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(HeapSnapshot)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(HeapSnapshot)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HeapSnapshot)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-/* virtual */ JSObject*
-HeapSnapshot::WrapObject(JSContext* aCx, HandleObject aGivenProto)
-{
- return HeapSnapshotBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/*** Reading Heap Snapshots ***********************************************************************/
-
-/* static */ already_AddRefed<HeapSnapshot>
-HeapSnapshot::Create(JSContext* cx,
- GlobalObject& global,
- const uint8_t* buffer,
- uint32_t size,
- ErrorResult& rv)
-{
- RefPtr<HeapSnapshot> snapshot = new HeapSnapshot(cx, global.GetAsSupports());
- if (!snapshot->init(cx, buffer, size)) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
- return snapshot.forget();
-}
-
-template<typename MessageType>
-static bool
-parseMessage(ZeroCopyInputStream& stream, uint32_t sizeOfMessage, MessageType& message)
-{
- // We need to create a new `CodedInputStream` for each message so that the
- // 64MB limit is applied per-message rather than to the whole stream.
- CodedInputStream codedStream(&stream);
-
- // The protobuf message nesting that core dumps exhibit is dominated by
- // allocation stacks' frames. In the most deeply nested case, each frame has
- // two messages: a StackFrame message and a StackFrame::Data message. These
- // frames are on top of a small constant of other messages. There are a
- // MAX_STACK_DEPTH number of frames, so we multiply this by 3 to make room for
- // the two messages per frame plus some head room for the constant number of
- // non-dominating messages.
- codedStream.SetRecursionLimit(HeapSnapshot::MAX_STACK_DEPTH * 3);
-
- auto limit = codedStream.PushLimit(sizeOfMessage);
- if (NS_WARN_IF(!message.ParseFromCodedStream(&codedStream)) ||
- NS_WARN_IF(!codedStream.ConsumedEntireMessage()) ||
- NS_WARN_IF(codedStream.BytesUntilLimit() != 0))
- {
- return false;
- }
-
- codedStream.PopLimit(limit);
- return true;
-}
-
-template<typename CharT, typename InternedStringSet>
-struct GetOrInternStringMatcher
-{
- InternedStringSet& internedStrings;
-
- explicit GetOrInternStringMatcher(InternedStringSet& strings) : internedStrings(strings) { }
-
- const CharT* match(const std::string* str) {
- MOZ_ASSERT(str);
- size_t length = str->length() / sizeof(CharT);
- auto tempString = reinterpret_cast<const CharT*>(str->data());
-
- UniquePtr<CharT[], NSFreePolicy> owned(NS_strndup(tempString, length));
- if (!owned || !internedStrings.append(Move(owned)))
- return nullptr;
-
- return internedStrings.back().get();
- }
-
- const CharT* match(uint64_t ref) {
- if (MOZ_LIKELY(ref < internedStrings.length())) {
- auto& string = internedStrings[ref];
- MOZ_ASSERT(string);
- return string.get();
- }
-
- return nullptr;
- }
-};
-
-template<
- // Either char or char16_t.
- typename CharT,
- // A reference to either `internedOneByteStrings` or `internedTwoByteStrings`
- // if CharT is char or char16_t respectively.
- typename InternedStringSet>
-const CharT*
-HeapSnapshot::getOrInternString(InternedStringSet& internedStrings,
- Maybe<StringOrRef>& maybeStrOrRef)
-{
- // Incomplete message: has neither a string nor a reference to an already
- // interned string.
- if (MOZ_UNLIKELY(maybeStrOrRef.isNothing()))
- return nullptr;
-
- GetOrInternStringMatcher<CharT, InternedStringSet> m(internedStrings);
- return maybeStrOrRef->match(m);
-}
-
-// Get a de-duplicated string as a Maybe<StringOrRef> from the given `msg`.
-#define GET_STRING_OR_REF_WITH_PROP_NAMES(msg, strPropertyName, refPropertyName) \
- (msg.has_##refPropertyName() \
- ? Some(StringOrRef(msg.refPropertyName())) \
- : msg.has_##strPropertyName() \
- ? Some(StringOrRef(&msg.strPropertyName())) \
- : Nothing())
-
-#define GET_STRING_OR_REF(msg, property) \
- (msg.has_##property##ref() \
- ? Some(StringOrRef(msg.property##ref())) \
- : msg.has_##property() \
- ? Some(StringOrRef(&msg.property())) \
- : Nothing())
-
-bool
-HeapSnapshot::saveNode(const protobuf::Node& node, NodeIdSet& edgeReferents)
-{
- // NB: de-duplicated string properties must be read back and interned in the
- // same order here as they are written and serialized in
- // `CoreDumpWriter::writeNode` or else indices in references to already
- // serialized strings will be off.
-
- if (NS_WARN_IF(!node.has_id()))
- return false;
- NodeId id = node.id();
-
- // NodeIds are derived from pointers (at most 48 bits) and we rely on them
- // fitting into JS numbers (IEEE 754 doubles, can precisely store 53 bit
- // integers) despite storing them on disk as 64 bit integers.
- if (NS_WARN_IF(!JS::Value::isNumberRepresentable(id)))
- return false;
-
- // Should only deserialize each node once.
- if (NS_WARN_IF(nodes.has(id)))
- return false;
-
- if (NS_WARN_IF(!JS::ubi::Uint32IsValidCoarseType(node.coarsetype())))
- return false;
- auto coarseType = JS::ubi::Uint32ToCoarseType(node.coarsetype());
-
- Maybe<StringOrRef> typeNameOrRef = GET_STRING_OR_REF_WITH_PROP_NAMES(node, typename_, typenameref);
- auto typeName = getOrInternString<char16_t>(internedTwoByteStrings, typeNameOrRef);
- if (NS_WARN_IF(!typeName))
- return false;
-
- if (NS_WARN_IF(!node.has_size()))
- return false;
- uint64_t size = node.size();
-
- auto edgesLength = node.edges_size();
- DeserializedNode::EdgeVector edges;
- if (NS_WARN_IF(!edges.reserve(edgesLength)))
- return false;
- for (decltype(edgesLength) i = 0; i < edgesLength; i++) {
- auto& protoEdge = node.edges(i);
-
- if (NS_WARN_IF(!protoEdge.has_referent()))
- return false;
- NodeId referent = protoEdge.referent();
-
- if (NS_WARN_IF(!edgeReferents.put(referent)))
- return false;
-
- const char16_t* edgeName = nullptr;
- if (protoEdge.EdgeNameOrRef_case() != protobuf::Edge::EDGENAMEORREF_NOT_SET) {
- Maybe<StringOrRef> edgeNameOrRef = GET_STRING_OR_REF(protoEdge, name);
- edgeName = getOrInternString<char16_t>(internedTwoByteStrings, edgeNameOrRef);
- if (NS_WARN_IF(!edgeName))
- return false;
- }
-
- edges.infallibleAppend(DeserializedEdge(referent, edgeName));
- }
-
- Maybe<StackFrameId> allocationStack;
- if (node.has_allocationstack()) {
- StackFrameId id = 0;
- if (NS_WARN_IF(!saveStackFrame(node.allocationstack(), id)))
- return false;
- allocationStack.emplace(id);
- }
- MOZ_ASSERT(allocationStack.isSome() == node.has_allocationstack());
-
- const char* jsObjectClassName = nullptr;
- if (node.JSObjectClassNameOrRef_case() != protobuf::Node::JSOBJECTCLASSNAMEORREF_NOT_SET) {
- Maybe<StringOrRef> clsNameOrRef = GET_STRING_OR_REF(node, jsobjectclassname);
- jsObjectClassName = getOrInternString<char>(internedOneByteStrings, clsNameOrRef);
- if (NS_WARN_IF(!jsObjectClassName))
- return false;
- }
-
- const char* scriptFilename = nullptr;
- if (node.ScriptFilenameOrRef_case() != protobuf::Node::SCRIPTFILENAMEORREF_NOT_SET) {
- Maybe<StringOrRef> scriptFilenameOrRef = GET_STRING_OR_REF(node, scriptfilename);
- scriptFilename = getOrInternString<char>(internedOneByteStrings, scriptFilenameOrRef);
- if (NS_WARN_IF(!scriptFilename))
- return false;
- }
-
- if (NS_WARN_IF(!nodes.putNew(id, DeserializedNode(id, coarseType, typeName,
- size, Move(edges),
- allocationStack,
- jsObjectClassName,
- scriptFilename, *this))))
- {
- return false;
- };
-
- return true;
-}
-
-bool
-HeapSnapshot::saveStackFrame(const protobuf::StackFrame& frame,
- StackFrameId& outFrameId)
-{
- // NB: de-duplicated string properties must be read in the same order here as
- // they are written in `CoreDumpWriter::getProtobufStackFrame` or else indices
- // in references to already serialized strings will be off.
-
- if (frame.has_ref()) {
- // We should only get a reference to the previous frame if we have already
- // seen the previous frame.
- if (!frames.has(frame.ref()))
- return false;
-
- outFrameId = frame.ref();
- return true;
- }
-
- // Incomplete message.
- if (!frame.has_data())
- return false;
-
- auto data = frame.data();
-
- if (!data.has_id())
- return false;
- StackFrameId id = data.id();
-
- // This should be the first and only time we see this frame.
- if (frames.has(id))
- return false;
-
- if (!data.has_line())
- return false;
- uint32_t line = data.line();
-
- if (!data.has_column())
- return false;
- uint32_t column = data.column();
-
- if (!data.has_issystem())
- return false;
- bool isSystem = data.issystem();
-
- if (!data.has_isselfhosted())
- return false;
- bool isSelfHosted = data.isselfhosted();
-
- Maybe<StringOrRef> sourceOrRef = GET_STRING_OR_REF(data, source);
- auto source = getOrInternString<char16_t>(internedTwoByteStrings, sourceOrRef);
- if (!source)
- return false;
-
- const char16_t* functionDisplayName = nullptr;
- if (data.FunctionDisplayNameOrRef_case() !=
- protobuf::StackFrame_Data::FUNCTIONDISPLAYNAMEORREF_NOT_SET)
- {
- Maybe<StringOrRef> nameOrRef = GET_STRING_OR_REF(data, functiondisplayname);
- functionDisplayName = getOrInternString<char16_t>(internedTwoByteStrings, nameOrRef);
- if (!functionDisplayName)
- return false;
- }
-
- Maybe<StackFrameId> parent;
- if (data.has_parent()) {
- StackFrameId parentId = 0;
- if (!saveStackFrame(data.parent(), parentId))
- return false;
- parent = Some(parentId);
- }
-
- if (!frames.putNew(id, DeserializedStackFrame(id, parent, line, column,
- source, functionDisplayName,
- isSystem, isSelfHosted, *this)))
- {
- return false;
- }
-
- outFrameId = id;
- return true;
-}
-
-#undef GET_STRING_OR_REF_WITH_PROP_NAMES
-#undef GET_STRING_OR_REF
-
-// Because protobuf messages aren't self-delimiting, we serialize each message
-// preceded by its size in bytes. When deserializing, we read this size and then
-// limit reading from the stream to the given byte size. If we didn't, then the
-// first message would consume the entire stream.
-static bool
-readSizeOfNextMessage(ZeroCopyInputStream& stream, uint32_t* sizep)
-{
- MOZ_ASSERT(sizep);
- CodedInputStream codedStream(&stream);
- return codedStream.ReadVarint32(sizep) && *sizep > 0;
-}
-
-bool
-HeapSnapshot::init(JSContext* cx, const uint8_t* buffer, uint32_t size)
-{
- if (!nodes.init() || !frames.init())
- return false;
-
- ArrayInputStream stream(buffer, size);
- GzipInputStream gzipStream(&stream);
- uint32_t sizeOfMessage = 0;
-
- // First is the metadata.
-
- protobuf::Metadata metadata;
- if (NS_WARN_IF(!readSizeOfNextMessage(gzipStream, &sizeOfMessage)))
- return false;
- if (!parseMessage(gzipStream, sizeOfMessage, metadata))
- return false;
- if (metadata.has_timestamp())
- timestamp.emplace(metadata.timestamp());
-
- // Next is the root node.
-
- protobuf::Node root;
- if (NS_WARN_IF(!readSizeOfNextMessage(gzipStream, &sizeOfMessage)))
- return false;
- if (!parseMessage(gzipStream, sizeOfMessage, root))
- return false;
-
- // Although the id is optional in the protobuf format for future proofing, we
- // can't currently do anything without it.
- if (NS_WARN_IF(!root.has_id()))
- return false;
- rootId = root.id();
-
- // The set of all node ids we've found edges pointing to.
- NodeIdSet edgeReferents(cx);
- if (NS_WARN_IF(!edgeReferents.init()))
- return false;
-
- if (NS_WARN_IF(!saveNode(root, edgeReferents)))
- return false;
-
- // Finally, the rest of the nodes in the core dump.
-
- // Test for the end of the stream. The protobuf library gives no way to tell
- // the difference between an underlying read error and the stream being
- // done. All we can do is attempt to read the size of the next message and
- // extrapolate guestimations from the result of that operation.
- while (readSizeOfNextMessage(gzipStream, &sizeOfMessage)) {
- protobuf::Node node;
- if (!parseMessage(gzipStream, sizeOfMessage, node))
- return false;
- if (NS_WARN_IF(!saveNode(node, edgeReferents)))
- return false;
- }
-
- // Check the set of node ids referred to by edges we found and ensure that we
- // have the node corresponding to each id. If we don't have all of them, it is
- // unsafe to perform analyses of this heap snapshot.
- for (auto range = edgeReferents.all(); !range.empty(); range.popFront()) {
- if (NS_WARN_IF(!nodes.has(range.front())))
- return false;
- }
-
- return true;
-}
-
-
-/*** Heap Snapshot Analyses ***********************************************************************/
-
-void
-HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options,
- JS::MutableHandleValue rval, ErrorResult& rv)
-{
- JS::ubi::Census census(cx);
- if (NS_WARN_IF(!census.init())) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- JS::ubi::CountTypePtr rootType;
- if (NS_WARN_IF(!JS::ubi::ParseCensusOptions(cx, census, options, rootType))) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return;
- }
-
- JS::ubi::RootedCount rootCount(cx, rootType->makeCount());
- if (NS_WARN_IF(!rootCount)) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- JS::ubi::CensusHandler handler(census, rootCount, GetCurrentThreadDebuggerMallocSizeOf());
-
- {
- JS::AutoCheckCannotGC nogc;
-
- JS::ubi::CensusTraversal traversal(cx, handler, nogc);
- if (NS_WARN_IF(!traversal.init())) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- if (NS_WARN_IF(!traversal.addStart(getRoot()))) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- if (NS_WARN_IF(!traversal.traverse())) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return;
- }
- }
-
- if (NS_WARN_IF(!handler.report(cx, rval))) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-}
-
-void
-HeapSnapshot::DescribeNode(JSContext* cx, JS::HandleObject breakdown, uint64_t nodeId,
- JS::MutableHandleValue rval, ErrorResult& rv) {
- MOZ_ASSERT(breakdown);
- JS::RootedValue breakdownVal(cx, JS::ObjectValue(*breakdown));
- JS::ubi::CountTypePtr rootType = JS::ubi::ParseBreakdown(cx, breakdownVal);
- if (NS_WARN_IF(!rootType)) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return;
- }
-
- JS::ubi::RootedCount rootCount(cx, rootType->makeCount());
- if (NS_WARN_IF(!rootCount)) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- JS::ubi::Node::Id id(nodeId);
- Maybe<JS::ubi::Node> node = getNodeById(id);
- if (NS_WARN_IF(node.isNothing())) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
- MallocSizeOf mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf();
- if (NS_WARN_IF(!rootCount->count(mallocSizeOf, *node))) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- if (NS_WARN_IF(!rootCount->report(cx, rval))) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-}
-
-
-already_AddRefed<DominatorTree>
-HeapSnapshot::ComputeDominatorTree(ErrorResult& rv)
-{
- Maybe<JS::ubi::DominatorTree> maybeTree;
- {
- auto ccjscx = CycleCollectedJSContext::Get();
- MOZ_ASSERT(ccjscx);
- auto cx = ccjscx->Context();
- MOZ_ASSERT(cx);
- JS::AutoCheckCannotGC nogc(cx);
- maybeTree = JS::ubi::DominatorTree::Create(cx, nogc, getRoot());
- }
-
- if (NS_WARN_IF(maybeTree.isNothing())) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- return MakeAndAddRef<DominatorTree>(Move(*maybeTree), this, mParent);
-}
-
-void
-HeapSnapshot::ComputeShortestPaths(JSContext*cx, uint64_t start,
- const Sequence<uint64_t>& targets,
- uint64_t maxNumPaths,
- JS::MutableHandleObject results,
- ErrorResult& rv)
-{
- // First ensure that our inputs are valid.
-
- if (NS_WARN_IF(maxNumPaths == 0)) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
- Maybe<JS::ubi::Node> startNode = getNodeById(start);
- if (NS_WARN_IF(startNode.isNothing())) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
- if (NS_WARN_IF(targets.Length() == 0)) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
- // Aggregate the targets into a set and make sure that they exist in the heap
- // snapshot.
-
- JS::ubi::NodeSet targetsSet;
- if (NS_WARN_IF(!targetsSet.init())) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- for (const auto& target : targets) {
- Maybe<JS::ubi::Node> targetNode = getNodeById(target);
- if (NS_WARN_IF(targetNode.isNothing())) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
- if (NS_WARN_IF(!targetsSet.put(*targetNode))) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
- }
-
- // Walk the heap graph and find the shortest paths.
-
- Maybe<ShortestPaths> maybeShortestPaths;
- {
- JS::AutoCheckCannotGC nogc(cx);
- maybeShortestPaths = ShortestPaths::Create(cx, nogc, maxNumPaths, *startNode,
- Move(targetsSet));
- }
-
- if (NS_WARN_IF(maybeShortestPaths.isNothing())) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- auto& shortestPaths = *maybeShortestPaths;
-
- // Convert the results into a Map object mapping target node IDs to arrays of
- // paths found.
-
- RootedObject resultsMap(cx, JS::NewMapObject(cx));
- if (NS_WARN_IF(!resultsMap)) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- for (auto range = shortestPaths.eachTarget(); !range.empty(); range.popFront()) {
- JS::RootedValue key(cx, JS::NumberValue(range.front().identifier()));
- JS::AutoValueVector paths(cx);
-
- bool ok = shortestPaths.forEachPath(range.front(), [&](JS::ubi::Path& path) {
- JS::AutoValueVector pathValues(cx);
-
- for (JS::ubi::BackEdge* edge : path) {
- JS::RootedObject pathPart(cx, JS_NewPlainObject(cx));
- if (!pathPart) {
- return false;
- }
-
- JS::RootedValue predecessor(cx, NumberValue(edge->predecessor().identifier()));
- if (!JS_DefineProperty(cx, pathPart, "predecessor", predecessor, JSPROP_ENUMERATE)) {
- return false;
- }
-
- RootedValue edgeNameVal(cx, NullValue());
- if (edge->name()) {
- RootedString edgeName(cx, JS_AtomizeUCString(cx, edge->name().get()));
- if (!edgeName) {
- return false;
- }
- edgeNameVal = StringValue(edgeName);
- }
-
- if (!JS_DefineProperty(cx, pathPart, "edge", edgeNameVal, JSPROP_ENUMERATE)) {
- return false;
- }
-
- if (!pathValues.append(ObjectValue(*pathPart))) {
- return false;
- }
- }
-
- RootedObject pathObj(cx, JS_NewArrayObject(cx, pathValues));
- return pathObj && paths.append(ObjectValue(*pathObj));
- });
-
- if (NS_WARN_IF(!ok)) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- JS::RootedObject pathsArray(cx, JS_NewArrayObject(cx, paths));
- if (NS_WARN_IF(!pathsArray)) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- JS::RootedValue pathsVal(cx, ObjectValue(*pathsArray));
- if (NS_WARN_IF(!JS::MapSet(cx, resultsMap, key, pathsVal))) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
- }
-
- results.set(resultsMap);
-}
-
-/*** Saving Heap Snapshots ************************************************************************/
-
-// If we are only taking a snapshot of the heap affected by the given set of
-// globals, find the set of compartments the globals are allocated
-// within. Returns false on OOM failure.
-static bool
-PopulateCompartmentsWithGlobals(CompartmentSet& compartments, AutoObjectVector& globals)
-{
- if (!compartments.init())
- return false;
-
- unsigned length = globals.length();
- for (unsigned i = 0; i < length; i++) {
- if (!compartments.put(GetObjectCompartment(globals[i])))
- return false;
- }
-
- return true;
-}
-
-// Add the given set of globals as explicit roots in the given roots
-// list. Returns false on OOM failure.
-static bool
-AddGlobalsAsRoots(AutoObjectVector& globals, ubi::RootList& roots)
-{
- unsigned length = globals.length();
- for (unsigned i = 0; i < length; i++) {
- if (!roots.addRoot(ubi::Node(globals[i].get()),
- u"heap snapshot global"))
- {
- return false;
- }
- }
- return true;
-}
-
-// Choose roots and limits for a traversal, given `boundaries`. Set `roots` to
-// the set of nodes within the boundaries that are referred to by nodes
-// outside. If `boundaries` does not include all JS compartments, initialize
-// `compartments` to the set of included compartments; otherwise, leave
-// `compartments` uninitialized. (You can use compartments.initialized() to
-// check.)
-//
-// If `boundaries` is incoherent, or we encounter an error while trying to
-// handle it, or we run out of memory, set `rv` appropriately and return
-// `false`.
-static bool
-EstablishBoundaries(JSContext* cx,
- ErrorResult& rv,
- const HeapSnapshotBoundaries& boundaries,
- ubi::RootList& roots,
- CompartmentSet& compartments)
-{
- MOZ_ASSERT(!roots.initialized());
- MOZ_ASSERT(!compartments.initialized());
-
- bool foundBoundaryProperty = false;
-
- if (boundaries.mRuntime.WasPassed()) {
- foundBoundaryProperty = true;
-
- if (!boundaries.mRuntime.Value()) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return false;
- }
-
- if (!roots.init()) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return false;
- }
- }
-
- if (boundaries.mDebugger.WasPassed()) {
- if (foundBoundaryProperty) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return false;
- }
- foundBoundaryProperty = true;
-
- JSObject* dbgObj = boundaries.mDebugger.Value();
- if (!dbgObj || !dbg::IsDebugger(*dbgObj)) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return false;
- }
-
- AutoObjectVector globals(cx);
- if (!dbg::GetDebuggeeGlobals(cx, *dbgObj, globals) ||
- !PopulateCompartmentsWithGlobals(compartments, globals) ||
- !roots.init(compartments) ||
- !AddGlobalsAsRoots(globals, roots))
- {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return false;
- }
- }
-
- if (boundaries.mGlobals.WasPassed()) {
- if (foundBoundaryProperty) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return false;
- }
- foundBoundaryProperty = true;
-
- uint32_t length = boundaries.mGlobals.Value().Length();
- if (length == 0) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return false;
- }
-
- AutoObjectVector globals(cx);
- for (uint32_t i = 0; i < length; i++) {
- JSObject* global = boundaries.mGlobals.Value().ElementAt(i);
- if (!JS_IsGlobalObject(global)) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return false;
- }
- if (!globals.append(global)) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return false;
- }
- }
-
- if (!PopulateCompartmentsWithGlobals(compartments, globals) ||
- !roots.init(compartments) ||
- !AddGlobalsAsRoots(globals, roots))
- {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return false;
- }
- }
-
- if (!foundBoundaryProperty) {
- rv.Throw(NS_ERROR_INVALID_ARG);
- return false;
- }
-
- MOZ_ASSERT(roots.initialized());
- MOZ_ASSERT_IF(boundaries.mDebugger.WasPassed(), compartments.initialized());
- MOZ_ASSERT_IF(boundaries.mGlobals.WasPassed(), compartments.initialized());
- return true;
-}
-
-
-// A variant covering all the various two-byte strings that we can get from the
-// ubi::Node API.
-class TwoByteString : public Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName>
-{
- using Base = Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName>;
-
- struct AsTwoByteStringMatcher
- {
- TwoByteString match(JSAtom* atom) {
- return TwoByteString(atom);
- }
-
- TwoByteString match(const char16_t* chars) {
- return TwoByteString(chars);
- }
- };
-
- struct IsNonNullMatcher
- {
- template<typename T>
- bool match(const T& t) { return t != nullptr; }
- };
-
- struct LengthMatcher
- {
- size_t match(JSAtom* atom) {
- MOZ_ASSERT(atom);
- JS::ubi::AtomOrTwoByteChars s(atom);
- return s.length();
- }
-
- size_t match(const char16_t* chars) {
- MOZ_ASSERT(chars);
- return NS_strlen(chars);
- }
-
- size_t match(const JS::ubi::EdgeName& ptr) {
- MOZ_ASSERT(ptr);
- return NS_strlen(ptr.get());
- }
- };
-
- struct CopyToBufferMatcher
- {
- RangedPtr<char16_t> destination;
- size_t maxLength;
-
- CopyToBufferMatcher(RangedPtr<char16_t> destination, size_t maxLength)
- : destination(destination)
- , maxLength(maxLength)
- { }
-
- size_t match(JS::ubi::EdgeName& ptr) {
- return ptr ? match(ptr.get()) : 0;
- }
-
- size_t match(JSAtom* atom) {
- MOZ_ASSERT(atom);
- JS::ubi::AtomOrTwoByteChars s(atom);
- return s.copyToBuffer(destination, maxLength);
- }
-
- size_t match(const char16_t* chars) {
- MOZ_ASSERT(chars);
- JS::ubi::AtomOrTwoByteChars s(chars);
- return s.copyToBuffer(destination, maxLength);
- }
- };
-
-public:
- template<typename T>
- MOZ_IMPLICIT TwoByteString(T&& rhs) : Base(Forward<T>(rhs)) { }
-
- template<typename T>
- TwoByteString& operator=(T&& rhs) {
- MOZ_ASSERT(this != &rhs, "self-move disallowed");
- this->~TwoByteString();
- new (this) TwoByteString(Forward<T>(rhs));
- return *this;
- }
-
- TwoByteString(const TwoByteString&) = delete;
- TwoByteString& operator=(const TwoByteString&) = delete;
-
- // Rewrap the inner value of a JS::ubi::AtomOrTwoByteChars as a TwoByteString.
- static TwoByteString from(JS::ubi::AtomOrTwoByteChars&& s) {
- AsTwoByteStringMatcher m;
- return s.match(m);
- }
-
- // Returns true if the given TwoByteString is non-null, false otherwise.
- bool isNonNull() const {
- IsNonNullMatcher m;
- return match(m);
- }
-
- // Return the length of the string, 0 if it is null.
- size_t length() const {
- LengthMatcher m;
- return match(m);
- }
-
- // Copy the contents of a TwoByteString into the provided buffer. The buffer
- // is NOT null terminated. The number of characters written is returned.
- size_t copyToBuffer(RangedPtr<char16_t> destination, size_t maxLength) {
- CopyToBufferMatcher m(destination, maxLength);
- return match(m);
- }
-
- struct HashPolicy;
-};
-
-// A hashing policy for TwoByteString.
-//
-// Atoms are pointer hashed and use pointer equality, which means that we
-// tolerate some duplication across atoms and the other two types of two-byte
-// strings. In practice, we expect the amount of this duplication to be very low
-// because each type is generally a different semantic thing in addition to
-// having a slightly different representation. For example, the set of edge
-// names and the set stack frames' source names naturally tend not to overlap
-// very much if at all.
-struct TwoByteString::HashPolicy {
- using Lookup = TwoByteString;
-
- struct HashingMatcher {
- js::HashNumber match(const JSAtom* atom) {
- return js::DefaultHasher<const JSAtom*>::hash(atom);
- }
-
- js::HashNumber match(const char16_t* chars) {
- MOZ_ASSERT(chars);
- auto length = NS_strlen(chars);
- return HashString(chars, length);
- }
-
- js::HashNumber match(const JS::ubi::EdgeName& ptr) {
- MOZ_ASSERT(ptr);
- return match(ptr.get());
- }
- };
-
- static js::HashNumber hash(const Lookup& l) {
- HashingMatcher hasher;
- return l.match(hasher);
- }
-
- struct EqualityMatcher {
- const TwoByteString& rhs;
- explicit EqualityMatcher(const TwoByteString& rhs) : rhs(rhs) { }
-
- bool match(const JSAtom* atom) {
- return rhs.is<JSAtom*>() && rhs.as<JSAtom*>() == atom;
- }
-
- bool match(const char16_t* chars) {
- MOZ_ASSERT(chars);
-
- const char16_t* rhsChars = nullptr;
- if (rhs.is<const char16_t*>())
- rhsChars = rhs.as<const char16_t*>();
- else if (rhs.is<JS::ubi::EdgeName>())
- rhsChars = rhs.as<JS::ubi::EdgeName>().get();
- else
- return false;
- MOZ_ASSERT(rhsChars);
-
- auto length = NS_strlen(chars);
- if (NS_strlen(rhsChars) != length)
- return false;
-
- return memcmp(chars, rhsChars, length * sizeof(char16_t)) == 0;
- }
-
- bool match(const JS::ubi::EdgeName& ptr) {
- MOZ_ASSERT(ptr);
- return match(ptr.get());
- }
- };
-
- static bool match(const TwoByteString& k, const Lookup& l) {
- EqualityMatcher eq(l);
- return k.match(eq);
- }
-
- static void rekey(TwoByteString& k, TwoByteString&& newKey) {
- k = Move(newKey);
- }
-};
-
-// Returns whether `edge` should be included in a heap snapshot of
-// `compartments`. The optional `policy` out-param is set to INCLUDE_EDGES
-// if we want to include the referent's edges, or EXCLUDE_EDGES if we don't
-// want to include them.
-static bool
-ShouldIncludeEdge(JS::CompartmentSet* compartments,
- const ubi::Node& origin, const ubi::Edge& edge,
- CoreDumpWriter::EdgePolicy* policy = nullptr)
-{
- if (policy) {
- *policy = CoreDumpWriter::INCLUDE_EDGES;
- }
-
- if (!compartments) {
- // We aren't targeting a particular set of compartments, so serialize all the
- // things!
- return true;
- }
-
- // We are targeting a particular set of compartments. If this node is in our target
- // set, serialize it and all of its edges. If this node is _not_ in our
- // target set, we also serialize under the assumption that it is a shared
- // resource being used by something in our target compartments since we reached it
- // by traversing the heap graph. However, we do not serialize its outgoing
- // edges and we abandon further traversal from this node.
- //
- // If the node does not belong to any compartment, we also serialize its outgoing
- // edges. This case is relevant for Shapes: they don't belong to a specific
- // compartment and contain edges to parent/kids Shapes we want to include. Note
- // that these Shapes may contain pointers into our target compartment (the
- // Shape's getter/setter JSObjects). However, we do not serialize nodes in other
- // compartments that are reachable from these non-compartment nodes.
-
- JSCompartment* compartment = edge.referent.compartment();
-
- if (!compartment || compartments->has(compartment)) {
- return true;
- }
-
- if (policy) {
- *policy = CoreDumpWriter::EXCLUDE_EDGES;
- }
-
- return !!origin.compartment();
-}
-
-// A `CoreDumpWriter` that serializes nodes to protobufs and writes them to the
-// given `ZeroCopyOutputStream`.
-class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter
-{
- using FrameSet = js::HashSet<uint64_t>;
- using TwoByteStringMap = js::HashMap<TwoByteString, uint64_t, TwoByteString::HashPolicy>;
- using OneByteStringMap = js::HashMap<const char*, uint64_t>;
-
- JSContext* cx;
- bool wantNames;
- // The set of |JS::ubi::StackFrame::identifier()|s that have already been
- // serialized and written to the core dump.
- FrameSet framesAlreadySerialized;
- // The set of two-byte strings that have already been serialized and written
- // to the core dump.
- TwoByteStringMap twoByteStringsAlreadySerialized;
- // The set of one-byte strings that have already been serialized and written
- // to the core dump.
- OneByteStringMap oneByteStringsAlreadySerialized;
-
- ::google::protobuf::io::ZeroCopyOutputStream& stream;
-
- JS::CompartmentSet* compartments;
-
- bool writeMessage(const ::google::protobuf::MessageLite& message) {
- // We have to create a new CodedOutputStream when writing each message so
- // that the 64MB size limit used by Coded{Output,Input}Stream to prevent
- // integer overflow is enforced per message rather than on the whole stream.
- ::google::protobuf::io::CodedOutputStream codedStream(&stream);
- codedStream.WriteVarint32(message.ByteSize());
- message.SerializeWithCachedSizes(&codedStream);
- return !codedStream.HadError();
- }
-
- // Attach the full two-byte string or a reference to a two-byte string that
- // has already been serialized to a protobuf message.
- template <typename SetStringFunction,
- typename SetRefFunction>
- bool attachTwoByteString(TwoByteString& string, SetStringFunction setString,
- SetRefFunction setRef) {
- auto ptr = twoByteStringsAlreadySerialized.lookupForAdd(string);
- if (ptr) {
- setRef(ptr->value());
- return true;
- }
-
- auto length = string.length();
- auto stringData = MakeUnique<std::string>(length * sizeof(char16_t), '\0');
- if (!stringData)
- return false;
-
- auto buf = const_cast<char16_t*>(reinterpret_cast<const char16_t*>(stringData->data()));
- string.copyToBuffer(RangedPtr<char16_t>(buf, length), length);
-
- uint64_t ref = twoByteStringsAlreadySerialized.count();
- if (!twoByteStringsAlreadySerialized.add(ptr, Move(string), ref))
- return false;
-
- setString(stringData.release());
- return true;
- }
-
- // Attach the full one-byte string or a reference to a one-byte string that
- // has already been serialized to a protobuf message.
- template <typename SetStringFunction,
- typename SetRefFunction>
- bool attachOneByteString(const char* string, SetStringFunction setString,
- SetRefFunction setRef) {
- auto ptr = oneByteStringsAlreadySerialized.lookupForAdd(string);
- if (ptr) {
- setRef(ptr->value());
- return true;
- }
-
- auto length = strlen(string);
- auto stringData = MakeUnique<std::string>(string, length);
- if (!stringData)
- return false;
-
- uint64_t ref = oneByteStringsAlreadySerialized.count();
- if (!oneByteStringsAlreadySerialized.add(ptr, string, ref))
- return false;
-
- setString(stringData.release());
- return true;
- }
-
- protobuf::StackFrame* getProtobufStackFrame(JS::ubi::StackFrame& frame,
- size_t depth = 1) {
- // NB: de-duplicated string properties must be written in the same order
- // here as they are read in `HeapSnapshot::saveStackFrame` or else indices
- // in references to already serialized strings will be off.
-
- MOZ_ASSERT(frame,
- "null frames should be represented as the lack of a serialized "
- "stack frame");
-
- auto id = frame.identifier();
- auto protobufStackFrame = MakeUnique<protobuf::StackFrame>();
- if (!protobufStackFrame)
- return nullptr;
-
- if (framesAlreadySerialized.has(id)) {
- protobufStackFrame->set_ref(id);
- return protobufStackFrame.release();
- }
-
- auto data = MakeUnique<protobuf::StackFrame_Data>();
- if (!data)
- return nullptr;
-
- data->set_id(id);
- data->set_line(frame.line());
- data->set_column(frame.column());
- data->set_issystem(frame.isSystem());
- data->set_isselfhosted(frame.isSelfHosted(cx));
-
- auto dupeSource = TwoByteString::from(frame.source());
- if (!attachTwoByteString(dupeSource,
- [&] (std::string* source) { data->set_allocated_source(source); },
- [&] (uint64_t ref) { data->set_sourceref(ref); }))
- {
- return nullptr;
- }
-
- auto dupeName = TwoByteString::from(frame.functionDisplayName());
- if (dupeName.isNonNull()) {
- if (!attachTwoByteString(dupeName,
- [&] (std::string* name) { data->set_allocated_functiondisplayname(name); },
- [&] (uint64_t ref) { data->set_functiondisplaynameref(ref); }))
- {
- return nullptr;
- }
- }
-
- auto parent = frame.parent();
- if (parent && depth < HeapSnapshot::MAX_STACK_DEPTH) {
- auto protobufParent = getProtobufStackFrame(parent, depth + 1);
- if (!protobufParent)
- return nullptr;
- data->set_allocated_parent(protobufParent);
- }
-
- protobufStackFrame->set_allocated_data(data.release());
-
- if (!framesAlreadySerialized.put(id))
- return nullptr;
-
- return protobufStackFrame.release();
- }
-
-public:
- StreamWriter(JSContext* cx,
- ::google::protobuf::io::ZeroCopyOutputStream& stream,
- bool wantNames,
- JS::CompartmentSet* compartments)
- : cx(cx)
- , wantNames(wantNames)
- , framesAlreadySerialized(cx)
- , twoByteStringsAlreadySerialized(cx)
- , oneByteStringsAlreadySerialized(cx)
- , stream(stream)
- , compartments(compartments)
- { }
-
- bool init() {
- return framesAlreadySerialized.init() &&
- twoByteStringsAlreadySerialized.init() &&
- oneByteStringsAlreadySerialized.init();
- }
-
- ~StreamWriter() override { }
-
- virtual bool writeMetadata(uint64_t timestamp) final {
- protobuf::Metadata metadata;
- metadata.set_timestamp(timestamp);
- return writeMessage(metadata);
- }
-
- virtual bool writeNode(const JS::ubi::Node& ubiNode,
- EdgePolicy includeEdges) override final {
- // NB: de-duplicated string properties must be written in the same order
- // here as they are read in `HeapSnapshot::saveNode` or else indices in
- // references to already serialized strings will be off.
-
- protobuf::Node protobufNode;
- protobufNode.set_id(ubiNode.identifier());
-
- protobufNode.set_coarsetype(JS::ubi::CoarseTypeToUint32(ubiNode.coarseType()));
-
- auto typeName = TwoByteString(ubiNode.typeName());
- if (NS_WARN_IF(!attachTwoByteString(typeName,
- [&] (std::string* name) { protobufNode.set_allocated_typename_(name); },
- [&] (uint64_t ref) { protobufNode.set_typenameref(ref); })))
- {
- return false;
- }
-
- mozilla::MallocSizeOf mallocSizeOf = dbg::GetDebuggerMallocSizeOf(cx);
- MOZ_ASSERT(mallocSizeOf);
- protobufNode.set_size(ubiNode.size(mallocSizeOf));
-
- if (includeEdges) {
- auto edges = ubiNode.edges(cx, wantNames);
- if (NS_WARN_IF(!edges))
- return false;
-
- for ( ; !edges->empty(); edges->popFront()) {
- ubi::Edge& ubiEdge = edges->front();
- if (!ShouldIncludeEdge(compartments, ubiNode, ubiEdge)) {
- continue;
- }
-
- protobuf::Edge* protobufEdge = protobufNode.add_edges();
- if (NS_WARN_IF(!protobufEdge)) {
- return false;
- }
-
- protobufEdge->set_referent(ubiEdge.referent.identifier());
-
- if (wantNames && ubiEdge.name) {
- TwoByteString edgeName(Move(ubiEdge.name));
- if (NS_WARN_IF(!attachTwoByteString(edgeName,
- [&] (std::string* name) { protobufEdge->set_allocated_name(name); },
- [&] (uint64_t ref) { protobufEdge->set_nameref(ref); })))
- {
- return false;
- }
- }
- }
- }
-
- if (ubiNode.hasAllocationStack()) {
- auto ubiStackFrame = ubiNode.allocationStack();
- auto protoStackFrame = getProtobufStackFrame(ubiStackFrame);
- if (NS_WARN_IF(!protoStackFrame))
- return false;
- protobufNode.set_allocated_allocationstack(protoStackFrame);
- }
-
- if (auto className = ubiNode.jsObjectClassName()) {
- if (NS_WARN_IF(!attachOneByteString(className,
- [&] (std::string* name) { protobufNode.set_allocated_jsobjectclassname(name); },
- [&] (uint64_t ref) { protobufNode.set_jsobjectclassnameref(ref); })))
- {
- return false;
- }
- }
-
- if (auto scriptFilename = ubiNode.scriptFilename()) {
- if (NS_WARN_IF(!attachOneByteString(scriptFilename,
- [&] (std::string* name) { protobufNode.set_allocated_scriptfilename(name); },
- [&] (uint64_t ref) { protobufNode.set_scriptfilenameref(ref); })))
- {
- return false;
- }
- }
-
- return writeMessage(protobufNode);
- }
-};
-
-// A JS::ubi::BreadthFirst handler that serializes a snapshot of the heap into a
-// core dump.
-class MOZ_STACK_CLASS HeapSnapshotHandler
-{
- CoreDumpWriter& writer;
- JS::CompartmentSet* compartments;
-
-public:
- HeapSnapshotHandler(CoreDumpWriter& writer,
- JS::CompartmentSet* compartments)
- : writer(writer),
- compartments(compartments)
- { }
-
- // JS::ubi::BreadthFirst handler interface.
-
- class NodeData { };
- typedef JS::ubi::BreadthFirst<HeapSnapshotHandler> Traversal;
- bool operator() (Traversal& traversal,
- JS::ubi::Node origin,
- const JS::ubi::Edge& edge,
- NodeData*,
- bool first)
- {
- // We're only interested in the first time we reach edge.referent, not in
- // every edge arriving at that node. "But, don't we want to serialize every
- // edge in the heap graph?" you ask. Don't worry! This edge is still
- // serialized into the core dump. Serializing a node also serializes each of
- // its edges, and if we are traversing a given edge, we must have already
- // visited and serialized the origin node and its edges.
- if (!first)
- return true;
-
- CoreDumpWriter::EdgePolicy policy;
- if (!ShouldIncludeEdge(compartments, origin, edge, &policy))
- return true;
-
- if (policy == CoreDumpWriter::EXCLUDE_EDGES)
- traversal.abandonReferent();
-
- return writer.writeNode(edge.referent, policy);
- }
-};
-
-
-bool
-WriteHeapGraph(JSContext* cx,
- const JS::ubi::Node& node,
- CoreDumpWriter& writer,
- bool wantNames,
- JS::CompartmentSet* compartments,
- JS::AutoCheckCannotGC& noGC)
-{
- // Serialize the starting node to the core dump.
-
- if (NS_WARN_IF(!writer.writeNode(node, CoreDumpWriter::INCLUDE_EDGES))) {
- return false;
- }
-
- // Walk the heap graph starting from the given node and serialize it into the
- // core dump.
-
- HeapSnapshotHandler handler(writer, compartments);
- HeapSnapshotHandler::Traversal traversal(cx, handler, noGC);
- if (!traversal.init())
- return false;
- traversal.wantNames = wantNames;
-
- bool ok = traversal.addStartVisited(node) &&
- traversal.traverse();
-
- return ok;
-}
-
-static unsigned long
-msSinceProcessCreation(const TimeStamp& now)
-{
- bool ignored;
- auto duration = now - TimeStamp::ProcessCreation(ignored);
- return (unsigned long) duration.ToMilliseconds();
-}
-
-/* static */ already_AddRefed<nsIFile>
-HeapSnapshot::CreateUniqueCoreDumpFile(ErrorResult& rv,
- const TimeStamp& now,
- nsAString& outFilePath)
-{
- nsCOMPtr<nsIFile> file;
- rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(file));
- if (NS_WARN_IF(rv.Failed()))
- return nullptr;
-
- auto ms = msSinceProcessCreation(now);
- rv = file->AppendNative(nsPrintfCString("%lu.fxsnapshot", ms));
- if (NS_WARN_IF(rv.Failed()))
- return nullptr;
-
- rv = file->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0666);
- if (NS_WARN_IF(rv.Failed()))
- return nullptr;
-
- rv = file->GetPath(outFilePath);
- if (NS_WARN_IF(rv.Failed()))
- return nullptr;
-
- return file.forget();
-}
-
-// Deletion policy for cleaning up PHeapSnapshotTempFileHelperChild pointers.
-class DeleteHeapSnapshotTempFileHelperChild
-{
-public:
- constexpr DeleteHeapSnapshotTempFileHelperChild() { }
-
- void operator()(PHeapSnapshotTempFileHelperChild* ptr) const {
- Unused << NS_WARN_IF(!HeapSnapshotTempFileHelperChild::Send__delete__(ptr));
- }
-};
-
-// A UniquePtr alias to automatically manage PHeapSnapshotTempFileHelperChild
-// pointers.
-using UniqueHeapSnapshotTempFileHelperChild = UniquePtr<PHeapSnapshotTempFileHelperChild,
- DeleteHeapSnapshotTempFileHelperChild>;
-
-// Get an nsIOutputStream that we can write the heap snapshot to. In non-e10s
-// and in the e10s parent process, open a file directly and create an output
-// stream for it. In e10s child processes, we are sandboxed without access to
-// the filesystem. Use IPDL to request a file descriptor from the parent
-// process.
-static already_AddRefed<nsIOutputStream>
-getCoreDumpOutputStream(ErrorResult& rv, TimeStamp& start, nsAString& outFilePath)
-{
- if (XRE_IsParentProcess()) {
- // Create the file and open the output stream directly.
-
- nsCOMPtr<nsIFile> file = HeapSnapshot::CreateUniqueCoreDumpFile(rv,
- start,
- outFilePath);
- if (NS_WARN_IF(rv.Failed()))
- return nullptr;
-
- nsCOMPtr<nsIOutputStream> outputStream;
- rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), file,
- PR_WRONLY, -1, 0);
- if (NS_WARN_IF(rv.Failed()))
- return nullptr;
-
- return outputStream.forget();
- } else {
- // Request a file descriptor from the parent process over IPDL.
-
- auto cc = ContentChild::GetSingleton();
- if (!cc) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
-
- UniqueHeapSnapshotTempFileHelperChild helper(
- cc->SendPHeapSnapshotTempFileHelperConstructor());
- if (NS_WARN_IF(!helper)) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
-
- OpenHeapSnapshotTempFileResponse response;
- if (!helper->SendOpenHeapSnapshotTempFile(&response)) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
- if (response.type() == OpenHeapSnapshotTempFileResponse::Tnsresult) {
- rv.Throw(response.get_nsresult());
- return nullptr;
- }
-
- auto opened = response.get_OpenedFile();
- outFilePath = opened.path();
- nsCOMPtr<nsIOutputStream> outputStream =
- FileDescriptorOutputStream::Create(opened.descriptor());
- if (NS_WARN_IF(!outputStream)) {
- rv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
-
- return outputStream.forget();
- }
-}
-
-} // namespace devtools
-
-namespace dom {
-
-using namespace JS;
-using namespace devtools;
-
-/* static */ void
-ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
- const HeapSnapshotBoundaries& boundaries,
- nsAString& outFilePath,
- ErrorResult& rv)
-{
- auto start = TimeStamp::Now();
-
- bool wantNames = true;
- CompartmentSet compartments;
-
- nsCOMPtr<nsIOutputStream> outputStream = getCoreDumpOutputStream(rv, start, outFilePath);
- if (NS_WARN_IF(rv.Failed()))
- return;
-
- ZeroCopyNSIOutputStream zeroCopyStream(outputStream);
- ::google::protobuf::io::GzipOutputStream gzipStream(&zeroCopyStream);
-
- JSContext* cx = global.Context();
-
- {
- Maybe<AutoCheckCannotGC> maybeNoGC;
- ubi::RootList rootList(cx, maybeNoGC, wantNames);
- if (!EstablishBoundaries(cx, rv, boundaries, rootList, compartments))
- return;
-
- StreamWriter writer(cx, gzipStream, wantNames,
- compartments.initialized() ? &compartments : nullptr);
- if (NS_WARN_IF(!writer.init())) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
-
- MOZ_ASSERT(maybeNoGC.isSome());
- ubi::Node roots(&rootList);
-
- // Serialize the initial heap snapshot metadata to the core dump.
- if (!writer.writeMetadata(PR_Now()) ||
- // Serialize the heap graph to the core dump, starting from our list of
- // roots.
- !WriteHeapGraph(cx,
- roots,
- writer,
- wantNames,
- compartments.initialized() ? &compartments : nullptr,
- maybeNoGC.ref()))
- {
- rv.Throw(zeroCopyStream.failed()
- ? zeroCopyStream.result()
- : NS_ERROR_UNEXPECTED);
- return;
- }
- }
-}
-
-/* static */ already_AddRefed<HeapSnapshot>
-ThreadSafeChromeUtils::ReadHeapSnapshot(GlobalObject& global,
- const nsAString& filePath,
- ErrorResult& rv)
-{
- UniquePtr<char[]> path(ToNewCString(filePath));
- if (!path) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- AutoMemMap mm;
- rv = mm.init(path.get());
- if (rv.Failed())
- return nullptr;
-
- RefPtr<HeapSnapshot> snapshot = HeapSnapshot::Create(
- global.Context(), global, reinterpret_cast<const uint8_t*>(mm.address()),
- mm.size(), rv);
-
- return snapshot.forget();
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.h b/devtools/shared/heapsnapshot/HeapSnapshot.h
deleted file mode 100644
index 12dfa4c2b..000000000
--- a/devtools/shared/heapsnapshot/HeapSnapshot.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_HeapSnapshot__
-#define mozilla_devtools_HeapSnapshot__
-
-#include "js/HashTable.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/devtools/DeserializedNode.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/Nullable.h"
-#include "mozilla/HashFunctions.h"
-#include "mozilla/Maybe.h"
-#include "mozilla/RefCounted.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/UniquePtr.h"
-
-#include "CoreDump.pb.h"
-#include "nsCOMPtr.h"
-#include "nsCRTGlue.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsISupports.h"
-#include "nsWrapperCache.h"
-#include "nsXPCOM.h"
-
-namespace mozilla {
-namespace devtools {
-
-class DominatorTree;
-
-struct NSFreePolicy {
- void operator()(void* ptr) {
- NS_Free(ptr);
- }
-};
-
-using UniqueTwoByteString = UniquePtr<char16_t[], NSFreePolicy>;
-using UniqueOneByteString = UniquePtr<char[], NSFreePolicy>;
-
-class HeapSnapshot final : public nsISupports
- , public nsWrapperCache
-{
- friend struct DeserializedNode;
- friend struct DeserializedEdge;
- friend struct DeserializedStackFrame;
- friend class JS::ubi::Concrete<JS::ubi::DeserializedNode>;
-
- explicit HeapSnapshot(JSContext* cx, nsISupports* aParent)
- : timestamp(Nothing())
- , rootId(0)
- , nodes(cx)
- , frames(cx)
- , mParent(aParent)
- {
- MOZ_ASSERT(aParent);
- };
-
- // Initialize this HeapSnapshot from the given buffer that contains a
- // serialized core dump. Do NOT take ownership of the buffer, only borrow it
- // for the duration of the call. Return false on failure.
- bool init(JSContext* cx, const uint8_t* buffer, uint32_t size);
-
- using NodeIdSet = js::HashSet<NodeId>;
-
- // Save the given `protobuf::Node` message in this `HeapSnapshot` as a
- // `DeserializedNode`.
- bool saveNode(const protobuf::Node& node, NodeIdSet& edgeReferents);
-
- // Save the given `protobuf::StackFrame` message in this `HeapSnapshot` as a
- // `DeserializedStackFrame`. The saved stack frame's id is returned via the
- // out parameter.
- bool saveStackFrame(const protobuf::StackFrame& frame,
- StackFrameId& outFrameId);
-
-public:
- // The maximum number of stack frames that we will serialize into a core
- // dump. This helps prevent over-recursion in the protobuf library when
- // deserializing stacks.
- static const size_t MAX_STACK_DEPTH = 60;
-
-private:
- // If present, a timestamp in the same units that `PR_Now` gives.
- Maybe<uint64_t> timestamp;
-
- // The id of the root node for this deserialized heap graph.
- NodeId rootId;
-
- // The set of nodes in this deserialized heap graph, keyed by id.
- using NodeSet = js::HashSet<DeserializedNode, DeserializedNode::HashPolicy>;
- NodeSet nodes;
-
- // The set of stack frames in this deserialized heap graph, keyed by id.
- using FrameSet = js::HashSet<DeserializedStackFrame,
- DeserializedStackFrame::HashPolicy>;
- FrameSet frames;
-
- Vector<UniqueTwoByteString> internedTwoByteStrings;
- Vector<UniqueOneByteString> internedOneByteStrings;
-
- using StringOrRef = Variant<const std::string*, uint64_t>;
-
- template<typename CharT,
- typename InternedStringSet>
- const CharT* getOrInternString(InternedStringSet& internedStrings,
- Maybe<StringOrRef>& maybeStrOrRef);
-
-protected:
- nsCOMPtr<nsISupports> mParent;
-
- virtual ~HeapSnapshot() { }
-
-public:
- // Create a `HeapSnapshot` from the given buffer that contains a serialized
- // core dump. Do NOT take ownership of the buffer, only borrow it for the
- // duration of the call.
- static already_AddRefed<HeapSnapshot> Create(JSContext* cx,
- dom::GlobalObject& global,
- const uint8_t* buffer,
- uint32_t size,
- ErrorResult& rv);
-
- // Creates the `$TEMP_DIR/XXXXXX-XXX.fxsnapshot` core dump file that heap
- // snapshots are serialized into.
- static already_AddRefed<nsIFile> CreateUniqueCoreDumpFile(ErrorResult& rv,
- const TimeStamp& now,
- nsAString& outFilePath);
-
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HeapSnapshot)
- MOZ_DECLARE_REFCOUNTED_TYPENAME(HeapSnapshot)
-
- nsISupports* GetParentObject() const { return mParent; }
-
- virtual JSObject* WrapObject(JSContext* aCx,
- JS::Handle<JSObject*> aGivenProto) override;
-
- const char16_t* borrowUniqueString(const char16_t* duplicateString,
- size_t length);
-
- // Get the root node of this heap snapshot's graph.
- JS::ubi::Node getRoot() {
- MOZ_ASSERT(nodes.initialized());
- auto p = nodes.lookup(rootId);
- MOZ_ASSERT(p);
- const DeserializedNode& node = *p;
- return JS::ubi::Node(const_cast<DeserializedNode*>(&node));
- }
-
- Maybe<JS::ubi::Node> getNodeById(JS::ubi::Node::Id nodeId) {
- auto p = nodes.lookup(nodeId);
- if (!p)
- return Nothing();
- return Some(JS::ubi::Node(const_cast<DeserializedNode*>(&*p)));
- }
-
- void TakeCensus(JSContext* cx, JS::HandleObject options,
- JS::MutableHandleValue rval, ErrorResult& rv);
-
- void DescribeNode(JSContext* cx, JS::HandleObject breakdown, uint64_t nodeId,
- JS::MutableHandleValue rval, ErrorResult& rv);
-
- already_AddRefed<DominatorTree> ComputeDominatorTree(ErrorResult& rv);
-
- void ComputeShortestPaths(JSContext*cx, uint64_t start,
- const dom::Sequence<uint64_t>& targets,
- uint64_t maxNumPaths,
- JS::MutableHandleObject results,
- ErrorResult& rv);
-
- dom::Nullable<uint64_t> GetCreationTime() {
- static const uint64_t maxTime = uint64_t(1) << 53;
- if (timestamp.isSome() && timestamp.ref() <= maxTime) {
- return dom::Nullable<uint64_t>(timestamp.ref());
- }
-
- return dom::Nullable<uint64_t>();
- }
-};
-
-// A `CoreDumpWriter` is given the data we wish to save in a core dump and
-// serializes it to disk, or memory, or a socket, etc.
-class CoreDumpWriter
-{
-public:
- virtual ~CoreDumpWriter() { };
-
- // Write the given bits of metadata we would like to associate with this core
- // dump.
- virtual bool writeMetadata(uint64_t timestamp) = 0;
-
- enum EdgePolicy : bool {
- INCLUDE_EDGES = true,
- EXCLUDE_EDGES = false
- };
-
- // Write the given `JS::ubi::Node` to the core dump. The given `EdgePolicy`
- // dictates whether its outgoing edges should also be written to the core
- // dump, or excluded.
- virtual bool writeNode(const JS::ubi::Node& node,
- EdgePolicy includeEdges) = 0;
-};
-
-// Serialize the heap graph as seen from `node` with the given `CoreDumpWriter`.
-// If `wantNames` is true, capture edge names. If `zones` is non-null, only
-// capture the sub-graph within the zone set, otherwise capture the whole heap
-// graph. Returns false on failure.
-bool
-WriteHeapGraph(JSContext* cx,
- const JS::ubi::Node& node,
- CoreDumpWriter& writer,
- bool wantNames,
- JS::CompartmentSet* compartments,
- JS::AutoCheckCannotGC& noGC);
-
-// Get the mozilla::MallocSizeOf for the current thread's JSRuntime.
-MallocSizeOf GetCurrentThreadDebuggerMallocSizeOf();
-
-} // namespace devtools
-} // namespace mozilla
-
-#endif // mozilla_devtools_HeapSnapshot__
diff --git a/devtools/shared/heapsnapshot/HeapSnapshotFileUtils.js b/devtools/shared/heapsnapshot/HeapSnapshotFileUtils.js
deleted file mode 100644
index abd44fc30..000000000
--- a/devtools/shared/heapsnapshot/HeapSnapshotFileUtils.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Heap snapshots are always saved in the temp directory, and have a regular
-// naming convention. This module provides helpers for working with heap
-// snapshot files in a safe manner. Because we attempt to avoid unnecessary
-// copies of the heap snapshot files by checking the local filesystem for a heap
-// snapshot file with the given snapshot id, we want to ensure that we are only
-// attempting to open heap snapshot files and not `~/.ssh/id_rsa`, for
-// example. Therefore, the RDP only talks about snapshot ids, or transfering the
-// bulk file data. A file path can be recovered from a snapshot id, which allows
-// one to check for the presence of the heap snapshot file on the local file
-// system, but we don't have to worry about opening arbitrary files.
-//
-// The heap snapshot file path conventions permits the following forms:
-//
-// $TEMP_DIRECTORY/XXXXXXXXXX.fxsnapshot
-// $TEMP_DIRECTORY/XXXXXXXXXX-XXXXX.fxsnapshot
-//
-// Where the strings of "X" are zero or more digits.
-
-"use strict";
-
-const { Ci } = require("chrome");
-loader.lazyRequireGetter(this, "FileUtils",
- "resource://gre/modules/FileUtils.jsm", true);
-loader.lazyRequireGetter(this, "OS", "resource://gre/modules/osfile.jsm", true);
-
-function getHeapSnapshotFileTemplate() {
- return OS.Path.join(OS.Constants.Path.tmpDir, `${Date.now()}.fxsnapshot`);
-}
-
-/**
- * Get a unique temp file path for a new heap snapshot. The file is guaranteed
- * not to exist before this call.
- *
- * @returns String
- */
-exports.getNewUniqueHeapSnapshotTempFilePath = function () {
- let file = new FileUtils.File(getHeapSnapshotFileTemplate());
- // The call to createUnique will append "-N" after the leaf name (but before
- // the extension) until a new file is found and create it. This guarantees we
- // won't accidentally choose the same file twice.
- file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
- return file.path;
-};
-
-function isValidSnapshotFileId(snapshotId) {
- return /^\d+(\-\d+)?$/.test(snapshotId);
-}
-
-/**
- * Get the file path for the given snapshot id.
- *
- * @param {String} snapshotId
- *
- * @returns String | null
- */
-exports.getHeapSnapshotTempFilePath = function (snapshotId) {
- // Don't want anyone sneaking "../../../.." strings into the snapshot id and
- // trying to make us open arbitrary files.
- if (!isValidSnapshotFileId(snapshotId)) {
- return null;
- }
- return OS.Path.join(OS.Constants.Path.tmpDir, snapshotId + ".fxsnapshot");
-};
-
-/**
- * Return true if we have the heap snapshot file for the given snapshot id on
- * the local file system. False is returned otherwise.
- *
- * @returns Promise<Boolean>
- */
-exports.haveHeapSnapshotTempFile = function (snapshotId) {
- const path = exports.getHeapSnapshotTempFilePath(snapshotId);
- if (!path) {
- return Promise.resolve(false);
- }
-
- return OS.File.stat(path).then(() => true,
- () => false);
-};
-
-/**
- * Given a heap snapshot's file path, extricate the snapshot id.
- *
- * @param {String} path
- *
- * @returns String
- */
-exports.getSnapshotIdFromPath = function (path) {
- return path.slice(OS.Constants.Path.tmpDir.length + 1,
- path.length - ".fxsnapshot".length);
-};
diff --git a/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperChild.h b/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperChild.h
deleted file mode 100644
index a1d433a5e..000000000
--- a/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperChild.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_HeapSnapshotTempFileHelperChild_h
-#define mozilla_devtools_HeapSnapshotTempFileHelperChild_h
-
-#include "mozilla/devtools/PHeapSnapshotTempFileHelperChild.h"
-
-namespace mozilla {
-namespace devtools {
-
-class HeapSnapshotTempFileHelperChild : public PHeapSnapshotTempFileHelperChild
-{
- explicit HeapSnapshotTempFileHelperChild() { }
-
-public:
- static inline PHeapSnapshotTempFileHelperChild* Create();
-};
-
-/* static */ inline PHeapSnapshotTempFileHelperChild*
-HeapSnapshotTempFileHelperChild::Create()
-{
- return new HeapSnapshotTempFileHelperChild();
-}
-
-} // namespace devtools
-} // namespace mozilla
-
-#endif // mozilla_devtools_HeapSnapshotTempFileHelperChild_h
diff --git a/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.cpp b/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.cpp
deleted file mode 100644
index 7246a9daa..000000000
--- a/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/devtools/HeapSnapshot.h"
-#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
-#include "mozilla/ErrorResult.h"
-#include "private/pprio.h"
-
-#include "nsIFile.h"
-
-namespace mozilla {
-namespace devtools {
-
-using ipc::FileDescriptor;
-
-static bool
-openFileFailure(ErrorResult& rv,
- OpenHeapSnapshotTempFileResponse* outResponse)
-{
- *outResponse = rv.StealNSResult();
- return true;
-}
-
-bool
-HeapSnapshotTempFileHelperParent::RecvOpenHeapSnapshotTempFile(
- OpenHeapSnapshotTempFileResponse* outResponse)
-{
- auto start = TimeStamp::Now();
- ErrorResult rv;
- nsAutoString filePath;
- nsCOMPtr<nsIFile> file = HeapSnapshot::CreateUniqueCoreDumpFile(rv,
- start,
- filePath);
- if (NS_WARN_IF(rv.Failed()))
- return openFileFailure(rv, outResponse);
-
- PRFileDesc* prfd;
- rv = file->OpenNSPRFileDesc(PR_WRONLY, 0, &prfd);
- if (NS_WARN_IF(rv.Failed()))
- return openFileFailure(rv, outResponse);
-
- FileDescriptor::PlatformHandleType handle =
- FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(prfd));
- FileDescriptor fd(handle);
- *outResponse = OpenedFile(filePath, fd);
- return true;
-}
-
-} // namespace devtools
-} // namespace mozilla
diff --git a/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.h b/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.h
deleted file mode 100644
index 1582279da..000000000
--- a/devtools/shared/heapsnapshot/HeapSnapshotTempFileHelperParent.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_HeapSnapshotTempFileHelperParent_h
-#define mozilla_devtools_HeapSnapshotTempFileHelperParent_h
-
-#include "mozilla/devtools/PHeapSnapshotTempFileHelperParent.h"
-
-namespace mozilla {
-namespace devtools {
-
-class HeapSnapshotTempFileHelperParent : public PHeapSnapshotTempFileHelperParent
-{
- explicit HeapSnapshotTempFileHelperParent() { }
- void ActorDestroy(ActorDestroyReason why) override { }
- bool RecvOpenHeapSnapshotTempFile(OpenHeapSnapshotTempFileResponse* outResponse)
- override;
-
- public:
- static inline PHeapSnapshotTempFileHelperParent* Create();
-};
-
-/* static */ inline PHeapSnapshotTempFileHelperParent*
-HeapSnapshotTempFileHelperParent::Create()
-{
- return new HeapSnapshotTempFileHelperParent();
-}
-
-} // namespace devtools
-} // namespace mozilla
-
-#endif // mozilla_devtools_HeapSnapshotTempFileHelperParent_h
diff --git a/devtools/shared/heapsnapshot/PHeapSnapshotTempFileHelper.ipdl b/devtools/shared/heapsnapshot/PHeapSnapshotTempFileHelper.ipdl
deleted file mode 100644
index 2576470e2..000000000
--- a/devtools/shared/heapsnapshot/PHeapSnapshotTempFileHelper.ipdl
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-include protocol PContent;
-
-namespace mozilla {
-namespace devtools {
-
-struct OpenedFile
-{
- nsString path;
- FileDescriptor descriptor;
-};
-
-union OpenHeapSnapshotTempFileResponse
-{
- nsresult;
- OpenedFile;
-};
-
-sync protocol PHeapSnapshotTempFileHelper
-{
- manager PContent;
-
-parent:
- sync OpenHeapSnapshotTempFile() returns (OpenHeapSnapshotTempFileResponse response);
-
- async __delete__();
-};
-
-} // namespace devtools
-} // namespace mozilla
diff --git a/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp b/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp
deleted file mode 100644
index 0c29db7f9..000000000
--- a/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/devtools/ZeroCopyNSIOutputStream.h"
-
-#include "mozilla/DebugOnly.h"
-#include "mozilla/Unused.h"
-
-namespace mozilla {
-namespace devtools {
-
-ZeroCopyNSIOutputStream::ZeroCopyNSIOutputStream(nsCOMPtr<nsIOutputStream>& out)
- : out(out)
- , result_(NS_OK)
- , amountUsed(0)
- , writtenCount(0)
-{
- DebugOnly<bool> nonBlocking = false;
- MOZ_ASSERT(out->IsNonBlocking(&nonBlocking) == NS_OK);
- MOZ_ASSERT(!nonBlocking);
-}
-
-ZeroCopyNSIOutputStream::~ZeroCopyNSIOutputStream()
-{
- if (!failed())
- Unused << NS_WARN_IF(NS_FAILED(writeBuffer()));
-}
-
-nsresult
-ZeroCopyNSIOutputStream::writeBuffer()
-{
- if (failed())
- return result_;
-
- if (amountUsed == 0)
- return NS_OK;
-
- int32_t amountWritten = 0;
- while (amountWritten < amountUsed) {
- uint32_t justWritten = 0;
-
- result_ = out->Write(buffer + amountWritten,
- amountUsed - amountWritten,
- &justWritten);
- if (NS_WARN_IF(NS_FAILED(result_)))
- return result_;
-
- amountWritten += justWritten;
- }
-
- writtenCount += amountUsed;
- amountUsed = 0;
- return NS_OK;
-}
-
-// ZeroCopyOutputStream Interface
-
-bool
-ZeroCopyNSIOutputStream::Next(void** data, int* size)
-{
- MOZ_ASSERT(data != nullptr);
- MOZ_ASSERT(size != nullptr);
-
- if (failed())
- return false;
-
- if (amountUsed == BUFFER_SIZE) {
- if (NS_FAILED(writeBuffer()))
- return false;
- }
-
- *data = buffer + amountUsed;
- *size = BUFFER_SIZE - amountUsed;
- amountUsed = BUFFER_SIZE;
- return true;
-}
-
-void
-ZeroCopyNSIOutputStream::BackUp(int count)
-{
- MOZ_ASSERT(count >= 0,
- "Cannot back up a negative amount of bytes.");
- MOZ_ASSERT(amountUsed == BUFFER_SIZE,
- "Can only call BackUp directly after calling Next.");
- MOZ_ASSERT(count <= amountUsed,
- "Can't back up further than we've given out.");
-
- amountUsed -= count;
-}
-
-::google::protobuf::int64
-ZeroCopyNSIOutputStream::ByteCount() const
-{
- return writtenCount + amountUsed;
-}
-
-} // namespace devtools
-} // namespace mozilla
diff --git a/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.h b/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.h
deleted file mode 100644
index 117fc0f87..000000000
--- a/devtools/shared/heapsnapshot/ZeroCopyNSIOutputStream.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_ZeroCopyNSIOutputStream__
-#define mozilla_devtools_ZeroCopyNSIOutputStream__
-
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/stubs/common.h>
-
-#include "nsCOMPtr.h"
-#include "nsIOutputStream.h"
-
-namespace mozilla {
-namespace devtools {
-
-// A `google::protobuf::io::ZeroCopyOutputStream` implementation that uses an
-// `nsIOutputStream` under the covers.
-//
-// This class will automatically write and flush its data to the
-// `nsIOutputStream` in its destructor, but if you care whether that call
-// succeeds or fails, then you should call the `flush` method yourself. Errors
-// will be logged, however.
-class MOZ_STACK_CLASS ZeroCopyNSIOutputStream
- : public ::google::protobuf::io::ZeroCopyOutputStream
-{
- static const int BUFFER_SIZE = 8192;
-
- // The nsIOutputStream we are streaming to.
- nsCOMPtr<nsIOutputStream>& out;
-
- // The buffer we write data to before passing it to the output stream.
- char buffer[BUFFER_SIZE];
-
- // The status of writing to the underlying output stream.
- nsresult result_;
-
- // The number of bytes in the buffer that have been used thus far.
- int amountUsed;
-
- // Excluding the amount of the buffer currently used (which hasn't been
- // written and flushed yet), this is the number of bytes written to the output
- // stream.
- int64_t writtenCount;
-
- // Write the internal buffer to the output stream and flush it.
- nsresult writeBuffer();
-
-public:
- explicit ZeroCopyNSIOutputStream(nsCOMPtr<nsIOutputStream>& out);
-
- nsresult flush() { return writeBuffer(); }
-
- // Return true if writing to the underlying output stream ever failed.
- bool failed() const { return NS_FAILED(result_); }
-
- nsresult result() const { return result_; }
-
- // ZeroCopyOutputStream Interface
- virtual ~ZeroCopyNSIOutputStream() override;
- virtual bool Next(void** data, int* size) override;
- virtual void BackUp(int count) override;
- virtual ::google::protobuf::int64 ByteCount() const override;
-};
-
-} // namespace devtools
-} // namespace mozilla
-
-#endif // mozilla_devtools_ZeroCopyNSIOutputStream__
diff --git a/devtools/shared/heapsnapshot/census-tree-node.js b/devtools/shared/heapsnapshot/census-tree-node.js
deleted file mode 100644
index b041e77f9..000000000
--- a/devtools/shared/heapsnapshot/census-tree-node.js
+++ /dev/null
@@ -1,748 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-// CensusTreeNode is an intermediate representation of a census report that
-// exists between after a report is generated by taking a census and before the
-// report is rendered in the DOM. It must be dead simple to render, with no
-// further data processing or massaging needed before rendering DOM nodes. Our
-// goal is to do the census report to CensusTreeNode transformation in the
-// HeapAnalysesWorker, and ensure that the **only** work that the main thread
-// has to do is strictly DOM rendering work.
-
-const {
- Visitor,
- walk,
- basisTotalBytes,
- basisTotalCount,
-} = require("resource://devtools/shared/heapsnapshot/CensusUtils.js");
-
-// Monotonically increasing integer for CensusTreeNode `id`s.
-let censusTreeNodeIdCounter = 0;
-
-/**
- * Return true if the given object is a SavedFrame stack object, false otherwise.
- *
- * @param {any} obj
- * @returns {Boolean}
- */
-function isSavedFrame(obj) {
- return Object.prototype.toString.call(obj) === "[object SavedFrame]";
-}
-
-/**
- * A CensusTreeNodeCache maps from SavedFrames to CensusTreeNodes. It is used when
- * aggregating multiple SavedFrame allocation stack keys into a tree of many
- * CensusTreeNodes. Each stack may share older frames, and we want to preserve
- * this sharing when converting to CensusTreeNode, so before creating a new
- * CensusTreeNode, we look for an existing one in one of our CensusTreeNodeCaches.
- */
-function CensusTreeNodeCache() {}
-CensusTreeNodeCache.prototype = null;
-
-/**
- * The value of a single entry stored in a CensusTreeNodeCache. It is a pair of
- * the CensusTreeNode for this cache value, and the subsequent
- * CensusTreeNodeCache for this node's children.
- *
- * @param {SavedFrame} frame
- * The frame being cached.
- */
-function CensusTreeNodeCacheValue() {
- // The CensusTreeNode for this cache value.
- this.node = undefined;
- // The CensusTreeNodeCache for this frame's children.
- this.children = undefined;
-}
-
-CensusTreeNodeCacheValue.prototype = null;
-
-/**
- * Create a unique string for the given SavedFrame (ignoring the frame's parent
- * chain) that can be used as a hash to key this frame within a CensusTreeNodeCache.
- *
- * NB: We manually hash rather than using an ES6 Map because we are purposely
- * ignoring the parent chain and wish to consider frames with everything the
- * same except their parents as the same.
- *
- * @param {SavedFrame} frame
- * The SavedFrame object we would like to lookup in or insert into a
- * CensusTreeNodeCache.
- *
- * @returns {String}
- * The unique string that can be used as a key in a CensusTreeNodeCache.
- */
-CensusTreeNodeCache.hashFrame = function (frame) {
- return `FRAME,${frame.functionDisplayName},${frame.source},${frame.line},${frame.column},${frame.asyncCause}`;
-};
-
-/**
- * Create a unique string for the given CensusTreeNode **with regards to
- * siblings at the current depth of the tree, not within the whole tree.** It
- * can be used as a hash to key this node within a CensusTreeNodeCache.
- *
- * @param {CensusTreeNode} node
- * The node we would like to lookup in or insert into a cache.
- *
- * @returns {String}
- * The unique string that can be used as a key in a CensusTreeNodeCache.
- */
-CensusTreeNodeCache.hashNode = function (node) {
- return isSavedFrame(node.name)
- ? CensusTreeNodeCache.hashFrame(node.name)
- : `NODE,${node.name}`;
-};
-
-/**
- * Insert the given CensusTreeNodeCacheValue whose node.name is a SavedFrame
- * object in the given cache.
- *
- * @param {CensusTreeNodeCache} cache
- * @param {CensusTreeNodeCacheValue} value
- */
-CensusTreeNodeCache.insertFrame = function (cache, value) {
- cache[CensusTreeNodeCache.hashFrame(value.node.name)] = value;
-};
-
-/**
- * Insert the given value in the cache.
- *
- * @param {CensusTreeNodeCache} cache
- * @param {CensusTreeNodeCacheValue} value
- */
-CensusTreeNodeCache.insertNode = function (cache, value) {
- if (isSavedFrame(value.node.name)) {
- CensusTreeNodeCache.insertFrame(cache, value);
- } else {
- cache[CensusTreeNodeCache.hashNode(value.node)] = value;
- }
-};
-
-/**
- * Lookup `frame` in `cache` and return its value if it exists.
- *
- * @param {CensusTreeNodeCache} cache
- * @param {SavedFrame} frame
- *
- * @returns {undefined|CensusTreeNodeCacheValue}
- */
-CensusTreeNodeCache.lookupFrame = function (cache, frame) {
- return cache[CensusTreeNodeCache.hashFrame(frame)];
-};
-
-/**
- * Lookup `node` in `cache` and return its value if it exists.
- *
- * @param {CensusTreeNodeCache} cache
- * @param {CensusTreeNode} node
- *
- * @returns {undefined|CensusTreeNodeCacheValue}
- */
-CensusTreeNodeCache.lookupNode = function (cache, node) {
- return isSavedFrame(node.name)
- ? CensusTreeNodeCache.lookupFrame(cache, node.name)
- : cache[CensusTreeNodeCache.hashNode(node)];
-};
-
-/**
- * Add `child` to `parent`'s set of children and store the parent ID
- * on the child.
- *
- * @param {CensusTreeNode} parent
- * @param {CensusTreeNode} child
- */
-function addChild(parent, child) {
- if (!parent.children) {
- parent.children = [];
- }
- child.parent = parent.id;
- parent.children.push(child);
-}
-
-/**
- * Get an array of each frame in the provided stack.
- *
- * @param {SavedFrame} stack
- * @returns {Array<SavedFrame>}
- */
-function getArrayOfFrames(stack) {
- const frames = [];
- let frame = stack;
- while (frame) {
- frames.push(frame);
- frame = frame.parent;
- }
- frames.reverse();
- return frames;
-}
-
-/**
- * Given an `edge` to a sub-`report` whose structure is described by
- * `breakdown`, create a CensusTreeNode tree.
- *
- * @param {Object} breakdown
- * The breakdown specifying the structure of the given report.
- *
- * @param {Object} report
- * The census report.
- *
- * @param {null|String|SavedFrame} edge
- * The edge leading to this report from the parent report.
- *
- * @param {CensusTreeNodeCache} cache
- * The cache of CensusTreeNodes we have already made for the siblings of
- * the node being created. The existing nodes are reused when possible.
- *
- * @param {Object} outParams
- * The return values are attached to this object after this function
- * returns. Because we create a CensusTreeNode for each frame in a
- * SavedFrame stack edge, there may multiple nodes per sub-report.
- *
- * - top: The deepest node in the CensusTreeNode subtree created.
- *
- * - bottom: The shallowest node in the CensusTreeNode subtree created.
- * This is null if the shallowest node in the subtree was
- * found in the `cache` and reused.
- *
- * Note that top and bottom are not necessarily different. In the case
- * where there is a 1:1 correspondence between an edge in the report and
- * a CensusTreeNode, top and bottom refer to the same node.
- */
-function makeCensusTreeNodeSubTree(breakdown, report, edge, cache, outParams) {
- if (!isSavedFrame(edge)) {
- const node = new CensusTreeNode(edge);
- outParams.top = outParams.bottom = node;
- return;
- }
-
- const frames = getArrayOfFrames(edge);
- let currentCache = cache;
- let prevNode;
- for (let i = 0, length = frames.length; i < length; i++) {
- const frame = frames[i];
-
- // Get or create the CensusTreeNodeCacheValue for this frame. If we already
- // have a CensusTreeNodeCacheValue (and hence a CensusTreeNode) for this
- // frame, we don't need to add the node to the previous node's children as
- // we have already done that. If we don't have a CensusTreeNodeCacheValue
- // and CensusTreeNode for this frame, then create one and make sure to hook
- // it up as a child of the previous node.
- let isNewNode = false;
- let val = CensusTreeNodeCache.lookupFrame(currentCache, frame);
- if (!val) {
- isNewNode = true;
- val = new CensusTreeNodeCacheValue();
- val.node = new CensusTreeNode(frame);
-
- CensusTreeNodeCache.insertFrame(currentCache, val);
- if (prevNode) {
- addChild(prevNode, val.node);
- }
- }
-
- if (i === 0) {
- outParams.bottom = isNewNode ? val.node : null;
- }
- if (i === length - 1) {
- outParams.top = val.node;
- }
-
- prevNode = val.node;
-
- if (i !== length - 1 && !val.children) {
- // This is not the last frame and therefore this node will have
- // children, which we must cache.
- val.children = new CensusTreeNodeCache();
- }
-
- currentCache = val.children;
- }
-}
-
-/**
- * A Visitor that walks a census report and creates the corresponding
- * CensusTreeNode tree.
- */
-function CensusTreeNodeVisitor() {
- // The root of the resulting CensusTreeNode tree.
- this._root = null;
-
- // The stack of CensusTreeNodes that we are in the process of building while
- // walking the census report.
- this._nodeStack = [];
-
- // To avoid unnecessary allocations, we reuse the same out parameter object
- // passed to `makeCensusTreeNodeSubTree` every time we call it.
- this._outParams = {
- top: null,
- bottom: null,
- };
-
- // The stack of `CensusTreeNodeCache`s that we use to aggregate many
- // SavedFrame stacks into a single CensusTreeNode tree.
- this._cacheStack = [new CensusTreeNodeCache()];
-
- // The current index in the DFS of the census report tree.
- this._index = -1;
-}
-
-CensusTreeNodeVisitor.prototype = Object.create(Visitor);
-
-/**
- * Create the CensusTreeNode subtree for this sub-report and link it to the
- * parent CensusTreeNode.
- *
- * @overrides Visitor.prototype.enter
- */
-CensusTreeNodeVisitor.prototype.enter = function (breakdown, report, edge) {
- this._index++;
-
- const cache = this._cacheStack[this._cacheStack.length - 1];
- makeCensusTreeNodeSubTree(breakdown, report, edge, cache, this._outParams);
- const { top, bottom } = this._outParams;
-
- if (!this._root) {
- this._root = bottom;
- } else if (bottom) {
- addChild(this._nodeStack[this._nodeStack.length - 1], bottom);
- }
-
- this._cacheStack.push(new CensusTreeNodeCache());
- this._nodeStack.push(top);
-};
-
-function values(cache) {
- return Object.keys(cache).map(k => cache[k]);
-}
-
-function isNonEmpty(node) {
- return (node.children !== undefined && node.children.length)
- || node.bytes !== 0
- || node.count !== 0;
-}
-
-/**
- * We have finished adding children to the CensusTreeNode subtree for the
- * current sub-report. Make sure that the children are sorted for every node in
- * the subtree.
- *
- * @overrides Visitor.prototype.exit
- */
-CensusTreeNodeVisitor.prototype.exit = function (breakdown, report, edge) {
- // Ensure all children are sorted and have their counts/bytes aggregated. We
- // only need to consider cache children here, because other children
- // correspond to other sub-reports and we already fixed them up in an earlier
- // invocation of `exit`.
-
- function dfs(node, childrenCache) {
- if (childrenCache) {
- const childValues = values(childrenCache);
- for (let i = 0, length = childValues.length; i < length; i++) {
- dfs(childValues[i].node, childValues[i].children);
- }
- }
-
- node.totalCount = node.count;
- node.totalBytes = node.bytes;
-
- if (node.children) {
- // Prune empty leaves.
- node.children = node.children.filter(isNonEmpty);
-
- node.children.sort(compareByTotal);
-
- for (let i = 0, length = node.children.length; i < length; i++) {
- node.totalCount += node.children[i].totalCount;
- node.totalBytes += node.children[i].totalBytes;
- }
- }
- }
-
- const top = this._nodeStack.pop();
- const cache = this._cacheStack.pop();
- dfs(top, cache);
-};
-
-/**
- * @overrides Visitor.prototype.count
- */
-CensusTreeNodeVisitor.prototype.count = function (breakdown, report, edge) {
- const node = this._nodeStack[this._nodeStack.length - 1];
- node.reportLeafIndex = this._index;
-
- if (breakdown.count) {
- node.count = report.count;
- }
-
- if (breakdown.bytes) {
- node.bytes = report.bytes;
- }
-};
-
-/**
- * Get the root of the resulting CensusTreeNode tree.
- *
- * @returns {CensusTreeNode}
- */
-CensusTreeNodeVisitor.prototype.root = function () {
- if (!this._root) {
- throw new Error("Attempt to get the root before walking the census report!");
- }
-
- if (this._nodeStack.length) {
- throw new Error("Attempt to get the root while walking the census report!");
- }
-
- return this._root;
-};
-
-/**
- * Create a single, uninitialized CensusTreeNode.
- *
- * @param {null|String|SavedFrame} name
- */
-function CensusTreeNode(name) {
- // Display name for this CensusTreeNode. Either null, a string, or a
- // SavedFrame.
- this.name = name;
-
- // The number of bytes occupied by matching things in the heap snapshot.
- this.bytes = 0;
-
- // The sum of `this.bytes` and `child.totalBytes` for each child in
- // `this.children`.
- this.totalBytes = 0;
-
- // The number of things in the heap snapshot that match this node in the
- // census tree.
- this.count = 0;
-
- // The sum of `this.count` and `child.totalCount` for each child in
- // `this.children`.
- this.totalCount = 0;
-
- // An array of this node's children, or undefined if it has no children.
- this.children = undefined;
-
- // The unique ID of this node.
- this.id = ++censusTreeNodeIdCounter;
-
- // If present, the unique ID of this node's parent. If this node does not have
- // a parent, then undefined.
- this.parent = undefined;
-
- // The `reportLeafIndex` property allows mapping a CensusTreeNode node back to
- // a leaf in the census report it was generated from. It is always one of the
- // following variants:
- //
- // * A `Number` index pointing a leaf report in a pre-order DFS traversal of
- // this CensusTreeNode's census report.
- //
- // * A `Set` object containing such indices, when this is part of an inverted
- // CensusTreeNode tree and multiple leaves in the report map onto this node.
- //
- // * Finally, `undefined` when no leaves in the census report correspond with
- // this node.
- //
- // The first and third cases are the common cases. The second case is rather
- // uncommon, and to avoid doubling the number of allocations when creating
- // CensusTreeNode trees, and objects that get structured cloned when sending
- // such trees from the HeapAnalysesWorker to the main thread, we only allocate
- // a Set object once a node actually does have multiple leaves it corresponds
- // to.
- this.reportLeafIndex = undefined;
-}
-
-CensusTreeNode.prototype = null;
-
-/**
- * Compare the given nodes by their `totalBytes` properties, and breaking ties
- * with the `totalCount`, `bytes`, and `count` properties (in that order).
- *
- * @param {CensusTreeNode} node1
- * @param {CensusTreeNode} node2
- *
- * @returns {Number}
- * A number suitable for using with Array.prototype.sort.
- */
-function compareByTotal(node1, node2) {
- return Math.abs(node2.totalBytes) - Math.abs(node1.totalBytes)
- || Math.abs(node2.totalCount) - Math.abs(node1.totalCount)
- || Math.abs(node2.bytes) - Math.abs(node1.bytes)
- || Math.abs(node2.count) - Math.abs(node1.count);
-}
-
-/**
- * Compare the given nodes by their `bytes` properties, and breaking ties with
- * the `count`, `totalBytes`, and `totalCount` properties (in that order).
- *
- * @param {CensusTreeNode} node1
- * @param {CensusTreeNode} node2
- *
- * @returns {Number}
- * A number suitable for using with Array.prototype.sort.
- */
-function compareBySelf(node1, node2) {
- return Math.abs(node2.bytes) - Math.abs(node1.bytes)
- || Math.abs(node2.count) - Math.abs(node1.count)
- || Math.abs(node2.totalBytes) - Math.abs(node1.totalBytes)
- || Math.abs(node2.totalCount) - Math.abs(node1.totalCount);
-}
-
-/**
- * Given a parent cache value from a tree we are building and a child node from
- * a tree we are basing the new tree off of, if we already have a corresponding
- * node in the parent's children cache, merge this node's counts with
- * it. Otherwise, create the corresponding node, add it to the parent's children
- * cache, and create the parent->child edge.
- *
- * @param {CensusTreeNodeCacheValue} parentCachevalue
- * @param {CensusTreeNode} node
- *
- * @returns {CensusTreeNodeCacheValue}
- * The new or extant child node's corresponding cache value.
- */
-function insertOrMergeNode(parentCacheValue, node) {
- if (!parentCacheValue.children) {
- parentCacheValue.children = new CensusTreeNodeCache();
- }
-
- let val = CensusTreeNodeCache.lookupNode(parentCacheValue.children, node);
-
- if (val) {
- // When inverting, it is possible that multiple leaves in the census report
- // get merged into a single CensusTreeNode node. When this occurs, switch
- // from a single index to a set of indices.
- if (val.node.reportLeafIndex !== undefined &&
- val.node.reportLeafIndex !== node.reportLeafIndex) {
- if (typeof val.node.reportLeafIndex === "number") {
- const oldIndex = val.node.reportLeafIndex;
- val.node.reportLeafIndex = new Set();
- val.node.reportLeafIndex.add(oldIndex);
- val.node.reportLeafIndex.add(node.reportLeafIndex);
- } else {
- val.node.reportLeafIndex.add(node.reportLeafIndex);
- }
- }
-
- val.node.count += node.count;
- val.node.bytes += node.bytes;
- } else {
- val = new CensusTreeNodeCacheValue();
-
- val.node = new CensusTreeNode(node.name);
- val.node.reportLeafIndex = node.reportLeafIndex;
- val.node.count = node.count;
- val.node.totalCount = node.totalCount;
- val.node.bytes = node.bytes;
- val.node.totalBytes = node.totalBytes;
-
- addChild(parentCacheValue.node, val.node);
- CensusTreeNodeCache.insertNode(parentCacheValue.children, val);
- }
-
- return val;
-}
-
-/**
- * Given an un-inverted CensusTreeNode tree, return the corresponding inverted
- * CensusTreeNode tree. The input tree is not modified. The resulting inverted
- * tree is sorted by self bytes rather than by total bytes.
- *
- * @param {CensusTreeNode} tree
- * The un-inverted tree.
- *
- * @returns {CensusTreeNode}
- * The corresponding inverted tree.
- */
-function invert(tree) {
- const inverted = new CensusTreeNodeCacheValue();
- inverted.node = new CensusTreeNode(null);
-
- // Do a depth-first search of the un-inverted tree. As we reach each leaf,
- // take the path from the old root to the leaf, reverse that path, and add it
- // to the new, inverted tree's root.
-
- const path = [];
- (function addInvertedPaths(node) {
- path.push(node);
-
- if (node.children) {
- for (let i = 0, length = node.children.length; i < length; i++) {
- addInvertedPaths(node.children[i]);
- }
- } else {
- // We found a leaf node, add the reverse path to the inverted tree.
- let currentCacheValue = inverted;
- for (let i = path.length - 1; i >= 0; i--) {
- currentCacheValue = insertOrMergeNode(currentCacheValue, path[i]);
- }
- }
-
- path.pop();
- }(tree));
-
- // Ensure that the root node always has the totals.
- inverted.node.totalBytes = tree.totalBytes;
- inverted.node.totalCount = tree.totalCount;
-
- return inverted.node;
-}
-
-/**
- * Given a CensusTreeNode tree and predicate function, create the tree
- * containing only the nodes in any path `(node_0, node_1, ..., node_n-1)` in
- * the given tree where `predicate(node_j)` is true for `0 <= j < n`, `node_0`
- * is the given tree's root, and `node_n-1` is a leaf in the given tree. The
- * given tree is left unmodified.
- *
- * @param {CensusTreeNode} tree
- * @param {Function} predicate
- *
- * @returns {CensusTreeNode}
- */
-function filter(tree, predicate) {
- const filtered = new CensusTreeNodeCacheValue();
- filtered.node = new CensusTreeNode(null);
-
- // Do a DFS over the given tree. If the predicate returns true for any node,
- // add that node and its whole subtree to the filtered tree.
-
- const path = [];
- let match = false;
-
- function addMatchingNodes(node) {
- path.push(node);
-
- let oldMatch = match;
- if (!match && predicate(node)) {
- match = true;
- }
-
- if (node.children) {
- for (let i = 0, length = node.children.length; i < length; i++) {
- addMatchingNodes(node.children[i]);
- }
- } else if (match) {
- // We found a matching leaf node, add it to the filtered tree.
- let currentCacheValue = filtered;
- for (let i = 0, length = path.length; i < length; i++) {
- currentCacheValue = insertOrMergeNode(currentCacheValue, path[i]);
- }
- }
-
- match = oldMatch;
- path.pop();
- }
-
- if (tree.children) {
- for (let i = 0, length = tree.children.length; i < length; i++) {
- addMatchingNodes(tree.children[i]);
- }
- }
-
- filtered.node.count = tree.count;
- filtered.node.totalCount = tree.totalCount;
- filtered.node.bytes = tree.bytes;
- filtered.node.totalBytes = tree.totalBytes;
-
- return filtered.node;
-}
-
-/**
- * Given a filter string, return a predicate function that takes a node and
- * returns true iff the node matches the filter.
- *
- * @param {String} filterString
- * @returns {Function}
- */
-function makeFilterPredicate(filterString) {
- return function (node) {
- if (!node.name) {
- return false;
- }
-
- if (isSavedFrame(node.name)) {
- return node.name.source.includes(filterString)
- || (node.name.functionDisplayName || "").includes(filterString)
- || (node.name.asyncCause || "").includes(filterString);
- }
-
- return String(node.name).includes(filterString);
- };
-}
-
-/**
- * Takes a report from a census (`dbg.memory.takeCensus()`) and the breakdown
- * used to generate the census and returns a structure used to render
- * a tree to display the data.
- *
- * Returns a recursive "CensusTreeNode" object, looking like:
- *
- * CensusTreeNode = {
- * // `children` if it exists, is sorted by `bytes`, if they are leaf nodes.
- * children: ?[<CensusTreeNode...>],
- * name: <?String>
- * count: <?Number>
- * bytes: <?Number>
- * id: <?Number>
- * parent: <?Number>
- * }
- *
- * @param {Object} breakdown
- * The breakdown used to generate the census report.
- *
- * @param {Object} report
- * The census report generated with the specified breakdown.
- *
- * @param {Object} options
- * Configuration options.
- * - invert: Whether to invert the resulting tree or not. Defaults to
- * false, ie uninverted.
- *
- * @returns {CensusTreeNode}
- */
-exports.censusReportToCensusTreeNode = function (breakdown, report,
- options = {
- invert: false,
- filter: null
- }) {
- // Reset the counter so that turning the same census report into a
- // CensusTreeNode tree repeatedly is idempotent.
- censusTreeNodeIdCounter = 0;
-
- const visitor = new CensusTreeNodeVisitor();
- walk(breakdown, report, visitor);
- let result = visitor.root();
-
- if (options.invert) {
- result = invert(result);
- }
-
- if (typeof options.filter === "string") {
- result = filter(result, makeFilterPredicate(options.filter));
- }
-
- // If the report is a delta report that was generated by diffing two other
- // reports, make sure to use the basis totals rather than the totals of the
- // difference.
- if (typeof report[basisTotalBytes] === "number") {
- result.totalBytes = report[basisTotalBytes];
- result.totalCount = report[basisTotalCount];
- }
-
- // Inverting and filtering could have messed up the sort order, so do a
- // depth-first search of the tree and ensure that siblings are sorted.
- const comparator = options.invert ? compareBySelf : compareByTotal;
- (function ensureSorted(node) {
- if (node.children) {
- node.children.sort(comparator);
- for (let i = 0, length = node.children.length; i < length; i++) {
- ensureSorted(node.children[i]);
- }
- }
- }(result));
-
- return result;
-};
diff --git a/devtools/shared/heapsnapshot/generate-core-dump-sources.sh b/devtools/shared/heapsnapshot/generate-core-dump-sources.sh
deleted file mode 100755
index 97e492ff0..000000000
--- a/devtools/shared/heapsnapshot/generate-core-dump-sources.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-
-# A script to generate devtools/server/CoreDump.pb.{h,cc} from
-# devtools/server/CoreDump.proto. This script assumes you have
-# downloaded and installed the protocol buffer compiler, and that it is either
-# on your $PATH or located at $PROTOC_PATH.
-#
-# These files were last compiled with libprotoc 2.4.1.
-
-set -e
-
-cd $(dirname $0)
-
-if [ -n $PROTOC_PATH ]; then
- PROTOC_PATH=`which protoc`
-fi
-
-if [ ! -e $PROTOC_PATH ]; then
- echo You must install the protocol compiler from
- echo https://code.google.com/p/protobuf/downloads/list
- exit 1
-fi
-
-echo Using $PROTOC_PATH as the protocol compiler
-
-$PROTOC_PATH --cpp_out="." CoreDump.proto
diff --git a/devtools/shared/heapsnapshot/moz.build b/devtools/shared/heapsnapshot/moz.build
deleted file mode 100644
index fa9ef3915..000000000
--- a/devtools/shared/heapsnapshot/moz.build
+++ /dev/null
@@ -1,63 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Developer Tools: Memory')
-
-if CONFIG['ENABLE_TESTS']:
- DIRS += ['tests/gtest']
-
-XPCSHELL_TESTS_MANIFESTS += [ 'tests/unit/xpcshell.ini' ]
-MOCHITEST_MANIFESTS += [ 'tests/mochitest/mochitest.ini' ]
-MOCHITEST_CHROME_MANIFESTS += [ 'tests/mochitest/chrome.ini' ]
-
-EXPORTS.mozilla.devtools += [
- 'AutoMemMap.h',
- 'CoreDump.pb.h',
- 'DeserializedNode.h',
- 'DominatorTree.h',
- 'FileDescriptorOutputStream.h',
- 'HeapSnapshot.h',
- 'HeapSnapshotTempFileHelperChild.h',
- 'HeapSnapshotTempFileHelperParent.h',
- 'ZeroCopyNSIOutputStream.h',
-]
-
-IPDL_SOURCES += [
- 'PHeapSnapshotTempFileHelper.ipdl',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-SOURCES += [
- 'AutoMemMap.cpp',
- 'CoreDump.pb.cc',
- 'DeserializedNode.cpp',
- 'DominatorTree.cpp',
- 'FileDescriptorOutputStream.cpp',
- 'HeapSnapshot.cpp',
- 'HeapSnapshotTempFileHelperParent.cpp',
- 'ZeroCopyNSIOutputStream.cpp',
-]
-
-# Disable RTTI in google protocol buffer
-DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
-
-FINAL_LIBRARY = 'xul'
-
-if CONFIG['MOZ_DEVTOOLS_SERVER']:
- DevToolsModules(
- 'census-tree-node.js',
- 'CensusUtils.js',
- 'DominatorTreeNode.js',
- 'HeapAnalysesClient.js',
- 'HeapAnalysesWorker.js',
- 'HeapSnapshotFileUtils.js',
- 'shortest-paths.js',
- )
-
-if CONFIG['GNU_CXX']:
- CXXFLAGS += ['-Wno-error=shadow']
diff --git a/devtools/shared/heapsnapshot/shortest-paths.js b/devtools/shared/heapsnapshot/shortest-paths.js
deleted file mode 100644
index 2d97b7de9..000000000
--- a/devtools/shared/heapsnapshot/shortest-paths.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-/**
- * Compress a set of paths leading to `target` into a single graph, returned as
- * a set of nodes and a set of edges.
- *
- * @param {NodeId} target
- * The target node passed to `HeapSnapshot.computeShortestPaths`.
- *
- * @param {Array<Path>} paths
- * An array of paths to `target`, as returned by
- * `HeapSnapshot.computeShortestPaths`.
- *
- * @returns {Object}
- * An object with two properties:
- * - edges: An array of unique objects of the form:
- * {
- * from: <node ID>,
- * to: <node ID>,
- * name: <string or null>
- * }
- * - nodes: An array of unique node IDs. Every `from` and `to` id is
- * guaranteed to be in this array exactly once.
- */
-exports.deduplicatePaths = function (target, paths) {
- // Use this structure to de-duplicate edges among many retaining paths from
- // start to target.
- //
- // Map<FromNodeId, Map<ToNodeId, Set<EdgeName>>>
- const deduped = new Map();
-
- function insert(from, to, name) {
- let toMap = deduped.get(from);
- if (!toMap) {
- toMap = new Map();
- deduped.set(from, toMap);
- }
-
- let nameSet = toMap.get(to);
- if (!nameSet) {
- nameSet = new Set();
- toMap.set(to, nameSet);
- }
-
- nameSet.add(name);
- }
-
- outer: for (let path of paths) {
- const pathLength = path.length;
-
- // Check for duplicate predecessors in the path, and skip paths that contain
- // them.
- const predecessorsSeen = new Set();
- predecessorsSeen.add(target);
- for (let i = 0; i < pathLength; i++) {
- if (predecessorsSeen.has(path[i].predecessor)) {
- continue outer;
- }
- predecessorsSeen.add(path[i].predecessor);
- }
-
- for (let i = 0; i < pathLength - 1; i++) {
- insert(path[i].predecessor, path[i + 1].predecessor, path[i].edge);
- }
-
- insert(path[pathLength - 1].predecessor, target, path[pathLength - 1].edge);
- }
-
- const nodes = [target];
- const edges = [];
-
- for (let [from, toMap] of deduped) {
- // If the second/third/etc shortest path contains the `target` anywhere
- // other than the very last node, we could accidentally put the `target` in
- // `nodes` more than once.
- if (from !== target) {
- nodes.push(from);
- }
-
- for (let [to, edgeNameSet] of toMap) {
- for (let name of edgeNameSet) {
- edges.push({ from, to, name });
- }
- }
- }
-
- return { nodes, edges };
-};
diff --git a/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp b/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp
deleted file mode 100644
index e236a0acf..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that the `JS::ubi::Node`s we create from
-// `mozilla::devtools::DeserializedNode` instances look and behave as we would
-// like.
-
-#include "DevTools.h"
-#include "js/TypeDecls.h"
-#include "mozilla/devtools/DeserializedNode.h"
-
-using testing::Field;
-using testing::ReturnRef;
-
-// A mock DeserializedNode for testing.
-struct MockDeserializedNode : public DeserializedNode
-{
- MockDeserializedNode(NodeId id, const char16_t* typeName, uint64_t size)
- : DeserializedNode(id, typeName, size)
- { }
-
- bool addEdge(DeserializedEdge&& edge)
- {
- return edges.append(Move(edge));
- }
-
- MOCK_METHOD1(getEdgeReferent, JS::ubi::Node(const DeserializedEdge&));
-};
-
-size_t fakeMallocSizeOf(const void*) {
- EXPECT_TRUE(false);
- MOZ_ASSERT_UNREACHABLE("fakeMallocSizeOf should never be called because "
- "DeserializedNodes report the deserialized size.");
- return 0;
-}
-
-DEF_TEST(DeserializedNodeUbiNodes, {
- const char16_t* typeName = u"TestTypeName";
- const char* className = "MyObjectClassName";
- const char* filename = "my-cool-filename.js";
-
- NodeId id = uint64_t(1) << 33;
- uint64_t size = uint64_t(1) << 60;
- MockDeserializedNode mocked(id, typeName, size);
- mocked.coarseType = JS::ubi::CoarseType::Script;
- mocked.jsObjectClassName = className;
- mocked.scriptFilename = filename;
-
- DeserializedNode& deserialized = mocked;
- JS::ubi::Node ubi(&deserialized);
-
- // Test the ubi::Node accessors.
-
- EXPECT_EQ(size, ubi.size(fakeMallocSizeOf));
- EXPECT_EQ(typeName, ubi.typeName());
- EXPECT_EQ(JS::ubi::CoarseType::Script, ubi.coarseType());
- EXPECT_EQ(id, ubi.identifier());
- EXPECT_FALSE(ubi.isLive());
- EXPECT_EQ(ubi.jsObjectClassName(), className);
- EXPECT_EQ(ubi.scriptFilename(), filename);
-
- // Test the ubi::Node's edges.
-
- UniquePtr<DeserializedNode> referent1(new MockDeserializedNode(1,
- nullptr,
- 10));
- DeserializedEdge edge1(referent1->id);
- mocked.addEdge(Move(edge1));
- EXPECT_CALL(mocked, getEdgeReferent(EdgeTo(referent1->id)))
- .Times(1)
- .WillOnce(Return(JS::ubi::Node(referent1.get())));
-
- UniquePtr<DeserializedNode> referent2(new MockDeserializedNode(2,
- nullptr,
- 20));
- DeserializedEdge edge2(referent2->id);
- mocked.addEdge(Move(edge2));
- EXPECT_CALL(mocked, getEdgeReferent(EdgeTo(referent2->id)))
- .Times(1)
- .WillOnce(Return(JS::ubi::Node(referent2.get())));
-
- UniquePtr<DeserializedNode> referent3(new MockDeserializedNode(3,
- nullptr,
- 30));
- DeserializedEdge edge3(referent3->id);
- mocked.addEdge(Move(edge3));
- EXPECT_CALL(mocked, getEdgeReferent(EdgeTo(referent3->id)))
- .Times(1)
- .WillOnce(Return(JS::ubi::Node(referent3.get())));
-
- auto range = ubi.edges(cx);
- ASSERT_TRUE(!!range);
-
- for ( ; !range->empty(); range->popFront()) {
- // Nothing to do here. This loop ensures that we get each edge referent
- // that we expect above.
- }
- });
diff --git a/devtools/shared/heapsnapshot/tests/gtest/DeserializedStackFrameUbiStackFrames.cpp b/devtools/shared/heapsnapshot/tests/gtest/DeserializedStackFrameUbiStackFrames.cpp
deleted file mode 100644
index 72e363934..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/DeserializedStackFrameUbiStackFrames.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that the `JS::ubi::StackFrame`s we create from
-// `mozilla::devtools::DeserializedStackFrame` instances look and behave as we would
-// like.
-
-#include "DevTools.h"
-#include "js/TypeDecls.h"
-#include "mozilla/devtools/DeserializedNode.h"
-
-using testing::Field;
-using testing::ReturnRef;
-
-// A mock DeserializedStackFrame for testing.
-struct MockDeserializedStackFrame : public DeserializedStackFrame
-{
- MockDeserializedStackFrame() : DeserializedStackFrame() { }
-};
-
-DEF_TEST(DeserializedStackFrameUbiStackFrames, {
- StackFrameId id = uint64_t(1) << 42;
- uint32_t line = 1337;
- uint32_t column = 9; // 3 space tabs!?
- const char16_t* source = u"my-javascript-file.js";
- const char16_t* functionDisplayName = u"myFunctionName";
-
- MockDeserializedStackFrame mocked;
- mocked.id = id;
- mocked.line = line;
- mocked.column = column;
- mocked.source = source;
- mocked.functionDisplayName = functionDisplayName;
-
- DeserializedStackFrame& deserialized = mocked;
- JS::ubi::StackFrame ubiFrame(&deserialized);
-
- // Test the JS::ubi::StackFrame accessors.
-
- EXPECT_EQ(id, ubiFrame.identifier());
- EXPECT_EQ(JS::ubi::StackFrame(), ubiFrame.parent());
- EXPECT_EQ(line, ubiFrame.line());
- EXPECT_EQ(column, ubiFrame.column());
- EXPECT_EQ(JS::ubi::AtomOrTwoByteChars(source), ubiFrame.source());
- EXPECT_EQ(JS::ubi::AtomOrTwoByteChars(functionDisplayName),
- ubiFrame.functionDisplayName());
- EXPECT_FALSE(ubiFrame.isSelfHosted(cx));
- EXPECT_FALSE(ubiFrame.isSystem());
-
- JS::RootedObject savedFrame(cx);
- EXPECT_TRUE(ubiFrame.constructSavedFrameStack(cx, &savedFrame));
-
- uint32_t frameLine;
- ASSERT_EQ(JS::SavedFrameResult::Ok, JS::GetSavedFrameLine(cx, savedFrame, &frameLine));
- EXPECT_EQ(line, frameLine);
-
- uint32_t frameColumn;
- ASSERT_EQ(JS::SavedFrameResult::Ok, JS::GetSavedFrameColumn(cx, savedFrame, &frameColumn));
- EXPECT_EQ(column, frameColumn);
-
- JS::RootedObject parent(cx);
- ASSERT_EQ(JS::SavedFrameResult::Ok, JS::GetSavedFrameParent(cx, savedFrame, &parent));
- EXPECT_EQ(nullptr, parent);
-
- ASSERT_EQ(NS_strlen(source), 21U);
- char16_t sourceBuf[21] = {};
-
- // Test when the length is shorter than the string length.
- auto written = ubiFrame.source(RangedPtr<char16_t>(sourceBuf), 3);
- EXPECT_EQ(written, 3U);
- for (size_t i = 0; i < 3; i++) {
- EXPECT_EQ(sourceBuf[i], source[i]);
- }
-
- written = ubiFrame.source(RangedPtr<char16_t>(sourceBuf), 21);
- EXPECT_EQ(written, 21U);
- for (size_t i = 0; i < 21; i++) {
- EXPECT_EQ(sourceBuf[i], source[i]);
- }
-
- ASSERT_EQ(NS_strlen(functionDisplayName), 14U);
- char16_t nameBuf[14] = {};
-
- written = ubiFrame.functionDisplayName(RangedPtr<char16_t>(nameBuf), 14);
- EXPECT_EQ(written, 14U);
- for (size_t i = 0; i < 14; i++) {
- EXPECT_EQ(nameBuf[i], functionDisplayName[i]);
- }
-});
diff --git a/devtools/shared/heapsnapshot/tests/gtest/DevTools.h b/devtools/shared/heapsnapshot/tests/gtest/DevTools.h
deleted file mode 100644
index 6eb5cfe21..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/DevTools.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_devtools_gtest_DevTools__
-#define mozilla_devtools_gtest_DevTools__
-
-#include "CoreDump.pb.h"
-#include "jsapi.h"
-#include "jspubtd.h"
-#include "nsCRTGlue.h"
-
-#include "gtest/gtest.h"
-#include "gmock/gmock.h"
-#include "mozilla/devtools/HeapSnapshot.h"
-#include "mozilla/dom/ChromeUtils.h"
-#include "mozilla/CycleCollectedJSContext.h"
-#include "mozilla/Move.h"
-#include "js/Principals.h"
-#include "js/UbiNode.h"
-#include "js/UniquePtr.h"
-
-using namespace mozilla;
-using namespace mozilla::devtools;
-using namespace mozilla::dom;
-using namespace testing;
-
-// GTest fixture class that all of our tests derive from.
-struct DevTools : public ::testing::Test {
- bool _initialized;
- JSContext* cx;
- JSCompartment* compartment;
- JS::Zone* zone;
- JS::PersistentRootedObject global;
-
- DevTools()
- : _initialized(false),
- cx(nullptr)
- { }
-
- virtual void SetUp() {
- MOZ_ASSERT(!_initialized);
-
- cx = getContext();
- if (!cx)
- return;
-
- JS_BeginRequest(cx);
-
- global.init(cx, createGlobal());
- if (!global)
- return;
- JS_EnterCompartment(cx, global);
-
- compartment = js::GetContextCompartment(cx);
- zone = js::GetContextZone(cx);
-
- _initialized = true;
- }
-
- JSContext* getContext() {
- return CycleCollectedJSContext::Get()->Context();
- }
-
- static void reportError(JSContext* cx, const char* message, JSErrorReport* report) {
- fprintf(stderr, "%s:%u:%s\n",
- report->filename ? report->filename : "<no filename>",
- (unsigned int) report->lineno,
- message);
- }
-
- static const JSClass* getGlobalClass() {
- static const JSClassOps globalClassOps = {
- nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr,
- JS_GlobalObjectTraceHook
- };
- static const JSClass globalClass = {
- "global", JSCLASS_GLOBAL_FLAGS,
- &globalClassOps
- };
- return &globalClass;
- }
-
- JSObject* createGlobal()
- {
- /* Create the global object. */
- JS::RootedObject newGlobal(cx);
- JS::CompartmentOptions options;
- options.behaviors().setVersion(JSVERSION_LATEST);
- newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
- JS::FireOnNewGlobalHook, options);
- if (!newGlobal)
- return nullptr;
-
- JSAutoCompartment ac(cx, newGlobal);
-
- /* Populate the global object with the standard globals, like Object and
- Array. */
- if (!JS_InitStandardClasses(cx, newGlobal))
- return nullptr;
-
- return newGlobal;
- }
-
- virtual void TearDown() {
- _initialized = false;
-
- if (global) {
- JS_LeaveCompartment(cx, nullptr);
- global = nullptr;
- }
- if (cx)
- JS_EndRequest(cx);
- }
-};
-
-
-// Helper to define a test and ensure that the fixture is initialized properly.
-#define DEF_TEST(name, body) \
- TEST_F(DevTools, name) { \
- ASSERT_TRUE(_initialized); \
- body \
- }
-
-
-// Fake JS::ubi::Node implementation
-class MOZ_STACK_CLASS FakeNode
-{
-public:
- JS::ubi::EdgeVector edges;
- JSCompartment* compartment;
- JS::Zone* zone;
- size_t size;
-
- explicit FakeNode()
- : edges(),
- compartment(nullptr),
- zone(nullptr),
- size(1)
- { }
-};
-
-namespace JS {
-namespace ubi {
-
-template<>
-class Concrete<FakeNode> : public Base
-{
- const char16_t* typeName() const override {
- return concreteTypeName;
- }
-
- js::UniquePtr<EdgeRange> edges(JSContext*, bool) const override {
- return js::UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges));
- }
-
- Size size(mozilla::MallocSizeOf) const override {
- return get().size;
- }
-
- JS::Zone* zone() const override {
- return get().zone;
- }
-
- JSCompartment* compartment() const override {
- return get().compartment;
- }
-
-protected:
- explicit Concrete(FakeNode* ptr) : Base(ptr) { }
- FakeNode& get() const { return *static_cast<FakeNode*>(ptr); }
-
-public:
- static const char16_t concreteTypeName[];
- static void construct(void* storage, FakeNode* ptr) {
- new (storage) Concrete(ptr);
- }
-};
-
-const char16_t Concrete<FakeNode>::concreteTypeName[] = u"FakeNode";
-
-} // namespace ubi
-} // namespace JS
-
-void AddEdge(FakeNode& node, FakeNode& referent, const char16_t* edgeName = nullptr) {
- char16_t* ownedEdgeName = nullptr;
- if (edgeName) {
- ownedEdgeName = NS_strdup(edgeName);
- ASSERT_NE(ownedEdgeName, nullptr);
- }
-
- JS::ubi::Edge edge(ownedEdgeName, &referent);
- ASSERT_TRUE(node.edges.append(mozilla::Move(edge)));
-}
-
-
-// Custom GMock Matchers
-
-// Use the testing namespace to avoid static analysis failures in the gmock
-// matcher classes that get generated from MATCHER_P macros.
-namespace testing {
-
-// Ensure that given node has the expected number of edges.
-MATCHER_P2(EdgesLength, cx, expectedLength, "") {
- auto edges = arg.edges(cx);
- if (!edges)
- return false;
-
- int actualLength = 0;
- for ( ; !edges->empty(); edges->popFront())
- actualLength++;
-
- return Matcher<int>(Eq(expectedLength))
- .MatchAndExplain(actualLength, result_listener);
-}
-
-// Get the nth edge and match it with the given matcher.
-MATCHER_P3(Edge, cx, n, matcher, "") {
- auto edges = arg.edges(cx);
- if (!edges)
- return false;
-
- int i = 0;
- for ( ; !edges->empty(); edges->popFront()) {
- if (i == n) {
- return Matcher<const JS::ubi::Edge&>(matcher)
- .MatchAndExplain(edges->front(), result_listener);
- }
-
- i++;
- }
-
- return false;
-}
-
-// Ensures that two char16_t* strings are equal.
-MATCHER_P(UTF16StrEq, str, "") {
- return NS_strcmp(arg, str) == 0;
-}
-
-MATCHER_P(UniqueUTF16StrEq, str, "") {
- return NS_strcmp(arg.get(), str) == 0;
-}
-
-MATCHER(UniqueIsNull, "") {
- return arg.get() == nullptr;
-}
-
-// Matches an edge whose referent is the node with the given id.
-MATCHER_P(EdgeTo, id, "") {
- return Matcher<const DeserializedEdge&>(Field(&DeserializedEdge::referent, id))
- .MatchAndExplain(arg, result_listener);
-}
-
-} // namespace testing
-
-
-// A mock `Writer` class to be used with testing `WriteHeapGraph`.
-class MockWriter : public CoreDumpWriter
-{
-public:
- virtual ~MockWriter() override { }
- MOCK_METHOD2(writeNode, bool(const JS::ubi::Node&, CoreDumpWriter::EdgePolicy));
- MOCK_METHOD1(writeMetadata, bool(uint64_t));
-};
-
-void ExpectWriteNode(MockWriter& writer, FakeNode& node) {
- EXPECT_CALL(writer, writeNode(Eq(JS::ubi::Node(&node)), _))
- .Times(1)
- .WillOnce(Return(true));
-}
-
-#endif // mozilla_devtools_gtest_DevTools__
diff --git a/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp b/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp
deleted file mode 100644
index bc517d6d9..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that heap snapshots cross compartment boundaries when expected.
-
-#include "DevTools.h"
-
-DEF_TEST(DoesCrossCompartmentBoundaries, {
- // Create a new global to get a new compartment.
- JS::CompartmentOptions options;
- JS::RootedObject newGlobal(cx, JS_NewGlobalObject(cx,
- getGlobalClass(),
- nullptr,
- JS::FireOnNewGlobalHook,
- options));
- ASSERT_TRUE(newGlobal);
- JSCompartment* newCompartment = nullptr;
- {
- JSAutoCompartment ac(cx, newGlobal);
- ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal));
- newCompartment = js::GetContextCompartment(cx);
- }
- ASSERT_TRUE(newCompartment);
- ASSERT_NE(newCompartment, compartment);
-
- // Our set of target compartments is both the old and new compartments.
- JS::CompartmentSet targetCompartments;
- ASSERT_TRUE(targetCompartments.init());
- ASSERT_TRUE(targetCompartments.put(compartment));
- ASSERT_TRUE(targetCompartments.put(newCompartment));
-
- FakeNode nodeA;
- FakeNode nodeB;
- FakeNode nodeC;
- FakeNode nodeD;
-
- nodeA.compartment = compartment;
- nodeB.compartment = nullptr;
- nodeC.compartment = newCompartment;
- nodeD.compartment = nullptr;
-
- AddEdge(nodeA, nodeB);
- AddEdge(nodeA, nodeC);
- AddEdge(nodeB, nodeD);
-
- ::testing::NiceMock<MockWriter> writer;
-
- // Should serialize nodeA, because it is in one of our target compartments.
- ExpectWriteNode(writer, nodeA);
-
- // Should serialize nodeB, because it doesn't belong to a compartment and is
- // therefore assumed to be shared.
- ExpectWriteNode(writer, nodeB);
-
- // Should also serialize nodeC, which is in our target compartments, but a
- // different compartment than A.
- ExpectWriteNode(writer, nodeC);
-
- // Should serialize nodeD because it's reachable via B and both nodes B and D
- // don't belong to a specific compartment.
- ExpectWriteNode(writer, nodeD);
-
- JS::AutoCheckCannotGC noGC(cx);
-
- ASSERT_TRUE(WriteHeapGraph(cx,
- JS::ubi::Node(&nodeA),
- writer,
- /* wantNames = */ false,
- &targetCompartments,
- noGC));
- });
diff --git a/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp b/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp
deleted file mode 100644
index 2fe5e6ace..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that heap snapshots walk the compartment boundaries correctly.
-
-#include "DevTools.h"
-
-DEF_TEST(DoesntCrossCompartmentBoundaries, {
- // Create a new global to get a new compartment.
- JS::CompartmentOptions options;
- JS::RootedObject newGlobal(cx, JS_NewGlobalObject(cx,
- getGlobalClass(),
- nullptr,
- JS::FireOnNewGlobalHook,
- options));
- ASSERT_TRUE(newGlobal);
- JSCompartment* newCompartment = nullptr;
- {
- JSAutoCompartment ac(cx, newGlobal);
- ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal));
- newCompartment = js::GetContextCompartment(cx);
- }
- ASSERT_TRUE(newCompartment);
- ASSERT_NE(newCompartment, compartment);
-
- // Our set of target compartments is only the pre-existing compartment and
- // does not include the new compartment.
- JS::CompartmentSet targetCompartments;
- ASSERT_TRUE(targetCompartments.init());
- ASSERT_TRUE(targetCompartments.put(compartment));
-
- FakeNode nodeA;
- FakeNode nodeB;
- FakeNode nodeC;
-
- nodeA.compartment = compartment;
- nodeB.compartment = nullptr;
- nodeC.compartment = newCompartment;
-
- AddEdge(nodeA, nodeB);
- AddEdge(nodeB, nodeC);
-
- ::testing::NiceMock<MockWriter> writer;
-
- // Should serialize nodeA, because it is in our target compartments.
- ExpectWriteNode(writer, nodeA);
-
- // Should serialize nodeB, because it doesn't belong to a compartment and is
- // therefore assumed to be shared.
- ExpectWriteNode(writer, nodeB);
-
- // But we shouldn't ever serialize nodeC.
-
- JS::AutoCheckCannotGC noGC(cx);
-
- ASSERT_TRUE(WriteHeapGraph(cx,
- JS::ubi::Node(&nodeA),
- writer,
- /* wantNames = */ false,
- &targetCompartments,
- noGC));
- });
diff --git a/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp b/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp
deleted file mode 100644
index be135dbb4..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that edge names get serialized correctly.
-
-#include "DevTools.h"
-
-using testing::Field;
-using testing::IsNull;
-using testing::Property;
-using testing::Return;
-
-DEF_TEST(SerializesEdgeNames, {
- FakeNode node;
- FakeNode referent;
-
- const char16_t edgeName[] = u"edge name";
- const char16_t emptyStr[] = u"";
-
- AddEdge(node, referent, edgeName);
- AddEdge(node, referent, emptyStr);
- AddEdge(node, referent, nullptr);
-
- ::testing::NiceMock<MockWriter> writer;
-
- // Should get the node with edges once.
- EXPECT_CALL(
- writer,
- writeNode(AllOf(EdgesLength(cx, 3),
- Edge(cx, 0, Field(&JS::ubi::Edge::name,
- UniqueUTF16StrEq(edgeName))),
- Edge(cx, 1, Field(&JS::ubi::Edge::name,
- UniqueUTF16StrEq(emptyStr))),
- Edge(cx, 2, Field(&JS::ubi::Edge::name,
- UniqueIsNull()))),
- _)
- )
- .Times(1)
- .WillOnce(Return(true));
-
- // Should get the referent node that doesn't have any edges once.
- ExpectWriteNode(writer, referent);
-
- JS::AutoCheckCannotGC noGC(cx);
- ASSERT_TRUE(WriteHeapGraph(cx,
- JS::ubi::Node(&node),
- writer,
- /* wantNames = */ true,
- /* zones = */ nullptr,
- noGC));
- });
diff --git a/devtools/shared/heapsnapshot/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp b/devtools/shared/heapsnapshot/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp
deleted file mode 100644
index 475442df8..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that everything in the heap graph gets serialized once, and only once.
-
-#include "DevTools.h"
-
-DEF_TEST(SerializesEverythingInHeapGraphOnce, {
- FakeNode nodeA;
- FakeNode nodeB;
- FakeNode nodeC;
- FakeNode nodeD;
-
- AddEdge(nodeA, nodeB);
- AddEdge(nodeB, nodeC);
- AddEdge(nodeC, nodeD);
- AddEdge(nodeD, nodeA);
-
- ::testing::NiceMock<MockWriter> writer;
-
- // Should serialize each node once.
- ExpectWriteNode(writer, nodeA);
- ExpectWriteNode(writer, nodeB);
- ExpectWriteNode(writer, nodeC);
- ExpectWriteNode(writer, nodeD);
-
- JS::AutoCheckCannotGC noGC(cx);
-
- ASSERT_TRUE(WriteHeapGraph(cx,
- JS::ubi::Node(&nodeA),
- writer,
- /* wantNames = */ false,
- /* zones = */ nullptr,
- noGC));
- });
diff --git a/devtools/shared/heapsnapshot/tests/gtest/SerializesTypeNames.cpp b/devtools/shared/heapsnapshot/tests/gtest/SerializesTypeNames.cpp
deleted file mode 100644
index a259c297b..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/SerializesTypeNames.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that a ubi::Node's typeName gets properly serialized into a core dump.
-
-#include "DevTools.h"
-
-using testing::Property;
-using testing::Return;
-
-DEF_TEST(SerializesTypeNames, {
- FakeNode node;
-
- ::testing::NiceMock<MockWriter> writer;
- EXPECT_CALL(writer, writeNode(Property(&JS::ubi::Node::typeName,
- UTF16StrEq(u"FakeNode")),
- _))
- .Times(1)
- .WillOnce(Return(true));
-
- JS::AutoCheckCannotGC noGC(cx);
- ASSERT_TRUE(WriteHeapGraph(cx,
- JS::ubi::Node(&node),
- writer,
- /* wantNames = */ true,
- /* zones = */ nullptr,
- noGC));
- });
diff --git a/devtools/shared/heapsnapshot/tests/gtest/moz.build b/devtools/shared/heapsnapshot/tests/gtest/moz.build
deleted file mode 100644
index 08c31e47c..000000000
--- a/devtools/shared/heapsnapshot/tests/gtest/moz.build
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, you can obtain one at http://mozilla.org/MPL/2.0/.
-
-Library('devtoolstests')
-
-LOCAL_INCLUDES += [
- '../..',
-]
-
-UNIFIED_SOURCES = [
- 'DeserializedNodeUbiNodes.cpp',
- 'DeserializedStackFrameUbiStackFrames.cpp',
- 'DoesCrossCompartmentBoundaries.cpp',
- 'DoesntCrossCompartmentBoundaries.cpp',
- 'SerializesEdgeNames.cpp',
- 'SerializesEverythingInHeapGraphOnce.cpp',
- 'SerializesTypeNames.cpp',
-]
-
-if CONFIG['GNU_CXX']:
- CXXFLAGS += ['-Wno-error=shadow']
-
-# THE MOCK_METHOD2 macro from gtest triggers this clang warning and it's hard
-# to work around, so we just ignore it.
-if CONFIG['CLANG_CXX']:
- CXXFLAGS += ['-Wno-inconsistent-missing-override']
-
-FINAL_LIBRARY = 'xul-gtest'
diff --git a/devtools/shared/heapsnapshot/tests/mochitest/chrome.ini b/devtools/shared/heapsnapshot/tests/mochitest/chrome.ini
deleted file mode 100644
index 497b6fe37..000000000
--- a/devtools/shared/heapsnapshot/tests/mochitest/chrome.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[DEFAULT]
-tags = devtools devtools-memory
-skip-if = os == 'android'
-support-files =
-
-[test_DominatorTree_01.html]
-[test_SaveHeapSnapshot.html]
-
diff --git a/devtools/shared/heapsnapshot/tests/mochitest/mochitest.ini b/devtools/shared/heapsnapshot/tests/mochitest/mochitest.ini
deleted file mode 100644
index 5e7aa8d10..000000000
--- a/devtools/shared/heapsnapshot/tests/mochitest/mochitest.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[DEFAULT]
-tags = devtools devtools-memory
-support-files =
-
-[test_saveHeapSnapshot_e10s_01.html]
-
diff --git a/devtools/shared/heapsnapshot/tests/mochitest/test_DominatorTree_01.html b/devtools/shared/heapsnapshot/tests/mochitest/test_DominatorTree_01.html
deleted file mode 100644
index 1f9d8c080..000000000
--- a/devtools/shared/heapsnapshot/tests/mochitest/test_DominatorTree_01.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Sanity test that we can compute dominator trees from a heap snapshot in a web window.
--->
-<head>
- <meta charset="utf-8">
- <title>ChromeUtils.saveHeapSnapshot test</title>
- <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
-</head>
-<body>
-<pre id="test">
-<script>
-SimpleTest.waitForExplicitFinish();
-window.onload = function() {
- const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
- const snapshot = ChromeUtils.readHeapSnapshot(path);
-
- const dominatorTree = snapshot.computeDominatorTree();
- ok(dominatorTree);
- ok(dominatorTree instanceof DominatorTree);
-
- let threw = false;
- try {
- new DominatorTree();
- } catch (e) {
- threw = true;
- }
- ok(threw, "Constructor shouldn't be usable");
-
- SimpleTest.finish();
-};
-</script>
-</pre>
-</body>
-</html>
diff --git a/devtools/shared/heapsnapshot/tests/mochitest/test_SaveHeapSnapshot.html b/devtools/shared/heapsnapshot/tests/mochitest/test_SaveHeapSnapshot.html
deleted file mode 100644
index f150a99c7..000000000
--- a/devtools/shared/heapsnapshot/tests/mochitest/test_SaveHeapSnapshot.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Bug 1024774 - Sanity test that we can take a heap snapshot in a web window.
--->
-<head>
- <meta charset="utf-8">
- <title>ChromeUtils.saveHeapSnapshot test</title>
- <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
-</head>
-<body>
-<pre id="test">
-<script>
-SimpleTest.waitForExplicitFinish();
-window.onload = function() {
- ok(ChromeUtils, "The ChromeUtils interface should be exposed in chrome windows.");
- ChromeUtils.saveHeapSnapshot({ runtime: true });
- ok(true, "Should save a heap snapshot and shouldn't throw.");
- SimpleTest.finish();
-};
-</script>
-</pre>
-</body>
-</html>
diff --git a/devtools/shared/heapsnapshot/tests/mochitest/test_saveHeapSnapshot_e10s_01.html b/devtools/shared/heapsnapshot/tests/mochitest/test_saveHeapSnapshot_e10s_01.html
deleted file mode 100644
index 15f88f8e0..000000000
--- a/devtools/shared/heapsnapshot/tests/mochitest/test_saveHeapSnapshot_e10s_01.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-Bug 1201597 - Sanity test that we can take a heap snapshot in an e10s child process.
--->
-<html>
-<head>
- <title>saveHeapSnapshot in e10s child processes</title>
- <script type="application/javascript"
- src="/tests/SimpleTest/SimpleTest.js">
- </script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
- <script type="application/javascript">
- window.onerror = function (msg, url, line, col, err) {
- ok(false, "@" + url + ":" + line + ":" + col + ": " + msg + "\n" + err.stack);
- };
-
- SimpleTest.waitForExplicitFinish();
-
- var childFrameURL = "data:text/html,<!DOCTYPE HTML><html><body></body></html>";
-
- // This function is stringified and loaded in the child process as a frame
- // script.
- function childFrameScript() {
- try {
- ChromeUtils.saveHeapSnapshot({ runtime: true });
- } catch (err) {
- sendAsyncMessage("testSaveHeapSnapshot:error",
- { error: err.toString() });
- return;
- }
-
- sendAsyncMessage("testSaveHeapSnapshot:done", {});
- }
-
- // Kick everything off on load.
- window.onload = function () {
- info("window.onload fired");
- SpecialPowers.addPermission("browser", true, document);
- SpecialPowers.pushPrefEnv({
- "set": [
- ["dom.ipc.browser_frames.oop_by_default", true],
- ["dom.mozBrowserFramesEnabled", true],
- ["browser.pagethumbnails.capturing_disabled", true]
- ]
- }, function () {
- var iframe = document.createElement("iframe");
- SpecialPowers.wrap(iframe).mozbrowser = true;
- iframe.id = "iframe";
- iframe.src = childFrameURL;
-
-
- iframe.addEventListener("mozbrowserloadend", function onLoadEnd() {
- iframe.removeEventListener("mozbrowserloadend", onLoadEnd);
- info("iframe done loading");
-
- var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
-
- function onError(e) {
- ok(false, e.data.error);
- }
- mm.addMessageListener("testSaveHeapSnapshot:error", onError);
-
- mm.addMessageListener("testSaveHeapSnapshot:done", function onMsg() {
- mm.removeMessageListener("testSaveHeapSnapshot:done", onMsg);
- mm.removeMessageListener("testSaveHeapSnapshot:error", onError);
- ok(true, "Saved heap snapshot in child process");
- SimpleTest.finish();
- });
-
- info("Loading frame script to save heap snapshot");
- mm.loadFrameScript("data:,(" + encodeURI(childFrameScript.toString()) + ")();",
- false);
- });
-
- info("Loading iframe");
- document.body.appendChild(iframe);
- });
- };
- </script>
-</window>
diff --git a/devtools/shared/heapsnapshot/tests/unit/.eslintrc.js b/devtools/shared/heapsnapshot/tests/unit/.eslintrc.js
deleted file mode 100644
index 59adf410a..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/.eslintrc.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"use strict";
-
-module.exports = {
- // Extend from the common devtools xpcshell eslintrc config.
- "extends": "../../../../.eslintrc.xpcshell.js"
-};
diff --git a/devtools/shared/heapsnapshot/tests/unit/Census.jsm b/devtools/shared/heapsnapshot/tests/unit/Census.jsm
deleted file mode 100644
index f8fb1ce44..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/Census.jsm
+++ /dev/null
@@ -1,165 +0,0 @@
-// Functions for checking results returned by
-// Debugger.Memory.prototype.takeCensus and
-// HeapSnapshot.prototype.takeCensus. Adapted from js/src/jit-test/lib/census.js.
-
-this.EXPORTED_SYMBOLS = ["Census"];
-
-this.Census = (function () {
- const Census = {};
-
- function dumpn(msg) {
- dump("DBG-TEST: Census.jsm: " + msg + "\n");
- }
-
- // Census.walkCensus(subject, name, walker)
- //
- // Use |walker| to check |subject|, a census object of the sort returned by
- // Debugger.Memory.prototype.takeCensus: a tree of objects with integers at the
- // leaves. Use |name| as the name for |subject| in diagnostic messages. Return
- // the number of leaves of |subject| we visited.
- //
- // A walker is an object with three methods:
- //
- // - enter(prop): Return the walker we should use to check the property of the
- // subject census named |prop|. This is for recursing into the subobjects of
- // the subject.
- //
- // - done(): Called after we have called 'enter' on every property of the
- // subject.
- //
- // - check(value): Check |value|, a leaf in the subject.
- //
- // Walker methods are expected to simply throw if a node we visit doesn't look
- // right.
- Census.walkCensus = (subject, name, walker) => walk(subject, name, walker, 0);
- function walk(subject, name, walker, count) {
- if (typeof subject === "object") {
- dumpn(name);
- for (let prop in subject) {
- count = walk(subject[prop],
- name + "[" + uneval(prop) + "]",
- walker.enter(prop),
- count);
- }
- walker.done();
- } else {
- dumpn(name + " = " + uneval(subject));
- walker.check(subject);
- count++;
- }
-
- return count;
- }
-
- // A walker that doesn't check anything.
- Census.walkAnything = {
- enter: () => Census.walkAnything,
- done: () => undefined,
- check: () => undefined
- };
-
- // A walker that requires all leaves to be zeros.
- Census.assertAllZeros = {
- enter: () => Census.assertAllZeros,
- done: () => undefined,
- check: elt => { if (elt !== 0) throw new Error("Census mismatch: expected zero, found " + elt); }
- };
-
- function expectedObject() {
- throw new Error("Census mismatch: subject has leaf where basis has nested object");
- }
-
- function expectedLeaf() {
- throw new Error("Census mismatch: subject has nested object where basis has leaf");
- }
-
- // Return a function that, given a 'basis' census, returns a census walker that
- // compares the subject census against the basis. The returned walker calls the
- // given |compare|, |missing|, and |extra| functions as follows:
- //
- // - compare(subjectLeaf, basisLeaf): Check a leaf of the subject against the
- // corresponding leaf of the basis.
- //
- // - missing(prop, value): Called when the subject is missing a property named
- // |prop| which is present in the basis with value |value|.
- //
- // - extra(prop): Called when the subject has a property named |prop|, but the
- // basis has no such property. This should return a walker that can check
- // the subject's value.
- function makeBasisChecker({compare, missing, extra}) {
- return function makeWalker(basis) {
- if (typeof basis === "object") {
- var unvisited = new Set(Object.getOwnPropertyNames(basis));
- return {
- enter: prop => {
- unvisited.delete(prop);
- if (prop in basis) {
- return makeWalker(basis[prop]);
- } else {
- return extra(prop);
- }
- },
-
- done: () => unvisited.forEach(prop => missing(prop, basis[prop])),
- check: expectedObject
- };
- } else {
- return {
- enter: expectedLeaf,
- done: expectedLeaf,
- check: elt => compare(elt, basis)
- };
- }
- };
- }
-
- function missingProp(prop) {
- throw new Error("Census mismatch: subject lacks property present in basis: " + prop);
- }
-
- function extraProp(prop) {
- throw new Error("Census mismatch: subject has property not present in basis: " + prop);
- }
-
- // Return a walker that checks that the subject census has counts all equal to
- // |basis|.
- Census.assertAllEqual = makeBasisChecker({
- compare: (a, b) => { if (a !== b) throw new Error("Census mismatch: expected " + a + " got " + b);},
- missing: missingProp,
- extra: extraProp
- });
-
- function ok(val) {
- if (!val) {
- throw new Error("Census mismatch: expected truthy, got " + val);
- }
- }
-
- // Return a walker that checks that the subject census has at least as many
- // items of each category as |basis|.
- Census.assertAllNotLessThan = makeBasisChecker({
- compare: (subject, basis) => ok(subject >= basis),
- missing: missingProp,
- extra: () => Census.walkAnything
- });
-
- // Return a walker that checks that the subject census has at most as many
- // items of each category as |basis|.
- Census.assertAllNotMoreThan = makeBasisChecker({
- compare: (subject, basis) => ok(subject <= basis),
- missing: missingProp,
- extra: () => Census.walkAnything
- });
-
- // Return a walker that checks that the subject census has within |fudge|
- // items of each category of the count in |basis|.
- Census.assertAllWithin = function (fudge, basis) {
- return makeBasisChecker({
- compare: (subject, basis) => ok(Math.abs(subject - basis) <= fudge),
- missing: missingProp,
- extra: () => Census.walkAnything
- })(basis);
- };
-
- return Census;
-}());
diff --git a/devtools/shared/heapsnapshot/tests/unit/Match.jsm b/devtools/shared/heapsnapshot/tests/unit/Match.jsm
deleted file mode 100644
index c29e6484e..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/Match.jsm
+++ /dev/null
@@ -1,190 +0,0 @@
-// A little pattern-matching library.
-//
-// Ported from js/src/tests/js1_8_5/reflect-parse/Match.js for use with devtools
-// server xpcshell tests.
-
-this.EXPORTED_SYMBOLS = ["Match"];
-
-this.Match = (function() {
-
- function Pattern(template) {
- // act like a constructor even as a function
- if (!(this instanceof Pattern))
- return new Pattern(template);
-
- this.template = template;
- }
-
- Pattern.prototype = {
- match: function(act) {
- return match(act, this.template);
- },
-
- matches: function(act) {
- try {
- return this.match(act);
- }
- catch (e if e instanceof MatchError) {
- return false;
- }
- },
-
- assert: function(act, message) {
- try {
- return this.match(act);
- }
- catch (e if e instanceof MatchError) {
- throw new Error((message || "failed match") + ": " + e.message);
- }
- },
-
- toString: () => "[object Pattern]"
- };
-
- Pattern.ANY = new Pattern;
- Pattern.ANY.template = Pattern.ANY;
-
- Pattern.NUMBER = new Pattern;
- Pattern.NUMBER.match = function (act) {
- if (typeof act !== 'number') {
- throw new MatchError("Expected number, got: " + quote(act));
- }
- }
-
- Pattern.NATURAL = new Pattern
- Pattern.NATURAL.match = function (act) {
- if (typeof act !== 'number' || act !== Math.floor(act) || act < 0) {
- throw new MatchError("Expected natural number, got: " + quote(act));
- }
- }
-
- var quote = uneval;
-
- function MatchError(msg) {
- this.message = msg;
- }
-
- MatchError.prototype = {
- toString: function() {
- return "match error: " + this.message;
- }
- };
-
- function isAtom(x) {
- return (typeof x === "number") ||
- (typeof x === "string") ||
- (typeof x === "boolean") ||
- (x === null) ||
- (typeof x === "object" && x instanceof RegExp);
- }
-
- function isObject(x) {
- return (x !== null) && (typeof x === "object");
- }
-
- function isFunction(x) {
- return typeof x === "function";
- }
-
- function isArrayLike(x) {
- return isObject(x) && ("length" in x);
- }
-
- function matchAtom(act, exp) {
- if ((typeof exp) === "number" && isNaN(exp)) {
- if ((typeof act) !== "number" || !isNaN(act))
- throw new MatchError("expected NaN, got: " + quote(act));
- return true;
- }
-
- if (exp === null) {
- if (act !== null)
- throw new MatchError("expected null, got: " + quote(act));
- return true;
- }
-
- if (exp instanceof RegExp) {
- if (!(act instanceof RegExp) || exp.source !== act.source)
- throw new MatchError("expected " + quote(exp) + ", got: " + quote(act));
- return true;
- }
-
- switch (typeof exp) {
- case "string":
- if (act !== exp)
- throw new MatchError("expected " + quote(exp) + ", got " + quote(act));
- return true;
- case "boolean":
- case "number":
- if (exp !== act)
- throw new MatchError("expected " + exp + ", got " + quote(act));
- return true;
- }
-
- throw new Error("bad pattern: " + exp.toSource());
- }
-
- function matchObject(act, exp) {
- if (!isObject(act))
- throw new MatchError("expected object, got " + quote(act));
-
- for (var key in exp) {
- if (!(key in act))
- throw new MatchError("expected property " + quote(key) + " not found in " + quote(act));
- match(act[key], exp[key]);
- }
-
- return true;
- }
-
- function matchFunction(act, exp) {
- if (!isFunction(act))
- throw new MatchError("expected function, got " + quote(act));
-
- if (act !== exp)
- throw new MatchError("expected function: " + exp +
- "\nbut got different function: " + act);
- }
-
- function matchArray(act, exp) {
- if (!isObject(act) || !("length" in act))
- throw new MatchError("expected array-like object, got " + quote(act));
-
- var length = exp.length;
- if (act.length !== exp.length)
- throw new MatchError("expected array-like object of length " + length + ", got " + quote(act));
-
- for (var i = 0; i < length; i++) {
- if (i in exp) {
- if (!(i in act))
- throw new MatchError("expected array property " + i + " not found in " + quote(act));
- match(act[i], exp[i]);
- }
- }
-
- return true;
- }
-
- function match(act, exp) {
- if (exp === Pattern.ANY)
- return true;
-
- if (exp instanceof Pattern)
- return exp.match(act);
-
- if (isAtom(exp))
- return matchAtom(act, exp);
-
- if (isArrayLike(exp))
- return matchArray(act, exp);
-
- if (isFunction(exp))
- return matchFunction(act, exp);
-
- return matchObject(act, exp);
- }
-
- return { Pattern: Pattern,
- MatchError: MatchError };
-
-})();
diff --git a/devtools/shared/heapsnapshot/tests/unit/dominator-tree-worker.js b/devtools/shared/heapsnapshot/tests/unit/dominator-tree-worker.js
deleted file mode 100644
index 1f49ca841..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/dominator-tree-worker.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-console.log("Initializing worker.");
-
-self.onmessage = e => {
- console.log("Starting test.");
- try {
- const path = ThreadSafeChromeUtils.saveHeapSnapshot({ runtime: true });
- const snapshot = ThreadSafeChromeUtils.readHeapSnapshot(path);
-
- const dominatorTree = snapshot.computeDominatorTree();
- ok(dominatorTree);
- ok(dominatorTree instanceof DominatorTree);
-
- let threw = false;
- try {
- new DominatorTree();
- } catch (e) {
- threw = true;
- }
- ok(threw, "Constructor shouldn't be usable");
- } catch (e) {
- ok(false, "Unexpected error inside worker:\n" + e.toString() + "\n" + e.stack);
- } finally {
- done();
- }
-};
-
-// Proxy assertions to the main thread.
-function ok(val, msg) {
- console.log("ok(" + !!val + ", \"" + msg + "\")");
- self.postMessage({
- type: "assertion",
- passed: !!val,
- msg,
- stack: Error().stack
- });
-}
-
-// Tell the main thread we are done with the tests.
-function done() {
- console.log("done()");
- self.postMessage({
- type: "done"
- });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js b/devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js
deleted file mode 100644
index 3171c8a6f..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/head_heapsnapshot.js
+++ /dev/null
@@ -1,448 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-var Cr = Components.results;
-var CC = Components.Constructor;
-
-const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const { Match } = Cu.import("resource://test/Match.jsm", {});
-const { Census } = Cu.import("resource://test/Census.jsm", {});
-const { addDebuggerToGlobal } =
- Cu.import("resource://gre/modules/jsdebugger.jsm", {});
-const { Task } = require("devtools/shared/task");
-
-const DevToolsUtils = require("devtools/shared/DevToolsUtils");
-const flags = require("devtools/shared/flags");
-const HeapAnalysesClient =
- require("devtools/shared/heapsnapshot/HeapAnalysesClient");
-const Services = require("Services");
-const { censusReportToCensusTreeNode } = require("devtools/shared/heapsnapshot/census-tree-node");
-const CensusUtils = require("devtools/shared/heapsnapshot/CensusUtils");
-const DominatorTreeNode = require("devtools/shared/heapsnapshot/DominatorTreeNode");
-const { deduplicatePaths } = require("devtools/shared/heapsnapshot/shortest-paths");
-const { LabelAndShallowSizeVisitor } = DominatorTreeNode;
-
-
-// Always log packets when running tests. runxpcshelltests.py will throw
-// the output away anyway, unless you give it the --verbose flag.
-if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
- Services.prefs.setBoolPref("devtools.debugger.log", true);
-}
-flags.wantLogging = true;
-
-const SYSTEM_PRINCIPAL = Cc["@mozilla.org/systemprincipal;1"]
- .createInstance(Ci.nsIPrincipal);
-
-function dumpn(msg) {
- dump("HEAPSNAPSHOT-TEST: " + msg + "\n");
-}
-
-function addTestingFunctionsToGlobal(global) {
- global.eval(
- `
- const testingFunctions = Components.utils.getJSTestingFunctions();
- for (let k in testingFunctions) {
- this[k] = testingFunctions[k];
- }
- `
- );
- if (!global.print) {
- global.print = do_print;
- }
- if (!global.newGlobal) {
- global.newGlobal = newGlobal;
- }
- if (!global.Debugger) {
- addDebuggerToGlobal(global);
- }
-}
-
-addTestingFunctionsToGlobal(this);
-
-/**
- * Create a new global, with all the JS shell testing functions. Similar to the
- * newGlobal function exposed to JS shells, and useful for porting JS shell
- * tests to xpcshell tests.
- */
-function newGlobal() {
- const global = new Cu.Sandbox(SYSTEM_PRINCIPAL, { freshZone: true });
- addTestingFunctionsToGlobal(global);
- return global;
-}
-
-function assertThrowsValue(f, val, msg) {
- var fullmsg;
- try {
- f();
- } catch (exc) {
- if ((exc === val) === (val === val) && (val !== 0 || 1 / exc === 1 / val))
- return;
- fullmsg = "Assertion failed: expected exception " + val + ", got " + exc;
- }
- if (fullmsg === undefined)
- fullmsg = "Assertion failed: expected exception " + val + ", no exception thrown";
- if (msg !== undefined)
- fullmsg += " - " + msg;
- throw new Error(fullmsg);
-}
-
-/**
- * Returns the full path of the file with the specified name in a
- * platform-independent and URL-like form.
- */
-function getFilePath(aName, aAllowMissing = false, aUsePlatformPathSeparator = false)
-{
- let file = do_get_file(aName, aAllowMissing);
- let path = Services.io.newFileURI(file).spec;
- let filePrePath = "file://";
- if ("nsILocalFileWin" in Ci &&
- file instanceof Ci.nsILocalFileWin) {
- filePrePath += "/";
- }
-
- path = path.slice(filePrePath.length);
-
- if (aUsePlatformPathSeparator && path.match(/^\w:/)) {
- path = path.replace(/\//g, "\\");
- }
-
- return path;
-}
-
-function saveNewHeapSnapshot(opts = { runtime: true }) {
- const filePath = ChromeUtils.saveHeapSnapshot(opts);
- ok(filePath, "Should get a file path to save the core dump to.");
- ok(true, "Saved a heap snapshot to " + filePath);
- return filePath;
-}
-
-function readHeapSnapshot(filePath) {
- const snapshot = ChromeUtils.readHeapSnapshot(filePath);
- ok(snapshot, "Should have read a heap snapshot back from " + filePath);
- ok(snapshot instanceof HeapSnapshot, "snapshot should be an instance of HeapSnapshot");
- return snapshot;
-}
-
-/**
- * Save a heap snapshot to the file with the given name in the current
- * directory, read it back as a HeapSnapshot instance, and then take a census of
- * the heap snapshot's serialized heap graph with the provided census options.
- *
- * @param {Object|undefined} censusOptions
- * Options that should be passed through to the takeCensus method. See
- * js/src/doc/Debugger/Debugger.Memory.md for details.
- *
- * @param {Debugger|null} dbg
- * If a Debugger object is given, only serialize the subgraph covered by
- * the Debugger's debuggees. If null, serialize the whole heap graph.
- *
- * @param {String} fileName
- * The file name to save the heap snapshot's core dump file to, within
- * the current directory.
- *
- * @returns Census
- */
-function saveHeapSnapshotAndTakeCensus(dbg = null, censusOptions = undefined) {
- const snapshotOptions = dbg ? { debugger: dbg } : { runtime: true };
- const filePath = saveNewHeapSnapshot(snapshotOptions);
- const snapshot = readHeapSnapshot(filePath);
-
- equal(typeof snapshot.takeCensus, "function", "snapshot should have a takeCensus method");
-
- return snapshot.takeCensus(censusOptions);
-}
-
-/**
- * Save a heap snapshot to disk, read it back as a HeapSnapshot instance, and
- * then compute its dominator tree.
- *
- * @param {Debugger|null} dbg
- * If a Debugger object is given, only serialize the subgraph covered by
- * the Debugger's debuggees. If null, serialize the whole heap graph.
- *
- * @returns {DominatorTree}
- */
-function saveHeapSnapshotAndComputeDominatorTree(dbg = null) {
- const snapshotOptions = dbg ? { debugger: dbg } : { runtime: true };
- const filePath = saveNewHeapSnapshot(snapshotOptions);
- const snapshot = readHeapSnapshot(filePath);
-
- equal(typeof snapshot.computeDominatorTree, "function",
- "snapshot should have a `computeDominatorTree` method");
-
- const dominatorTree = snapshot.computeDominatorTree();
-
- ok(dominatorTree, "Should be able to compute a dominator tree");
- ok(dominatorTree instanceof DominatorTree, "Should be an instance of DominatorTree");
-
- return dominatorTree;
-}
-
-function isSavedFrame(obj) {
- return Object.prototype.toString.call(obj) === "[object SavedFrame]";
-}
-
-function savedFrameReplacer(key, val) {
- if (isSavedFrame(val)) {
- return `<SavedFrame '${val.toString().split(/\n/g).shift()}'>`;
- } else {
- return val;
- }
-}
-
-/**
- * Assert that creating a CensusTreeNode from the given `report` with the
- * specified `breakdown` creates the given `expected` CensusTreeNode.
- *
- * @param {Object} breakdown
- * The census breakdown.
- *
- * @param {Object} report
- * The census report.
- *
- * @param {Object} expected
- * The expected CensusTreeNode result.
- *
- * @param {Object} options
- * The options to pass through to `censusReportToCensusTreeNode`.
- */
-function compareCensusViewData(breakdown, report, expected, options) {
- dumpn("Generating CensusTreeNode from report:");
- dumpn("breakdown: " + JSON.stringify(breakdown, null, 4));
- dumpn("report: " + JSON.stringify(report, null, 4));
- dumpn("expected: " + JSON.stringify(expected, savedFrameReplacer, 4));
-
- const actual = censusReportToCensusTreeNode(breakdown, report, options);
- dumpn("actual: " + JSON.stringify(actual, savedFrameReplacer, 4));
-
- assertStructurallyEquivalent(actual, expected);
-}
-
-// Deep structural equivalence that can handle Map objects in addition to plain
-// objects.
-function assertStructurallyEquivalent(actual, expected, path = "root") {
- if (actual === expected) {
- equal(actual, expected, "actual and expected are the same");
- return;
- }
-
- equal(typeof actual, typeof expected, `${path}: typeof should be the same`);
-
- if (actual && typeof actual === "object") {
- const actualProtoString = Object.prototype.toString.call(actual);
- const expectedProtoString = Object.prototype.toString.call(expected);
- equal(actualProtoString, expectedProtoString,
- `${path}: Object.prototype.toString.call() should be the same`);
-
- if (actualProtoString === "[object Map]") {
- const expectedKeys = new Set([...expected.keys()]);
-
- for (let key of actual.keys()) {
- ok(expectedKeys.has(key),
- `${path}: every key in actual should exist in expected: ${String(key).slice(0, 10)}`);
- expectedKeys.delete(key);
-
- assertStructurallyEquivalent(actual.get(key), expected.get(key),
- path + ".get(" + String(key).slice(0, 20) + ")");
- }
-
- equal(expectedKeys.size, 0,
- `${path}: every key in expected should also exist in actual, did not see ${[...expectedKeys]}`);
- } else if (actualProtoString === "[object Set]") {
- const expectedItems = new Set([...expected]);
-
- for (let item of actual) {
- ok(expectedItems.has(item),
- `${path}: every set item in actual should exist in expected: ${item}`);
- expectedItems.delete(item);
- }
-
- equal(expectedItems.size, 0,
- `${path}: every set item in expected should also exist in actual, did not see ${[...expectedItems]}`);
- } else {
- const expectedKeys = new Set(Object.keys(expected));
-
- for (let key of Object.keys(actual)) {
- ok(expectedKeys.has(key),
- `${path}: every key in actual should exist in expected: ${key}`);
- expectedKeys.delete(key);
-
- assertStructurallyEquivalent(actual[key], expected[key], path + "." + key);
- }
-
- equal(expectedKeys.size, 0,
- `${path}: every key in expected should also exist in actual, did not see ${[...expectedKeys]}`);
- }
- } else {
- equal(actual, expected, `${path}: primitives should be equal`);
- }
-}
-
-/**
- * Assert that creating a diff of the `first` and `second` census reports
- * creates the `expected` delta-report.
- *
- * @param {Object} breakdown
- * The census breakdown.
- *
- * @param {Object} first
- * The first census report.
- *
- * @param {Object} second
- * The second census report.
- *
- * @param {Object} expected
- * The expected delta-report.
- */
-function assertDiff(breakdown, first, second, expected) {
- dumpn("Diffing census reports:");
- dumpn("Breakdown: " + JSON.stringify(breakdown, null, 4));
- dumpn("First census report: " + JSON.stringify(first, null, 4));
- dumpn("Second census report: " + JSON.stringify(second, null, 4));
- dumpn("Expected delta-report: " + JSON.stringify(expected, null, 4));
-
- const actual = CensusUtils.diff(breakdown, first, second);
- dumpn("Actual delta-report: " + JSON.stringify(actual, null, 4));
-
- assertStructurallyEquivalent(actual, expected);
-}
-
-/**
- * Assert that creating a label and getting a shallow size from the given node
- * description with the specified breakdown is as expected.
- *
- * @param {Object} breakdown
- * @param {Object} givenDescription
- * @param {Number} expectedShallowSize
- * @param {Object} expectedLabel
- */
-function assertLabelAndShallowSize(breakdown, givenDescription, expectedShallowSize, expectedLabel) {
- dumpn("Computing label and shallow size from node description:");
- dumpn("Breakdown: " + JSON.stringify(breakdown, null, 4));
- dumpn("Given description: " + JSON.stringify(givenDescription, null, 4));
-
- const visitor = new LabelAndShallowSizeVisitor();
- CensusUtils.walk(breakdown, description, visitor);
-
- dumpn("Expected shallow size: " + expectedShallowSize);
- dumpn("Actual shallow size: " + visitor.shallowSize());
- equal(visitor.shallowSize(), expectedShallowSize, "Shallow size should be correct");
-
- dumpn("Expected label: " + JSON.stringify(expectedLabel, null, 4));
- dumpn("Actual label: " + JSON.stringify(visitor.label(), null, 4));
- assertStructurallyEquivalent(visitor.label(), expectedLabel);
-}
-
-// Counter for mock DominatorTreeNode ids.
-let TEST_NODE_ID_COUNTER = 0;
-
-/**
- * Create a mock DominatorTreeNode for testing, with sane defaults. Override any
- * property by providing it on `opts`. Optionally pass child nodes as well.
- *
- * @param {Object} opts
- * @param {Array<DominatorTreeNode>?} children
- *
- * @returns {DominatorTreeNode}
- */
-function makeTestDominatorTreeNode(opts, children) {
- const nodeId = TEST_NODE_ID_COUNTER++;
-
- const node = Object.assign({
- nodeId,
- label: undefined,
- shallowSize: 1,
- retainedSize: (children || []).reduce((size, c) => size + c.retainedSize, 1),
- parentId: undefined,
- children,
- moreChildrenAvailable: true,
- }, opts);
-
- if (children && children.length) {
- children.map(c => c.parentId = node.nodeId);
- }
-
- return node;
-}
-
-/**
- * Insert `newChildren` into the given dominator `tree` as specified by the
- * `path` from the root to the node the `newChildren` should be inserted
- * beneath. Assert that the resulting tree matches `expected`.
- */
-function assertDominatorTreeNodeInsertion(tree, path, newChildren, moreChildrenAvailable, expected) {
- dumpn("Inserting new children into a dominator tree:");
- dumpn("Dominator tree: " + JSON.stringify(tree, null, 2));
- dumpn("Path: " + JSON.stringify(path, null, 2));
- dumpn("New children: " + JSON.stringify(newChildren, null, 2));
- dumpn("Expected resulting tree: " + JSON.stringify(expected, null, 2));
-
- const actual = DominatorTreeNode.insert(tree, path, newChildren, moreChildrenAvailable);
- dumpn("Actual resulting tree: " + JSON.stringify(actual, null, 2));
-
- assertStructurallyEquivalent(actual, expected);
-}
-
-function assertDeduplicatedPaths({ target, paths, expectedNodes, expectedEdges }) {
- dumpn("Deduplicating paths:");
- dumpn("target = " + target);
- dumpn("paths = " + JSON.stringify(paths, null, 2));
- dumpn("expectedNodes = " + expectedNodes);
- dumpn("expectedEdges = " + JSON.stringify(expectedEdges, null, 2));
-
- const { nodes, edges } = deduplicatePaths(target, paths);
-
- dumpn("Actual nodes = " + nodes);
- dumpn("Actual edges = " + JSON.stringify(edges, null, 2));
-
- equal(nodes.length, expectedNodes.length,
- "actual number of nodes is equal to the expected number of nodes");
-
- equal(edges.length, expectedEdges.length,
- "actual number of edges is equal to the expected number of edges");
-
- const expectedNodeSet = new Set(expectedNodes);
- const nodeSet = new Set(nodes);
- ok(nodeSet.size === nodes.length,
- "each returned node should be unique");
-
- for (let node of nodes) {
- ok(expectedNodeSet.has(node), `the ${node} node was expected`);
- }
-
- for (let expectedEdge of expectedEdges) {
- let count = 0;
- for (let edge of edges) {
- if (edge.from === expectedEdge.from &&
- edge.to === expectedEdge.to &&
- edge.name === expectedEdge.name) {
- count++;
- }
- }
- equal(count, 1,
- "should have exactly one matching edge for the expected edge = " + JSON.stringify(edge));
- }
-}
-
-function assertCountToBucketBreakdown(breakdown, expected) {
- dumpn("count => bucket breakdown");
- dumpn("Initial breakdown = ", JSON.stringify(breakdown, null, 2));
- dumpn("Expected results = ", JSON.stringify(expected, null, 2));
-
- const actual = CensusUtils.countToBucketBreakdown(breakdown);
- dumpn("Actual results = ", JSON.stringify(actual, null, 2));
-
- assertStructurallyEquivalent(actual, expected);
-}
-
-/**
- * Create a mock path entry for the given predecessor and edge.
- */
-function pathEntry(predecessor, edge) {
- return { predecessor, edge };
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/heap-snapshot-worker.js b/devtools/shared/heapsnapshot/tests/unit/heap-snapshot-worker.js
deleted file mode 100644
index 10ee70cec..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/heap-snapshot-worker.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-console.log("Initializing worker.");
-
-self.onmessage = e => {
- console.log("Starting test.");
- try {
- ok(typeof ChromeUtils === "undefined",
- "Should not have access to ChromeUtils in a worker.");
- ok(ThreadSafeChromeUtils,
- "Should have access to ThreadSafeChromeUtils in a worker.");
- ok(HeapSnapshot,
- "Should have access to HeapSnapshot in a worker.");
-
- const filePath = ThreadSafeChromeUtils.saveHeapSnapshot({ globals: [this] });
- ok(true, "Should be able to save a snapshot.");
-
- const snapshot = ThreadSafeChromeUtils.readHeapSnapshot(filePath);
- ok(snapshot, "Should be able to read a heap snapshot");
- ok(snapshot instanceof HeapSnapshot, "Should be an instanceof HeapSnapshot");
- } catch (e) {
- ok(false, "Unexpected error inside worker:\n" + e.toString() + "\n" + e.stack);
- } finally {
- done();
- }
-};
-
-// Proxy assertions to the main thread.
-function ok(val, msg) {
- console.log("ok(" + !!val + ", \"" + msg + "\")");
- self.postMessage({
- type: "assertion",
- passed: !!val,
- msg,
- stack: Error().stack
- });
-}
-
-// Tell the main thread we are done with the tests.
-function done() {
- console.log("done()");
- self.postMessage({
- type: "done"
- });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_01.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_01.js
deleted file mode 100644
index 845a0d263..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_01.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can generate label structures from node description reports.
-
-const breakdown = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
-};
-
-const description = {
- objects: {
- Function: { count: 1, bytes: 32 },
- other: { count: 0, bytes: 0 }
- },
- strings: {},
- scripts: {},
- other: {}
-};
-
-const expected = [
- "objects",
- "Function"
-];
-
-const shallowSize = 32;
-
-function run_test() {
- assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_02.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_02.js
deleted file mode 100644
index e1f32de58..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_02.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can generate label structures from node description reports.
-
-const breakdown = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
-};
-
-const description = {
- objects: {
- other: { count: 1, bytes: 10 }
- },
- strings: {},
- scripts: {},
- other: {}
-};
-
-const expected = [
- "objects",
- "other"
-];
-
-const shallowSize = 10;
-
-function run_test() {
- assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_03.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_03.js
deleted file mode 100644
index ad35dcec1..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_03.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can generate label structures from node description reports.
-
-const breakdown = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
-};
-
-const description = {
- objects: {
- other: { count: 0, bytes: 0 }
- },
- strings: {
- "JSString": { count: 1, bytes: 42 },
- },
- scripts: {},
- other: {}
-};
-
-const expected = [
- "strings",
- "JSString"
-];
-
-const shallowSize = 42;
-
-function run_test() {
- assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_04.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_04.js
deleted file mode 100644
index 566ad0dab..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_LabelAndShallowSize_04.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can generate label structures from node description reports.
-
-const breakdown = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: {
- by: "allocationStack",
- then: { by: "count", count: true, bytes: true },
- noStack: { by: "count", count: true, bytes: true },
- },
- other: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
-};
-
-const stack = saveStack();
-
-const description = {
- objects: {
- Array: new Map([[stack, { count: 1, bytes: 512 }]]),
- other: { count: 0, bytes: 0 }
- },
- strings: {},
- scripts: {},
- other: {}
-};
-
-const expected = [
- "objects",
- "Array",
- stack
-];
-
-const shallowSize = 512;
-
-function run_test() {
- assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_attachShortestPaths_01.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_attachShortestPaths_01.js
deleted file mode 100644
index 24e8e2eb5..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_attachShortestPaths_01.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test that the DominatorTreeNode.attachShortestPaths function can correctly
-// attach the deduplicated shortest retaining paths for each node it is given.
-
-const startNodeId = 9999;
-const maxNumPaths = 2;
-
-// Mock data mapping node id to shortest paths to that node id.
-const shortestPaths = new Map([
- [1000, [
- [pathEntry(1100, "a"), pathEntry(1200, "b")],
- [pathEntry(1100, "c"), pathEntry(1300, "d")],
- ]],
- [2000, [
- [pathEntry(2100, "e"), pathEntry(2200, "f"), pathEntry(2300, "g")]
- ]],
- [3000, [
- [pathEntry(3100, "h")],
- [pathEntry(3100, "i")],
- [pathEntry(3100, "j")],
- [pathEntry(3200, "k")],
- [pathEntry(3300, "l")],
- [pathEntry(3400, "m")],
- ]],
-]);
-
-const actual = [
- makeTestDominatorTreeNode({ nodeId: 1000 }),
- makeTestDominatorTreeNode({ nodeId: 2000 }),
- makeTestDominatorTreeNode({ nodeId: 3000 }),
-];
-
-const expected = [
- makeTestDominatorTreeNode({
- nodeId: 1000,
- shortestPaths: {
- nodes: [
- { id: 1000, label: ["SomeType-1000"] },
- { id: 1100, label: ["SomeType-1100"] },
- { id: 1200, label: ["SomeType-1200"] },
- { id: 1300, label: ["SomeType-1300"] },
- ],
- edges: [
- { from: 1100, to: 1200, name: "a" },
- { from: 1100, to: 1300, name: "c" },
- { from: 1200, to: 1000, name: "b" },
- { from: 1300, to: 1000, name: "d" },
- ]
- }
- }),
-
- makeTestDominatorTreeNode({
- nodeId: 2000,
- shortestPaths: {
- nodes: [
- { id: 2000, label: ["SomeType-2000"] },
- { id: 2100, label: ["SomeType-2100"] },
- { id: 2200, label: ["SomeType-2200"] },
- { id: 2300, label: ["SomeType-2300"] },
- ],
- edges: [
- { from: 2100, to: 2200, name: "e" },
- { from: 2200, to: 2300, name: "f" },
- { from: 2300, to: 2000, name: "g" },
- ]
- }
- }),
-
- makeTestDominatorTreeNode({ nodeId: 3000,
- shortestPaths: {
- nodes: [
- { id: 3000, label: ["SomeType-3000"] },
- { id: 3100, label: ["SomeType-3100"] },
- { id: 3200, label: ["SomeType-3200"] },
- { id: 3300, label: ["SomeType-3300"] },
- { id: 3400, label: ["SomeType-3400"] },
- ],
- edges: [
- { from: 3100, to: 3000, name: "h" },
- { from: 3100, to: 3000, name: "i" },
- { from: 3100, to: 3000, name: "j" },
- { from: 3200, to: 3000, name: "k" },
- { from: 3300, to: 3000, name: "l" },
- { from: 3400, to: 3000, name: "m" },
- ]
- }
- }),
-];
-
-const breakdown = {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
-};
-
-const mockSnapshot = {
- computeShortestPaths: (start, nodeIds, max) => {
- equal(start, startNodeId);
- equal(max, maxNumPaths);
-
- return new Map(nodeIds.map(nodeId => {
- const paths = shortestPaths.get(nodeId);
- ok(paths, "Expected computeShortestPaths call for node id = " + nodeId);
- return [nodeId, paths];
- }));
- },
-
- describeNode: (bd, nodeId) => {
- equal(bd, breakdown);
- return {
- ["SomeType-" + nodeId]: {
- count: 1,
- bytes: 10,
- }
- };
- },
-};
-
-function run_test() {
- DominatorTreeNode.attachShortestPaths(mockSnapshot,
- breakdown,
- startNodeId,
- actual,
- maxNumPaths);
-
- dumpn("Expected = " + JSON.stringify(expected, null, 2));
- dumpn("Actual = " + JSON.stringify(actual, null, 2));
-
- assertStructurallyEquivalent(expected, actual);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_getNodeByIdAlongPath_01.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_getNodeByIdAlongPath_01.js
deleted file mode 100644
index de2907809..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_getNodeByIdAlongPath_01.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can find the node with the given id along the specified path.
-
-const node3000 = makeTestDominatorTreeNode({ nodeId: 3000 });
-
-const node2000 = makeTestDominatorTreeNode({ nodeId: 2000 }, [
- makeTestDominatorTreeNode({}),
- node3000,
- makeTestDominatorTreeNode({}),
-]);
-
-const node1000 = makeTestDominatorTreeNode({ nodeId: 1000 }, [
- makeTestDominatorTreeNode({}),
- node2000,
- makeTestDominatorTreeNode({}),
-]);
-
-const tree = node1000;
-
-const path = [1000, 2000, 3000];
-
-const tests = [
- { id: 1000, expected: node1000 },
- { id: 2000, expected: node2000 },
- { id: 3000, expected: node3000 },
-];
-
-function run_test() {
- for (let { id, expected } of tests) {
- const actual = DominatorTreeNode.getNodeByIdAlongPath(id, tree, path);
- equal(actual, expected, `We should have got the node with id = ${id}`);
- }
-
- equal(null,
- DominatorTreeNode.getNodeByIdAlongPath(999999999999, tree, path),
- "null is returned for nodes that are not even in the tree");
-
- const lastNodeId = tree.children[tree.children.length - 1].nodeId;
- equal(null,
- DominatorTreeNode.getNodeByIdAlongPath(lastNodeId, tree, path),
- "null is returned for nodes that are not along the path");
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_01.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_01.js
deleted file mode 100644
index 979232ff4..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_01.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can insert new children into an existing DominatorTreeNode tree.
-
-const tree = makeTestDominatorTreeNode({ nodeId: 1000 }, [
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({ nodeId: 2000 }, [
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({ nodeId: 3000 }),
- makeTestDominatorTreeNode({}),
- ]),
- makeTestDominatorTreeNode({}),
-]);
-
-const path = [1000, 2000, 3000];
-
-const newChildren = [
- makeTestDominatorTreeNode({ parentId: 3000 }),
- makeTestDominatorTreeNode({ parentId: 3000 }),
-];
-
-const moreChildrenAvailable = false;
-
-const expected = {
- nodeId: 1000,
- parentId: undefined,
- label: undefined,
- shallowSize: 1,
- retainedSize: 7,
- children: [
- {
- nodeId: 0,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 1000,
- moreChildrenAvailable: true,
- children: undefined,
- },
- {
- nodeId: 2000,
- label: undefined,
- shallowSize: 1,
- retainedSize: 4,
- parentId: 1000,
- children: [
- {
- nodeId: 1,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 2000,
- moreChildrenAvailable: true,
- children: undefined,
- },
- {
- nodeId: 3000,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 2000,
- children: [
- {
- nodeId: 7,
- parentId: 3000,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- moreChildrenAvailable: true,
- children: undefined,
- },
- {
- nodeId: 8,
- parentId: 3000,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- moreChildrenAvailable: true,
- children: undefined,
- },
- ],
- moreChildrenAvailable: false
- },
- {
- nodeId: 3,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 2000,
- moreChildrenAvailable: true,
- children: undefined,
- },
- ],
- moreChildrenAvailable: true
- },
- {
- nodeId: 5,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 1000,
- moreChildrenAvailable: true,
- children: undefined,
- }
- ],
- moreChildrenAvailable: true
-};
-
-function run_test() {
- assertDominatorTreeNodeInsertion(tree, path, newChildren, moreChildrenAvailable, expected);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_02.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_02.js
deleted file mode 100644
index 9a8d11d0b..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_02.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test attempting to insert new children into an existing DominatorTreeNode
-// tree with a bad path.
-
-const tree = makeTestDominatorTreeNode({}, [
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({}, [
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({}),
- ]),
- makeTestDominatorTreeNode({}),
-]);
-
-const path = [111111, 222222, 333333];
-
-const newChildren = [
- makeTestDominatorTreeNode({ parentId: 333333 }),
- makeTestDominatorTreeNode({ parentId: 333333 }),
-];
-
-const moreChildrenAvailable = false;
-
-const expected = tree;
-
-function run_test() {
- assertDominatorTreeNodeInsertion(tree, path, newChildren, moreChildrenAvailable, expected);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_03.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_03.js
deleted file mode 100644
index f8cb5eec3..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_insert_03.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test inserting new children into an existing DominatorTreeNode at the root.
-
-const tree = makeTestDominatorTreeNode({ nodeId: 666 }, [
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({}, [
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({}),
- makeTestDominatorTreeNode({}),
- ]),
- makeTestDominatorTreeNode({}),
-]);
-
-const path = [666];
-
-const newChildren = [
- makeTestDominatorTreeNode({
- nodeId: 777,
- parentId: 666
- }),
- makeTestDominatorTreeNode({
- nodeId: 888,
- parentId: 666
- }),
-];
-
-const moreChildrenAvailable = false;
-
-const expected = {
- nodeId: 666,
- label: undefined,
- parentId: undefined,
- shallowSize: 1,
- retainedSize: 7,
- children: [
- {
- nodeId: 0,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 666,
- moreChildrenAvailable: true,
- children: undefined
- },
- {
- nodeId: 4,
- label: undefined,
- shallowSize: 1,
- retainedSize: 4,
- parentId: 666,
- children: [
- {
- nodeId: 1,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 4,
- moreChildrenAvailable: true,
- children: undefined
- },
- {
- nodeId: 2,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 4,
- moreChildrenAvailable: true,
- children: undefined
- },
- {
- nodeId: 3,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 4,
- moreChildrenAvailable: true,
- children: undefined
- }
- ],
- moreChildrenAvailable: true
- },
- {
- nodeId: 5,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 666,
- moreChildrenAvailable: true,
- children: undefined
- },
- {
- nodeId: 777,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 666,
- moreChildrenAvailable: true,
- children: undefined
- },
- {
- nodeId: 888,
- label: undefined,
- shallowSize: 1,
- retainedSize: 1,
- parentId: 666,
- moreChildrenAvailable: true,
- children: undefined
- }
- ],
- moreChildrenAvailable: false
-};
-
-function run_test() {
- assertDominatorTreeNodeInsertion(tree, path, newChildren, moreChildrenAvailable, expected);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_partialTraversal_01.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_partialTraversal_01.js
deleted file mode 100644
index 78ec47b64..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTreeNode_partialTraversal_01.js
+++ /dev/null
@@ -1,164 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we correctly set `moreChildrenAvailable` when doing a partial
-// traversal of a dominator tree to create the initial incrementally loaded
-// `DominatorTreeNode` tree.
-
-// `tree` maps parent to children:
-//
-// 100
-// |- 200
-// | |- 500
-// | |- 600
-// | `- 700
-// |- 300
-// | |- 800
-// | |- 900
-// `- 400
-// |- 1000
-// |- 1100
-// `- 1200
-const tree = new Map([
- [100, [200, 300, 400]],
- [200, [500, 600, 700]],
- [300, [800, 900]],
- [400, [1000, 1100, 1200]]
-]);
-
-const mockDominatorTree = {
- root: 100,
- getRetainedSize: _ => 10,
- getImmediatelyDominated: id => (tree.get(id) || []).slice()
-};
-
-const mockSnapshot = {
- describeNode: _ => ({
- objects: { count: 0, bytes: 0 },
- strings: { count: 0, bytes: 0 },
- scripts: { count: 0, bytes: 0 },
- other: { SomeType: { count: 1, bytes: 10 } }
- })
-};
-
-const breakdown = {
- by: "coarseType",
- objects: { by: "count", count: true, bytes: true },
- strings: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
- },
-};
-
-const expected = {
- nodeId: 100,
- label: [
- "other",
- "SomeType"
- ],
- shallowSize: 10,
- retainedSize: 10,
- shortestPaths: undefined,
- children: [
- {
- nodeId: 200,
- label: [
- "other",
- "SomeType"
- ],
- shallowSize: 10,
- retainedSize: 10,
- parentId: 100,
- shortestPaths: undefined,
- children: [
- {
- nodeId: 500,
- label: [
- "other",
- "SomeType"
- ],
- shallowSize: 10,
- retainedSize: 10,
- parentId: 200,
- moreChildrenAvailable: false,
- shortestPaths: undefined,
- children: undefined
- },
- {
- nodeId: 600,
- label: [
- "other",
- "SomeType"
- ],
- shallowSize: 10,
- retainedSize: 10,
- parentId: 200,
- moreChildrenAvailable: false,
- shortestPaths: undefined,
- children: undefined
- }
- ],
- moreChildrenAvailable: true
- },
- {
- nodeId: 300,
- label: [
- "other",
- "SomeType"
- ],
- shallowSize: 10,
- retainedSize: 10,
- parentId: 100,
- shortestPaths: undefined,
- children: [
- {
- nodeId: 800,
- label: [
- "other",
- "SomeType"
- ],
- shallowSize: 10,
- retainedSize: 10,
- parentId: 300,
- moreChildrenAvailable: false,
- shortestPaths: undefined,
- children: undefined
- },
- {
- nodeId: 900,
- label: [
- "other",
- "SomeType"
- ],
- shallowSize: 10,
- retainedSize: 10,
- parentId: 300,
- moreChildrenAvailable: false,
- shortestPaths: undefined,
- children: undefined
- }
- ],
- moreChildrenAvailable: false
- }
- ],
- moreChildrenAvailable: true,
- parentId: undefined,
-};
-
-function run_test() {
- // Traverse the whole depth of the test tree, but one short of the number of
- // siblings. This will exercise the moreChildrenAvailable handling for
- // siblings.
- const actual = DominatorTreeNode.partialTraversal(mockDominatorTree,
- mockSnapshot,
- breakdown,
- /* maxDepth = */ 4,
- /* siblings = */ 2);
-
- dumpn("Expected = " + JSON.stringify(expected, null, 2));
- dumpn("Actual = " + JSON.stringify(actual, null, 2));
-
- assertStructurallyEquivalent(expected, actual);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_01.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_01.js
deleted file mode 100644
index e8145f658..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_01.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Sanity test that we can compute dominator trees.
-
-function run_test() {
- const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
- const snapshot = ChromeUtils.readHeapSnapshot(path);
-
- const dominatorTree = snapshot.computeDominatorTree();
- ok(dominatorTree);
- ok(dominatorTree instanceof DominatorTree);
-
- let threw = false;
- try {
- new DominatorTree();
- } catch (e) {
- threw = true;
- }
- ok(threw, "Constructor shouldn't be usable");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_02.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_02.js
deleted file mode 100644
index a518f8a27..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_02.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can compute dominator trees from a snapshot in a worker.
-
-add_task(function* () {
- const worker = new ChromeWorker("resource://test/dominator-tree-worker.js");
- worker.postMessage({});
-
- let assertionCount = 0;
- worker.onmessage = e => {
- if (e.data.type !== "assertion") {
- return;
- }
-
- ok(e.data.passed, e.data.msg + "\n" + e.data.stack);
- assertionCount++;
- };
-
- yield waitForDone(worker);
-
- ok(assertionCount > 0);
- worker.terminate();
-});
-
-function waitForDone(w) {
- return new Promise((resolve, reject) => {
- w.onerror = e => {
- reject();
- ok(false, "Error in worker: " + e);
- };
-
- w.addEventListener("message", function listener(e) {
- if (e.data.type === "done") {
- w.removeEventListener("message", listener, false);
- resolve();
- }
- }, false);
- });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_03.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_03.js
deleted file mode 100644
index 0a14ce53d..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_03.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can get the root of dominator trees.
-
-function run_test() {
- const dominatorTree = saveHeapSnapshotAndComputeDominatorTree();
- equal(typeof dominatorTree.root, "number", "root should be a number");
- equal(Math.floor(dominatorTree.root), dominatorTree.root, "root should be an integer");
- ok(dominatorTree.root >= 0, "root should be positive");
- ok(dominatorTree.root <= Math.pow(2, 48), "root should be less than or equal to 2^48");
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_04.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_04.js
deleted file mode 100644
index e5aef3fec..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_04.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can get the retained sizes of dominator trees.
-
-function run_test() {
- const dominatorTree = saveHeapSnapshotAndComputeDominatorTree();
- equal(typeof dominatorTree.getRetainedSize, "function",
- "getRetainedSize should be a function");
-
- const size = dominatorTree.getRetainedSize(dominatorTree.root);
- ok(size, "should get a size for the root");
- equal(typeof size, "number", "retained sizes should be a number");
- equal(Math.floor(size), size, "size should be an integer");
- ok(size > 0, "size should be positive");
- ok(size <= Math.pow(2, 64), "size should be less than or equal to 2^64");
-
- const bad = dominatorTree.getRetainedSize(1);
- equal(bad, null, "null is returned for unknown node ids");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_05.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_05.js
deleted file mode 100644
index c07cee994..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_05.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can get the set of immediately dominated nodes for any given
-// node and that this forms a tree.
-
-function run_test() {
- var dominatorTree = saveHeapSnapshotAndComputeDominatorTree();
- equal(typeof dominatorTree.getImmediatelyDominated, "function",
- "getImmediatelyDominated should be a function");
-
- // Do a traversal of the dominator tree.
- //
- // Note that we don't assert directly, only if we get an unexpected
- // value. There are just way too many nodes in the heap graph to assert for
- // every one. This test would constantly time out and assertion messages would
- // overflow the log size.
-
- var root = dominatorTree.root;
- equal(dominatorTree.getImmediateDominator(root), null,
- "The root should not have a parent");
-
- var seen = new Set();
- var stack = [root];
- while (stack.length > 0) {
- var top = stack.pop();
-
- if (seen.has(top)) {
- ok(false,
- "This is a tree, not a graph: we shouldn't have multiple edges to the same node");
- }
- seen.add(top);
- if (seen.size % 1000 === 0) {
- dumpn("Progress update: seen size = " + seen.size);
- }
-
- var newNodes = dominatorTree.getImmediatelyDominated(top);
- if (Object.prototype.toString.call(newNodes) !== "[object Array]") {
- ok(false, "getImmediatelyDominated should return an array for known node ids");
- }
-
- var topSize = dominatorTree.getRetainedSize(top);
-
- var lastSize = Infinity;
- for (var i = 0; i < newNodes.length; i++) {
- if (typeof newNodes[i] !== "number") {
- ok(false, "Every dominated id should be a number");
- }
-
- if (dominatorTree.getImmediateDominator(newNodes[i]) !== top) {
- ok(false, "child's parent should be the expected parent");
- }
-
- var thisSize = dominatorTree.getRetainedSize(newNodes[i]);
-
- if (thisSize >= topSize) {
- ok(false, "the size of children in the dominator tree should always be less than that of their parent");
- }
-
- if (thisSize > lastSize) {
- ok(false,
- "children should be sorted by greatest to least retained size, "
- + "lastSize = " + lastSize + ", thisSize = " + thisSize);
- }
-
- lastSize = thisSize;
- stack.push(newNodes[i]);
- }
- }
-
- ok(true, "Successfully walked the tree");
- dumpn("Walked " + seen.size + " nodes");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_06.js b/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_06.js
deleted file mode 100644
index 680478623..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_DominatorTree_06.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the retained size of a node is the sum of its children retained
-// sizes plus its shallow size.
-
-// Note that we don't assert directly, only if we get an unexpected
-// value. There are just way too many nodes in the heap graph to assert for
-// every one. This test would constantly time out and assertion messages would
-// overflow the log size.
-function fastAssert(cond, msg) {
- if (!cond) {
- ok(false, msg);
- }
-}
-
-var COUNT = { by: "count", count: false, bytes: true };
-
-function run_test() {
- var path = saveNewHeapSnapshot();
- var snapshot = ChromeUtils.readHeapSnapshot(path);
- var dominatorTree = snapshot.computeDominatorTree();
-
- // Do a traversal of the dominator tree and assert the relationship between
- // retained size, shallow size, and children's retained sizes.
-
- var root = dominatorTree.root;
- var stack = [root];
- while (stack.length > 0) {
- var top = stack.pop();
-
- var children = dominatorTree.getImmediatelyDominated(top);
-
- var topRetainedSize = dominatorTree.getRetainedSize(top);
- var topShallowSize = snapshot.describeNode(COUNT, top).bytes;
- fastAssert(topShallowSize <= topRetainedSize,
- "The shallow size should be less than or equal to the " +
- "retained size");
-
- var sumOfChildrensRetainedSizes = 0;
- for (var i = 0; i < children.length; i++) {
- sumOfChildrensRetainedSizes += dominatorTree.getRetainedSize(children[i]);
- stack.push(children[i]);
- }
-
- fastAssert(sumOfChildrensRetainedSizes <= topRetainedSize,
- "The sum of the children's retained sizes should be less than " +
- "or equal to the retained size");
- fastAssert(sumOfChildrensRetainedSizes + topShallowSize === topRetainedSize,
- "The sum of the children's retained sizes plus the shallow " +
- "size should be equal to the retained size");
- }
-
- ok(true, "Successfully walked the tree");
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_01.js
deleted file mode 100644
index 0114e0b69..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_01.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the HeapAnalyses{Client,Worker} "computeDominatorTree" request.
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const dominatorTreeId = yield client.computeDominatorTree(snapshotFilePath);
- equal(typeof dominatorTreeId, "number",
- "should get a dominator tree id, and it should be a number");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_02.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_02.js
deleted file mode 100644
index 6e3f5b257..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_computeDominatorTree_02.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the HeapAnalyses{Client,Worker} "computeDominatorTree" request with bad
-// file paths.
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- let threw = false;
- try {
- yield client.computeDominatorTree("/etc/passwd");
- } catch (_) {
- threw = true;
- }
- ok(threw, "should throw when given a bad path");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_01.js
deleted file mode 100644
index 7708de93c..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_01.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can delete heap snapshots.
-
-function run_test() {
- run_next_test();
-}
-
-const breakdown = {
- by: "coarseType",
- objects: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- strings: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- let dominatorTreeId = yield client.computeDominatorTree(snapshotFilePath);
- ok(true, "Should have computed the dominator tree");
-
- yield client.deleteHeapSnapshot(snapshotFilePath);
- ok(true, "Should have deleted the snapshot");
-
- let threw = false;
- try {
- yield client.getDominatorTree({
- dominatorTreeId: dominatorTreeId,
- breakdown
- });
- } catch (_) {
- threw = true;
- }
- ok(threw, "getDominatorTree on deleted tree should throw an error");
-
- threw = false;
- try {
- yield client.computeDominatorTree(snapshotFilePath);
- } catch (_) {
- threw = true;
- }
- ok(threw, "computeDominatorTree on deleted snapshot should throw an error");
-
- threw = false;
- try {
- yield client.takeCensus(snapshotFilePath);
- } catch (_) {
- threw = true;
- }
- ok(threw, "takeCensus on deleted tree should throw an error");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_02.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_02.js
deleted file mode 100644
index 3e25ddac4..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_02.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test deleteHeapSnapshot is a noop if the provided path matches no snapshot
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- let threw = false;
- try {
- yield client.deleteHeapSnapshot("path-does-not-exist");
- } catch (_) {
- threw = true;
- }
- ok(threw, "deleteHeapSnapshot on non-existant path should throw an error");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_03.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_03.js
deleted file mode 100644
index e648c9407..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_deleteHeapSnapshot_03.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test other dominatorTrees can still be retrieved after deleting a snapshot
-
-function run_test() {
- run_next_test();
-}
-
-const breakdown = {
- by: "coarseType",
- objects: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- strings: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
-};
-
-function* createSnapshotAndDominatorTree(client) {
- let snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- let dominatorTreeId = yield client.computeDominatorTree(snapshotFilePath);
- return { dominatorTreeId, snapshotFilePath };
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- let savedSnapshots = [
- yield createSnapshotAndDominatorTree(client),
- yield createSnapshotAndDominatorTree(client),
- yield createSnapshotAndDominatorTree(client)
- ];
- ok(true, "Create 3 snapshots and dominator trees");
-
- yield client.deleteHeapSnapshot(savedSnapshots[1].snapshotFilePath);
- ok(true, "Snapshot deleted");
-
- let tree = yield client.getDominatorTree({
- dominatorTreeId: savedSnapshots[0].dominatorTreeId,
- breakdown
- });
- ok(tree, "Should get a valid tree for first snapshot");
-
- let threw = false;
- try {
- yield client.getDominatorTree({
- dominatorTreeId: savedSnapshots[1].dominatorTreeId,
- breakdown
- });
- } catch (_) {
- threw = true;
- }
- ok(threw, "getDominatorTree on a deleted snapshot should throw an error");
-
- tree = yield client.getDominatorTree({
- dominatorTreeId: savedSnapshots[2].dominatorTreeId,
- breakdown
- });
- ok(tree, "Should get a valid tree for third snapshot");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCensusIndividuals_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCensusIndividuals_01.js
deleted file mode 100644
index b63ad4230..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCensusIndividuals_01.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can get census individuals.
-
-function run_test() {
- run_next_test();
-}
-
-const COUNT = { by: "count", count: true, bytes: true };
-
-const CENSUS_BREAKDOWN = {
- by: "coarseType",
- objects: COUNT,
- strings: COUNT,
- scripts: COUNT,
- other: COUNT,
-};
-
-const LABEL_BREAKDOWN = {
- by: "internalType",
- then: COUNT,
-};
-
-const MAX_INDIVIDUALS = 10;
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const dominatorTreeId = yield client.computeDominatorTree(snapshotFilePath);
- ok(true, "Should have computed dominator tree");
-
- const { report } = yield client.takeCensus(snapshotFilePath,
- { breakdown: CENSUS_BREAKDOWN },
- { asTreeNode: true });
- ok(report, "Should get a report");
-
- let nodesWithLeafIndicesFound = 0;
-
- yield* (function* assertCanGetIndividuals(censusNode) {
- if (censusNode.reportLeafIndex !== undefined) {
- nodesWithLeafIndicesFound++;
-
- const response = yield client.getCensusIndividuals({
- dominatorTreeId,
- indices: DevToolsUtils.isSet(censusNode.reportLeafIndex)
- ? censusNode.reportLeafIndex
- : new Set([censusNode.reportLeafIndex]),
- censusBreakdown: CENSUS_BREAKDOWN,
- labelBreakdown: LABEL_BREAKDOWN,
- maxRetainingPaths: 1,
- maxIndividuals: MAX_INDIVIDUALS,
- });
-
- dumpn(`response = ${JSON.stringify(response, null, 4)}`);
-
- equal(response.nodes.length, Math.min(MAX_INDIVIDUALS, censusNode.count),
- "response.nodes.length === Math.min(MAX_INDIVIDUALS, censusNode.count)");
-
- let lastRetainedSize = Infinity;
- for (let individual of response.nodes) {
- equal(typeof individual.nodeId, "number",
- "individual.nodeId should be a number");
- ok(individual.retainedSize <= lastRetainedSize,
- "individual.retainedSize <= lastRetainedSize");
- lastRetainedSize = individual.retainedSize;
- ok(individual.shallowSize, "individual.shallowSize should exist and be non-zero");
- ok(individual.shortestPaths, "individual.shortestPaths should exist");
- ok(individual.shortestPaths.nodes, "individual.shortestPaths.nodes should exist");
- ok(individual.shortestPaths.edges, "individual.shortestPaths.edges should exist");
- ok(individual.label, "individual.label should exist");
- }
- }
-
- if (censusNode.children) {
- for (let child of censusNode.children) {
- yield* assertCanGetIndividuals(child);
- }
- }
- }(report));
-
- equal(nodesWithLeafIndicesFound, 4, "Should have found a leaf for each coarse type");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCreationTime_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCreationTime_01.js
deleted file mode 100644
index 5df79de7a..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getCreationTime_01.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can get a HeapSnapshot's
-// creation time.
-
-function waitForThirtyMilliseconds() {
- const start = Date.now();
- while (Date.now() - start < 30) ;
-}
-
-function run_test() {
- run_next_test();
-}
-
-const BREAKDOWN = {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
- const start = Date.now() * 1000;
-
- // Because Date.now() is less precise than the snapshot's time stamp, give it
- // a little bit of head room. Additionally, WinXP's timers have a granularity
- // of only +/-15 ms.
- waitForThirtyMilliseconds();
- const snapshotFilePath = saveNewHeapSnapshot();
- waitForThirtyMilliseconds();
- const end = Date.now() * 1000;
-
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- let threw = false;
- try {
- yield client.getCreationTime("/not/a/real/path", {
- breakdown: BREAKDOWN
- });
- } catch (_) {
- threw = true;
- }
- ok(threw, "getCreationTime should throw when snapshot does not exist");
-
- let time = yield client.getCreationTime(snapshotFilePath, {
- breakdown: BREAKDOWN
- });
-
- dumpn("Start = " + start);
- dumpn("End = " + end);
- dumpn("Time = " + time);
-
- ok(time >= start, "creation time occurred after start");
- ok(time <= end, "creation time occurred before end");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_01.js
deleted file mode 100644
index cedea5375..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_01.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the HeapAnalyses{Client,Worker} "getDominatorTree" request.
-
-function run_test() {
- run_next_test();
-}
-
-const breakdown = {
- by: "coarseType",
- objects: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- strings: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const dominatorTreeId = yield client.computeDominatorTree(snapshotFilePath);
- equal(typeof dominatorTreeId, "number",
- "should get a dominator tree id, and it should be a number");
-
- const partialTree = yield client.getDominatorTree({
- dominatorTreeId,
- breakdown
- });
- ok(partialTree, "Should get a partial tree");
- equal(typeof partialTree, "object",
- "partialTree should be an object");
-
- function checkTree(node) {
- equal(typeof node.nodeId, "number", "each node should have an id");
-
- if (node === partialTree) {
- equal(node.parentId, undefined, "the root has no parent");
- } else {
- equal(typeof node.parentId, "number", "each node should have a parent id");
- }
-
- equal(typeof node.retainedSize, "number",
- "each node should have a retained size");
-
- ok(node.children === undefined || Array.isArray(node.children),
- "each node either has a list of children, or undefined meaning no children loaded");
- equal(typeof node.moreChildrenAvailable, "boolean",
- "each node should indicate if there are more children available or not");
-
- equal(typeof node.shortestPaths, "object",
- "Should have shortest paths");
- equal(typeof node.shortestPaths.nodes, "object",
- "Should have shortest paths' nodes");
- equal(typeof node.shortestPaths.edges, "object",
- "Should have shortest paths' edges");
-
- if (node.children) {
- node.children.forEach(checkTree);
- }
- }
-
- checkTree(partialTree);
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_02.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_02.js
deleted file mode 100644
index fd29beece..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getDominatorTree_02.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the HeapAnalyses{Client,Worker} "getDominatorTree" request with bad
-// dominator tree ids.
-
-function run_test() {
- run_next_test();
-}
-
-const breakdown = {
- by: "coarseType",
- objects: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- strings: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- let threw = false;
- try {
- yield client.getDominatorTree({ dominatorTreeId: 42, breakdown });
- } catch (_) {
- threw = true;
- }
- ok(threw, "should throw when given a bad id");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getImmediatelyDominated_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getImmediatelyDominated_01.js
deleted file mode 100644
index caf1c2056..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_getImmediatelyDominated_01.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the HeapAnalyses{Client,Worker} "getImmediatelyDominated" request.
-
-function run_test() {
- run_next_test();
-}
-
-const breakdown = {
- by: "coarseType",
- objects: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- strings: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- const dominatorTreeId = yield client.computeDominatorTree(snapshotFilePath);
-
- const partialTree = yield client.getDominatorTree({
- dominatorTreeId,
- breakdown
- });
- ok(partialTree.children.length > 0,
- "root should immediately dominate some nodes");
-
- // First, test getting a subset of children available.
- const response = yield client.getImmediatelyDominated({
- dominatorTreeId,
- breakdown,
- nodeId: partialTree.nodeId,
- startIndex: 0,
- maxCount: partialTree.children.length - 1
- });
-
- ok(Array.isArray(response.nodes));
- ok(response.nodes.every(node => node.parentId === partialTree.nodeId));
- ok(response.moreChildrenAvailable);
- equal(response.path.length, 1);
- equal(response.path[0], partialTree.nodeId);
-
- for (let node of response.nodes) {
- equal(typeof node.shortestPaths, "object",
- "Should have shortest paths");
- equal(typeof node.shortestPaths.nodes, "object",
- "Should have shortest paths' nodes");
- equal(typeof node.shortestPaths.edges, "object",
- "Should have shortest paths' edges");
- }
-
- // Next, test getting a subset of children available.
- const secondResponse = yield client.getImmediatelyDominated({
- dominatorTreeId,
- breakdown,
- nodeId: partialTree.nodeId,
- startIndex: 0,
- maxCount: Infinity
- });
-
- ok(Array.isArray(secondResponse.nodes));
- ok(secondResponse.nodes.every(node => node.parentId === partialTree.nodeId));
- ok(!secondResponse.moreChildrenAvailable);
- equal(secondResponse.path.length, 1);
- equal(secondResponse.path[0], partialTree.nodeId);
-
- for (let node of secondResponse.nodes) {
- equal(typeof node.shortestPaths, "object",
- "Should have shortest paths");
- equal(typeof node.shortestPaths.nodes, "object",
- "Should have shortest paths' nodes");
- equal(typeof node.shortestPaths.edges, "object",
- "Should have shortest paths' edges");
- }
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_readHeapSnapshot_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_readHeapSnapshot_01.js
deleted file mode 100644
index 0d0d58bef..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_readHeapSnapshot_01.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can read heap snapshots.
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_01.js
deleted file mode 100644
index 6f22cbad3..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_01.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can take diffs between censuses.
-
-function run_test() {
- run_next_test();
-}
-
-const BREAKDOWN = {
- by: "objectClass",
- then: { by: "count", count: true, bytes: false },
- other: { by: "count", count: true, bytes: false },
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const markers = [allocationMarker()];
-
- const firstSnapshotFilePath = saveNewHeapSnapshot();
-
- // Allocate and hold an additional AllocationMarker object so we can see it in
- // the next heap snapshot.
- markers.push(allocationMarker());
-
- const secondSnapshotFilePath = saveNewHeapSnapshot();
-
- yield client.readHeapSnapshot(firstSnapshotFilePath);
- yield client.readHeapSnapshot(secondSnapshotFilePath);
- ok(true, "Should have read both heap snapshot files");
-
- const { delta } = yield client.takeCensusDiff(firstSnapshotFilePath,
- secondSnapshotFilePath,
- { breakdown: BREAKDOWN });
-
- equal(delta.AllocationMarker.count, 1,
- "There exists one new AllocationMarker in the second heap snapshot");
-
- const { delta: deltaTreeNode } = yield client.takeCensusDiff(firstSnapshotFilePath,
- secondSnapshotFilePath,
- { breakdown: BREAKDOWN },
- { asTreeNode: true });
-
- // Have to manually set these because symbol properties aren't structured
- // cloned.
- delta[CensusUtils.basisTotalBytes] = deltaTreeNode.totalBytes;
- delta[CensusUtils.basisTotalCount] = deltaTreeNode.totalCount;
-
- compareCensusViewData(BREAKDOWN, delta, deltaTreeNode,
- "Returning delta-census as a tree node represents same data as the report");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_02.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_02.js
deleted file mode 100644
index f1ba9ce84..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensusDiff_02.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can take diffs between censuses as
-// inverted trees.
-
-function run_test() {
- run_next_test();
-}
-
-const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
-};
-
-add_task(function* () {
- const firstSnapshotFilePath = saveNewHeapSnapshot();
- const secondSnapshotFilePath = saveNewHeapSnapshot();
-
- const client = new HeapAnalysesClient();
- yield client.readHeapSnapshot(firstSnapshotFilePath);
- yield client.readHeapSnapshot(secondSnapshotFilePath);
-
- ok(true, "Should have read both heap snapshot files");
-
- const { delta } = yield client.takeCensusDiff(firstSnapshotFilePath,
- secondSnapshotFilePath,
- { breakdown: BREAKDOWN });
-
- const { delta: deltaTreeNode } = yield client.takeCensusDiff(firstSnapshotFilePath,
- secondSnapshotFilePath,
- { breakdown: BREAKDOWN },
- { asInvertedTreeNode: true });
-
- // Have to manually set these because symbol properties aren't structured
- // cloned.
- delta[CensusUtils.basisTotalBytes] = deltaTreeNode.totalBytes;
- delta[CensusUtils.basisTotalCount] = deltaTreeNode.totalCount;
-
- compareCensusViewData(BREAKDOWN, delta, deltaTreeNode, { invert: true });
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_01.js
deleted file mode 100644
index e26981db4..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_01.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can take censuses.
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const { report } = yield client.takeCensus(snapshotFilePath);
- ok(report, "Should get a report");
- equal(typeof report, "object", "report should be an object");
-
- ok(report.objects);
- ok(report.scripts);
- ok(report.strings);
- ok(report.other);
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_02.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_02.js
deleted file mode 100644
index 34494af70..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_02.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can take censuses with breakdown
-// options.
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const { report } = yield client.takeCensus(snapshotFilePath, {
- breakdown: { by: "count", count: true, bytes: true }
- });
-
- ok(report, "Should get a report");
- equal(typeof report, "object", "report should be an object");
-
- ok(report.count);
- ok(report.bytes);
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_03.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_03.js
deleted file mode 100644
index 486e250b5..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_03.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} bubbles errors properly when things
-// go wrong.
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- // Snapshot file path to a file that doesn't exist.
- let failed = false;
- try {
- yield client.readHeapSnapshot(getFilePath("foo-bar-baz" + Math.random(), true));
- } catch (e) {
- failed = true;
- }
- ok(failed, "should not read heap snapshots that do not exist");
-
- // Snapshot file path to a file that is not a heap snapshot.
- failed = false;
- try {
- yield client.readHeapSnapshot(getFilePath("test_HeapAnalyses_takeCensus_03.js"));
- } catch (e) {
- failed = true;
- }
- ok(failed, "should not be able to read a file that is not a heap snapshot as a heap snapshot");
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- // Bad census breakdown options.
- failed = false;
- try {
- yield client.takeCensus(snapshotFilePath, {
- breakdown: { by: "some classification that we do not have" }
- });
- } catch (e) {
- failed = true;
- }
- ok(failed, "should not be able to breakdown by an unknown classification");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_04.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_04.js
deleted file mode 100644
index 769a2d99d..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_04.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can send SavedFrame stacks from
-// by-allocation-stack reports from the worker.
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* test() {
- const client = new HeapAnalysesClient();
-
- // Track some allocation stacks.
-
- const g = newGlobal();
- const dbg = new Debugger(g);
- g.eval(` // 1
- this.log = []; // 2
- function f() { this.log.push(allocationMarker()); } // 3
- function g() { this.log.push(allocationMarker()); } // 4
- function h() { this.log.push(allocationMarker()); } // 5
- `); // 6
-
- // Create one allocationMarker with tracking turned off,
- // so it will have no associated stack.
- g.f();
-
- dbg.memory.allocationSamplingProbability = 1;
-
- for (let [func, n] of [ [g.f, 20],
- [g.g, 10],
- [g.h, 5] ]) {
- for (let i = 0; i < n; i++) {
- dbg.memory.trackingAllocationSites = true;
- // All allocations of allocationMarker occur with this line as the oldest
- // stack frame.
- func();
- dbg.memory.trackingAllocationSites = false;
- }
- }
-
- // Take a heap snapshot.
-
- const snapshotFilePath = saveNewHeapSnapshot({ debugger: dbg });
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- // Run a census broken down by class name -> allocation stack so we can grab
- // only the AllocationMarker objects we have complete control over.
-
- const { report } = yield client.takeCensus(snapshotFilePath, {
- breakdown: { by: "objectClass",
- then: { by: "allocationStack",
- then: { by: "count",
- bytes: true,
- count: true
- },
- noStack: { by: "count",
- bytes: true,
- count: true
- }
- }
- }
- });
-
- // Test the generated report.
-
- ok(report, "Should get a report");
-
- const map = report.AllocationMarker;
- ok(map, "Should get AllocationMarkers in the report.");
- // From a module with a different global, and therefore a different Map
- // constructor, so we can't use instanceof.
- equal(map.__proto__.constructor.name, "Map");
-
- equal(map.size, 4, "Should have 4 allocation stacks (including the lack of a stack)");
-
- // Gather the stacks we are expecting to appear as keys, and
- // check that there are no unexpected keys.
- let stacks = {};
-
- map.forEach((v, k) => {
- if (k === "noStack") {
- // No need to save this key.
- } else if (k.functionDisplayName === "f" &&
- k.parent.functionDisplayName === "test") {
- stacks.f = k;
- } else if (k.functionDisplayName === "g" &&
- k.parent.functionDisplayName === "test") {
- stacks.g = k;
- } else if (k.functionDisplayName === "h" &&
- k.parent.functionDisplayName === "test") {
- stacks.h = k;
- } else {
- dumpn("Unexpected allocation stack:");
- k.toString().split(/\n/g).forEach(s => dumpn(s));
- ok(false);
- }
- });
-
- ok(map.get("noStack"));
- equal(map.get("noStack").count, 1);
-
- ok(stacks.f);
- ok(map.get(stacks.f));
- equal(map.get(stacks.f).count, 20);
-
- ok(stacks.g);
- ok(map.get(stacks.g));
- equal(map.get(stacks.g).count, 10);
-
- ok(stacks.h);
- ok(map.get(stacks.h));
- equal(map.get(stacks.h).count, 5);
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_05.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_05.js
deleted file mode 100644
index 7e16d9f00..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_05.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can take censuses and return
-// a CensusTreeNode.
-
-function run_test() {
- run_next_test();
-}
-
-const BREAKDOWN = {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const { report } = yield client.takeCensus(snapshotFilePath, {
- breakdown: BREAKDOWN
- });
-
- const { report: treeNode } = yield client.takeCensus(snapshotFilePath, {
- breakdown: BREAKDOWN
- }, {
- asTreeNode: true
- });
-
- ok(treeNode.children.length > 0, "treeNode has children");
- ok(treeNode.children.every(type => {
- return "name" in type &&
- "bytes" in type &&
- "count" in type;
- }), "all of tree node's children have name, bytes, count");
-
- compareCensusViewData(BREAKDOWN, report, treeNode,
- "Returning census as a tree node represents same data as the report");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_06.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_06.js
deleted file mode 100644
index 7795a9700..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_06.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can take censuses by
-// "allocationStack" and return a CensusTreeNode.
-
-function run_test() {
- run_next_test();
-}
-
-const BREAKDOWN = {
- by: "objectClass",
- then: {
- by: "allocationStack",
- then: { by: "count", count: true, bytes: true },
- noStack: { by: "count", count: true, bytes: true }
- },
- other: { by: "count", count: true, bytes: true }
-};
-
-add_task(function* () {
- const g = newGlobal();
- const dbg = new Debugger(g);
-
- // 5 allocation markers with no stack.
- g.eval(`
- this.markers = [];
- for (var i = 0; i < 5; i++) {
- markers.push(allocationMarker());
- }
- `);
-
- dbg.memory.allocationSamplingProbability = 1;
- dbg.memory.trackingAllocationSites = true;
-
- // 5 allocation markers at 5 stacks.
- g.eval(`
- (function shouldHaveCountOfOne() {
- markers.push(allocationMarker());
- markers.push(allocationMarker());
- markers.push(allocationMarker());
- markers.push(allocationMarker());
- markers.push(allocationMarker());
- }());
- `);
-
- // 5 allocation markers at 1 stack.
- g.eval(`
- (function shouldHaveCountOfFive() {
- for (var i = 0; i < 5; i++) {
- markers.push(allocationMarker());
- }
- }());
- `);
-
- const snapshotFilePath = saveNewHeapSnapshot({ debugger: dbg });
-
- const client = new HeapAnalysesClient();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const { report } = yield client.takeCensus(snapshotFilePath, {
- breakdown: BREAKDOWN
- });
-
- const { report: treeNode } = yield client.takeCensus(snapshotFilePath, {
- breakdown: BREAKDOWN
- }, {
- asTreeNode: true
- });
-
- const markers = treeNode.children.find(c => c.name === "AllocationMarker");
- ok(markers);
-
- const noStack = markers.children.find(c => c.name === "noStack");
- equal(noStack.count, 5);
-
- let numShouldHaveFiveFound = 0;
- let numShouldHaveOneFound = 0;
-
- function walk(node) {
- if (node.children) {
- node.children.forEach(walk);
- }
-
- if (!isSavedFrame(node.name)) {
- return;
- }
-
- if (node.name.functionDisplayName === "shouldHaveCountOfFive") {
- equal(node.count, 5, "shouldHaveCountOfFive should have count of five");
- numShouldHaveFiveFound++;
- }
-
- if (node.name.functionDisplayName === "shouldHaveCountOfOne") {
- equal(node.count, 1, "shouldHaveCountOfOne should have count of one");
- numShouldHaveOneFound++;
- }
- }
- markers.children.forEach(walk);
-
- equal(numShouldHaveFiveFound, 1);
- equal(numShouldHaveOneFound, 5);
-
- compareCensusViewData(BREAKDOWN, report, treeNode,
- "Returning census as a tree node represents same data as the report");
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_07.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_07.js
deleted file mode 100644
index 986b3aaa8..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapAnalyses_takeCensus_07.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the HeapAnalyses{Client,Worker} can take censuses and return
-// an inverted CensusTreeNode.
-
-function run_test() {
- run_next_test();
-}
-
-const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
-};
-
-add_task(function* () {
- const client = new HeapAnalysesClient();
-
- const snapshotFilePath = saveNewHeapSnapshot();
- yield client.readHeapSnapshot(snapshotFilePath);
- ok(true, "Should have read the heap snapshot");
-
- const { report } = yield client.takeCensus(snapshotFilePath, {
- breakdown: BREAKDOWN
- });
-
- const { report: treeNode } = yield client.takeCensus(snapshotFilePath, {
- breakdown: BREAKDOWN
- }, {
- asInvertedTreeNode: true
- });
-
- compareCensusViewData(BREAKDOWN, report, treeNode, { invert: true });
-
- client.destroy();
-});
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_01.js
deleted file mode 100644
index 2ec577bd0..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_01.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Sanity test that we can compute shortest paths.
-//
-// Because the actual heap graph is too unpredictable and likely to drastically
-// change as various implementation bits change, we don't test exact paths
-// here. See js/src/jsapi-tests/testUbiNode.cpp for such tests, where we can
-// control the specific graph shape and structure and so testing exact paths is
-// reliable.
-
-function run_test() {
- const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
- const snapshot = ChromeUtils.readHeapSnapshot(path);
-
- const dominatorTree = snapshot.computeDominatorTree();
- const dominatedByRoot = dominatorTree.getImmediatelyDominated(dominatorTree.root)
- .slice(0, 10);
- ok(dominatedByRoot);
- ok(dominatedByRoot.length);
-
- const targetSet = new Set(dominatedByRoot);
-
- const shortestPaths = snapshot.computeShortestPaths(dominatorTree.root, dominatedByRoot, 2);
- ok(shortestPaths);
- ok(shortestPaths instanceof Map);
- ok(shortestPaths.size === targetSet.size);
-
- for (let [target, paths] of shortestPaths) {
- ok(targetSet.has(target),
- "We should only get paths for our targets");
- targetSet.delete(target);
-
- ok(paths.length > 0,
- "We must have at least one path, since the target is dominated by the root");
- ok(paths.length <= 2,
- "Should not have recorded more paths than the max requested");
-
- dumpn("---------------------");
- dumpn("Shortest paths for 0x" + target.toString(16) + ":");
- for (let path of paths) {
- dumpn(" path =");
- for (let part of path) {
- dumpn(" predecessor: 0x" + part.predecessor.toString(16) +
- "; edge: " + part.edge);
- }
- }
- dumpn("---------------------");
-
- for (let path of paths) {
- ok(path.length > 0, "Cannot have zero length paths");
- ok(path[0].predecessor === dominatorTree.root,
- "The first predecessor is always our start node");
-
- for (let part of path) {
- ok(part.predecessor, "Each part of a path has a predecessor");
- ok(!!snapshot.describeNode({ by: "count", count: true, bytes: true},
- part.predecessor),
- "The predecessor is in the heap snapshot");
- ok("edge" in part, "Each part has an (potentially null) edge property");
- }
- }
- }
-
- ok(targetSet.size === 0,
- "We found paths for all of our targets");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_02.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_02.js
deleted file mode 100644
index 04fe58733..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_computeShortestPaths_02.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test computing shortest paths with invalid arguments.
-
-function run_test() {
- const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
- const snapshot = ChromeUtils.readHeapSnapshot(path);
-
- const dominatorTree = snapshot.computeDominatorTree();
- const target = dominatorTree.getImmediatelyDominated(dominatorTree.root).pop();
- ok(target);
-
- let threw = false;
- try {
- snapshot.computeShortestPaths(0, [target], 2);
- } catch (_) {
- threw = true;
- }
- ok(threw, "invalid start node should throw");
-
- threw = false;
- try {
- snapshot.computeShortestPaths(dominatorTree.root, [0], 2);
- } catch (_) {
- threw = true;
- }
- ok(threw, "invalid target nodes should throw");
-
- threw = false;
- try {
- snapshot.computeShortestPaths(dominatorTree.root, [], 2);
- } catch (_) {
- threw = true;
- }
- ok(threw, "empty target nodes should throw");
-
- threw = false;
- try {
- snapshot.computeShortestPaths(dominatorTree.root, [target], 0);
- } catch (_) {
- threw = true;
- }
- ok(threw, "0 max paths should throw");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_creationTime_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_creationTime_01.js
deleted file mode 100644
index 0d08fea16..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_creationTime_01.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// HeapSnapshot.prototype.creationTime returns the expected time.
-
-function waitForThirtyMilliseconds() {
- const start = Date.now();
- while (Date.now() - start < 30) ;
-}
-
-function run_test() {
- const start = Date.now() * 1000;
- do_print("start = " + start);
-
- // Because Date.now() is less precise than the snapshot's time stamp, give it
- // a little bit of head room. Additionally, WinXP's timer only has granularity
- // of +/- 15ms.
- waitForThirtyMilliseconds();
- const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
- waitForThirtyMilliseconds();
-
- const end = Date.now() * 1000;
- do_print("end = " + end);
-
- const snapshot = ChromeUtils.readHeapSnapshot(path);
- do_print("snapshot.creationTime = " + snapshot.creationTime);
-
- ok(snapshot.creationTime >= start);
- ok(snapshot.creationTime <= end);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_deepStack_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_deepStack_01.js
deleted file mode 100644
index 9eb11d9af..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_deepStack_01.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can save a core dump with very deep allocation stacks and read
-// it back into a HeapSnapshot.
-
-function stackDepth(stack) {
- return stack ? 1 + stackDepth(stack.parent) : 0;
-}
-
-function run_test() {
- // Create a Debugger observing a debuggee's allocations.
- const debuggee = new Cu.Sandbox(null);
- const dbg = new Debugger(debuggee);
- dbg.memory.trackingAllocationSites = true;
-
- // Allocate some objects in the debuggee that will have their allocation
- // stacks recorded by the Debugger.
-
- debuggee.eval("this.objects = []");
- debuggee.eval(
- (function recursiveAllocate(n) {
- if (n <= 0)
- return;
-
- // Make sure to recurse before pushing the object so that when TCO is
- // implemented sometime in the future, it doesn't invalidate this test.
- recursiveAllocate(n - 1);
- this.objects.push({});
- }).toString()
- );
- debuggee.eval("recursiveAllocate = recursiveAllocate.bind(this);");
- debuggee.eval("recursiveAllocate(200);");
-
- // Now save a snapshot that will include the allocation stacks and read it
- // back again.
-
- const filePath = ChromeUtils.saveHeapSnapshot({ runtime: true });
- ok(true, "Should be able to save a snapshot.");
-
- const snapshot = ChromeUtils.readHeapSnapshot(filePath);
- ok(snapshot, "Should be able to read a heap snapshot");
- ok(snapshot instanceof HeapSnapshot, "Should be an instanceof HeapSnapshot");
-
- const report = snapshot.takeCensus({
- breakdown: { by: "allocationStack",
- then: { by: "count", bytes: true, count: true },
- noStack: { by: "count", bytes: true, count: true }
- }
- });
-
- // Keep this synchronized with `HeapSnapshot::MAX_STACK_DEPTH`!
- const MAX_STACK_DEPTH = 60;
-
- let foundStacks = false;
- report.forEach((v, k) => {
- if (k === "noStack") {
- return;
- }
-
- foundStacks = true;
- const depth = stackDepth(k);
- dumpn("Stack depth is " + depth);
- ok(depth <= MAX_STACK_DEPTH,
- "Every stack should have depth less than or equal to the maximum stack depth");
- });
- ok(foundStacks);
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_describeNode_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_describeNode_01.js
deleted file mode 100644
index d79cb5a7b..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_describeNode_01.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can describe nodes with a breakdown.
-
-function run_test() {
- const path = saveNewHeapSnapshot();
- const snapshot = ChromeUtils.readHeapSnapshot(path);
- ok(snapshot.describeNode);
- equal(typeof snapshot.describeNode, "function");
-
- const dt = snapshot.computeDominatorTree();
-
- let threw = false;
- try {
- snapshot.describeNode(undefined, dt.root);
- } catch (_) {
- threw = true;
- }
- ok(threw, "Should require a breakdown");
-
- const breakdown = {
- by: "coarseType",
- objects: { by: "objectClass" },
- scripts: { by: "internalType" },
- strings: { by: "internalType" },
- other: { by: "internalType" }
- };
-
- threw = false;
- try {
- snapshot.describeNode(breakdown, 0);
- } catch (_) {
- threw = true;
- }
- ok(threw, "Should throw when given an invalid node id");
-
- const description = snapshot.describeNode(breakdown, dt.root);
- ok(description);
- ok(description.other);
- ok(description.other["JS::ubi::RootList"]);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_01.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_01.js
deleted file mode 100644
index f3b3090b0..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_01.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// HeapSnapshot.prototype.takeCensus returns a value of an appropriate
-// shape. Ported from js/src/jit-tests/debug/Memory-takeCensus-01.js
-
-function run_test() {
- var dbg = new Debugger;
-
- function checkProperties(census) {
- equal(typeof census, "object");
- for (prop of Object.getOwnPropertyNames(census)) {
- var desc = Object.getOwnPropertyDescriptor(census, prop);
- equal(desc.enumerable, true);
- equal(desc.configurable, true);
- equal(desc.writable, true);
- if (typeof desc.value === "object")
- checkProperties(desc.value);
- else
- equal(typeof desc.value, "number");
- }
- }
-
- checkProperties(saveHeapSnapshotAndTakeCensus(dbg));
-
- var g = newGlobal();
- dbg.addDebuggee(g);
- checkProperties(saveHeapSnapshotAndTakeCensus(dbg));
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_02.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_02.js
deleted file mode 100644
index 680ac9b58..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_02.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// HeapSnapshot.prototype.takeCensus behaves plausibly as we allocate objects.
-//
-// Exact object counts vary in ways we can't predict. For example,
-// BaselineScripts can hold onto "template objects", which exist only to hold
-// the shape and type for newly created objects. When BaselineScripts are
-// discarded, these template objects go with them.
-//
-// So instead of expecting precise counts, we expect counts that are at least as
-// many as we would expect given the object graph we've built.
-//
-// Ported from js/src/jit-tests/debug/Memory-takeCensus-02.js
-
-function run_test() {
- // A Debugger with no debuggees had better not find anything.
- var dbg = new Debugger;
- var census0 = saveHeapSnapshotAndTakeCensus(dbg);
- Census.walkCensus(census0, "census0", Census.assertAllZeros);
-
- function newGlobalWithDefs() {
- var g = newGlobal();
- g.eval(`
- function times(n, fn) {
- var a=[];
- for (var i = 0; i<n; i++)
- a.push(fn());
- return a;
- }
- `);
- return g;
- }
-
- // Allocate a large number of various types of objects, and check that census
- // finds them.
- var g = newGlobalWithDefs();
- dbg.addDebuggee(g);
-
- g.eval("var objs = times(100, () => ({}));");
- g.eval("var rxs = times(200, () => /foo/);");
- g.eval("var ars = times(400, () => []);");
- g.eval("var fns = times(800, () => () => {});");
-
- var census1 = dbg.memory.takeCensus(dbg);
- Census.walkCensus(census1, "census1",
- Census.assertAllNotLessThan(
- { "objects":
- { "Object": { count: 100 },
- "RegExp": { count: 200 },
- "Array": { count: 400 },
- "Function": { count: 800 }
- }
- }));
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_03.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_03.js
deleted file mode 100644
index 25f2c3791..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_03.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// HeapSnapshot.prototype.takeCensus behaves plausibly as we add and remove
-// debuggees.
-//
-// Ported from js/src/jit-test/tests/debug/Memory-takeCensus-03.js
-
-function run_test() {
- var dbg = new Debugger;
-
- var census0 = saveHeapSnapshotAndTakeCensus(dbg);
- Census.walkCensus(census0, "census0", Census.assertAllZeros);
-
- var g1 = newGlobal();
- dbg.addDebuggee(g1);
- var census1 = saveHeapSnapshotAndTakeCensus(dbg);
- Census.walkCensus(census1, "census1", Census.assertAllNotLessThan(census0));
-
- var g2 = newGlobal();
- dbg.addDebuggee(g2);
- var census2 = saveHeapSnapshotAndTakeCensus(dbg);
- Census.walkCensus(census2, "census2", Census.assertAllNotLessThan(census1));
-
- dbg.removeDebuggee(g2);
- var census3 = saveHeapSnapshotAndTakeCensus(dbg);
- Census.walkCensus(census3, "census3", Census.assertAllEqual(census1));
-
- dbg.removeDebuggee(g1);
- var census4 = saveHeapSnapshotAndTakeCensus(dbg);
- Census.walkCensus(census4, "census4", Census.assertAllEqual(census0));
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_04.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_04.js
deleted file mode 100644
index 799844cde..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_04.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that HeapSnapshot.prototype.takeCensus finds GC roots that are on the
-// stack.
-//
-// Ported from js/src/jit-test/tests/debug/Memory-takeCensus-04.js
-
-function run_test() {
- var g = newGlobal();
- var dbg = new Debugger(g);
-
- g.eval(`
-function withAllocationMarkerOnStack(f) {
- (function () {
- var onStack = allocationMarker();
- f();
- }());
-}
-`);
-
- equal("AllocationMarker" in saveHeapSnapshotAndTakeCensus(dbg).objects, false,
- "There shouldn't exist any allocation markers in the census.");
-
- var allocationMarkerCount;
- g.withAllocationMarkerOnStack(() => {
- const census = saveHeapSnapshotAndTakeCensus(dbg);
- allocationMarkerCount = census.objects.AllocationMarker.count;
- });
-
- equal(allocationMarkerCount, 1,
- "Should have one allocation marker in the census, because there " +
- "was one on the stack.");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_05.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_05.js
deleted file mode 100644
index da6067624..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_05.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that HeapSnapshot.prototype.takeCensus finds cross compartment
-// wrapper GC roots.
-//
-// Ported from js/src/jit-test/tests/debug/Memory-takeCensus-05.js
-
-function run_test() {
- var g = newGlobal();
- var dbg = new Debugger(g);
-
- equal("AllocationMarker" in saveHeapSnapshotAndTakeCensus(dbg).objects, false,
- "No allocation markers should exist in the census.");
-
- this.ccw = g.allocationMarker();
-
- const census = saveHeapSnapshotAndTakeCensus(dbg);
- equal(census.objects.AllocationMarker.count, 1,
- "Should have one allocation marker in the census, because there " +
- "is one cross-compartment wrapper referring to it.");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_06.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_06.js
deleted file mode 100644
index 0412410c0..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_06.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Check HeapSnapshot.prototype.takeCensus handling of 'breakdown' argument.
-//
-// Ported from js/src/jit-test/tests/debug/Memory-takeCensus-06.js
-
-function run_test() {
- var Pattern = Match.Pattern;
-
- var g = newGlobal();
- var dbg = new Debugger(g);
-
- Pattern({ count: Pattern.NATURAL,
- bytes: Pattern.NATURAL })
- .assert(saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "count" } }));
-
- let census = saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "count", count: false, bytes: false } });
- equal("count" in census, false);
- equal("bytes" in census, false);
-
- census = saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "count", count: true, bytes: false } });
- equal("count" in census, true);
- equal("bytes" in census, false);
-
- census = saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "count", count: false, bytes: true } });
- equal("count" in census, false);
- equal("bytes" in census, true);
-
- census = saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "count", count: true, bytes: true } });
- equal("count" in census, true);
- equal("bytes" in census, true);
-
-
- // Pattern doesn't mind objects with extra properties, so we'll restrict this
- // list to the object classes we're pretty sure are going to stick around for
- // the forseeable future.
- Pattern({
- Function: { count: Pattern.NATURAL },
- Object: { count: Pattern.NATURAL },
- Debugger: { count: Pattern.NATURAL },
- Sandbox: { count: Pattern.NATURAL },
-
- // The below are all Debugger prototype objects.
- Source: { count: Pattern.NATURAL },
- Environment: { count: Pattern.NATURAL },
- Script: { count: Pattern.NATURAL },
- Memory: { count: Pattern.NATURAL },
- Frame: { count: Pattern.NATURAL }
- })
- .assert(saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "objectClass" } }));
-
- Pattern({
- objects: { count: Pattern.NATURAL },
- scripts: { count: Pattern.NATURAL },
- strings: { count: Pattern.NATURAL },
- other: { count: Pattern.NATURAL }
- })
- .assert(saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "coarseType" } }));
-
- // As for { by: 'objectClass' }, restrict our pattern to the types
- // we predict will stick around for a long time.
- Pattern({
- JSString: { count: Pattern.NATURAL },
- "js::Shape": { count: Pattern.NATURAL },
- JSObject: { count: Pattern.NATURAL },
- JSScript: { count: Pattern.NATURAL }
- })
- .assert(saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "internalType" } }));
-
-
- // Nested breakdowns.
-
- let coarseTypePattern = {
- objects: { count: Pattern.NATURAL },
- scripts: { count: Pattern.NATURAL },
- strings: { count: Pattern.NATURAL },
- other: { count: Pattern.NATURAL }
- };
-
- Pattern({
- JSString: coarseTypePattern,
- "js::Shape": coarseTypePattern,
- JSObject: coarseTypePattern,
- JSScript: coarseTypePattern,
- })
- .assert(saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "internalType",
- then: { by: "coarseType" }
- }
- }));
-
- Pattern({
- Function: { count: Pattern.NATURAL },
- Object: { count: Pattern.NATURAL },
- Debugger: { count: Pattern.NATURAL },
- Sandbox: { count: Pattern.NATURAL },
- other: coarseTypePattern
- })
- .assert(saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: {
- by: "objectClass",
- then: { by: "count" },
- other: { by: "coarseType" }
- }
- }));
-
- Pattern({
- objects: { count: Pattern.NATURAL, label: "object" },
- scripts: { count: Pattern.NATURAL, label: "scripts" },
- strings: { count: Pattern.NATURAL, label: "strings" },
- other: { count: Pattern.NATURAL, label: "other" }
- })
- .assert(saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: {
- by: "coarseType",
- objects: { by: "count", label: "object" },
- scripts: { by: "count", label: "scripts" },
- strings: { by: "count", label: "strings" },
- other: { by: "count", label: "other" }
- }
- }));
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_07.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_07.js
deleted file mode 100644
index f5c36056f..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_07.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// HeapSnapshot.prototype.takeCensus breakdown: check error handling on property
-// gets.
-//
-// Ported from js/src/jit-test/tests/debug/Memory-takeCensus-07.js
-
-function run_test() {
- var g = newGlobal();
- var dbg = new Debugger(g);
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { get by() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
-
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "count", get count() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "count", get bytes() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
-
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "objectClass", get then() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "objectClass", get other() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
-
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "coarseType", get objects() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "coarseType", get scripts() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "coarseType", get strings() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "coarseType", get other() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
-
-
- assertThrowsValue(() => {
- saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "internalType", get then() { throw "ಠ_ಠ"; } }
- });
- }, "ಠ_ಠ");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_08.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_08.js
deleted file mode 100644
index 5934aa919..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_08.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// HeapSnapshot.prototype.takeCensus: test by: 'count' breakdown
-//
-// Ported from js/src/jit-test/tests/debug/Memory-takeCensus-08.js
-
-function run_test() {
- let g = newGlobal();
- let dbg = new Debugger(g);
-
- g.eval(`
- var stuff = [];
- function add(n, c) {
- for (let i = 0; i < n; i++)
- stuff.push(c());
- }
-
- let count = 0;
-
- function obj() { return { count: count++ }; }
- obj.factor = 1;
-
- // This creates a closure (a function JSObject) that has captured
- // a Call object. So each call creates two items.
- function fun() { let v = count; return () => { return v; } }
- fun.factor = 2;
-
- function str() { return 'perambulator' + count++; }
- str.factor = 1;
-
- // Eval a fresh text each time, allocating:
- // - a fresh ScriptSourceObject
- // - a new JSScripts, not an eval cache hits
- // - a fresh prototype object
- // - a fresh Call object, since the eval makes 'ev' heavyweight
- // - the new function itself
- function ev() {
- return eval(\`(function () { return \${ count++ } })\`);
- }
- ev.factor = 5;
-
- // A new object (1) with a new shape (2) with a new atom (3)
- function shape() { return { [ 'theobroma' + count++ ]: count }; }
- shape.factor = 3;
- `);
-
- let baseline = 0;
- function countIncreasedByAtLeast(n) {
- let oldBaseline = baseline;
-
- // Since a census counts only reachable objects, one might assume that calling
- // GC here would have no effect on the census results. But GC also throws away
- // JIT code and any objects it might be holding (template objects, say);
- // takeCensus reaches those. Shake everything loose that we can, to make the
- // census approximate reachability a bit more closely, and make our results a
- // bit more predictable.
- gc(g, "shrinking");
-
- baseline = saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "count" } }).count;
- return baseline >= oldBaseline + n;
- }
-
- countIncreasedByAtLeast(0);
-
- g.add(100, g.obj);
- ok(countIncreasedByAtLeast(g.obj.factor * 100));
-
- g.add(100, g.fun);
- ok(countIncreasedByAtLeast(g.fun.factor * 100));
-
- g.add(100, g.str);
- ok(countIncreasedByAtLeast(g.str.factor * 100));
-
- g.add(100, g.ev);
- ok(countIncreasedByAtLeast(g.ev.factor * 100));
-
- g.add(100, g.shape);
- ok(countIncreasedByAtLeast(g.shape.factor * 100));
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_09.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_09.js
deleted file mode 100644
index bbacccc8d..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_09.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// HeapSnapshot.prototype.takeCensus: by: allocationStack breakdown
-//
-// Ported from js/src/jit-test/tests/debug/Memory-takeCensus-09.js
-
-function run_test() {
- var g = newGlobal();
- var dbg = new Debugger(g);
-
- g.eval(` // 1
- var log = []; // 2
- function f() { log.push(allocationMarker()); } // 3
- function g() { f(); } // 4
- function h() { f(); } // 5
- `); // 6
-
- // Create one allocationMarker with tracking turned off,
- // so it will have no associated stack.
- g.f();
-
- dbg.memory.allocationSamplingProbability = 1;
-
- for ([func, n] of [[g.f, 20], [g.g, 10], [g.h, 5]]) {
- for (let i = 0; i < n; i++) {
- dbg.memory.trackingAllocationSites = true;
- // All allocations of allocationMarker occur with this line as the oldest
- // stack frame.
- func();
- dbg.memory.trackingAllocationSites = false;
- }
- }
-
- let census = saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "objectClass",
- then: { by: "allocationStack",
- then: { by: "count",
- label: "haz stack"
- },
- noStack: { by: "count",
- label: "no haz stack"
- }
- }
- }
- });
-
- let map = census.AllocationMarker;
- ok(map instanceof Map, "Should be a Map instance");
- equal(map.size, 4, "Should have 4 allocation stacks (including the lack of a stack)");
-
- // Gather the stacks we are expecting to appear as keys, and
- // check that there are no unexpected keys.
- let stacks = { };
-
- map.forEach((v, k) => {
- if (k === "noStack") {
- // No need to save this key.
- } else if (k.functionDisplayName === "f" &&
- k.parent.functionDisplayName === "run_test") {
- stacks.f = k;
- } else if (k.functionDisplayName === "f" &&
- k.parent.functionDisplayName === "g" &&
- k.parent.parent.functionDisplayName === "run_test") {
- stacks.fg = k;
- } else if (k.functionDisplayName === "f" &&
- k.parent.functionDisplayName === "h" &&
- k.parent.parent.functionDisplayName === "run_test") {
- stacks.fh = k;
- } else {
- dumpn("Unexpected allocation stack:");
- k.toString().split(/\n/g).forEach(s => dumpn(s));
- ok(false);
- }
- });
-
- equal(map.get("noStack").label, "no haz stack");
- equal(map.get("noStack").count, 1);
-
- ok(stacks.f);
- equal(map.get(stacks.f).label, "haz stack");
- equal(map.get(stacks.f).count, 20);
-
- ok(stacks.fg);
- equal(map.get(stacks.fg).label, "haz stack");
- equal(map.get(stacks.fg).count, 10);
-
- ok(stacks.fh);
- equal(map.get(stacks.fh).label, "haz stack");
- equal(map.get(stacks.fh).count, 5);
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_10.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_10.js
deleted file mode 100644
index a7f987f5a..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_10.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Check byte counts produced by takeCensus.
-//
-// Ported from js/src/jit-test/tests/debug/Memory-take Census-10.js
-
-function run_test() {
- let g = newGlobal();
- let dbg = new Debugger(g);
-
- let sizeOfAM = byteSize(allocationMarker());
-
- // Allocate a single allocation marker, and check that we can find it.
- g.eval("var hold = allocationMarker();");
- let census = saveHeapSnapshotAndTakeCensus(dbg, { breakdown: { by: "objectClass" } });
- equal(census.AllocationMarker.count, 1);
- equal(census.AllocationMarker.bytes, sizeOfAM);
- g.hold = null;
-
- g.eval(` // 1
- var objs = []; // 2
- function fnerd() { // 3
- objs.push(allocationMarker()); // 4
- for (let i = 0; i < 10; i++) // 5
- objs.push(allocationMarker()); // 6
- } // 7
- `); // 8
-
- dbg.memory.allocationSamplingProbability = 1;
- dbg.memory.trackingAllocationSites = true;
- g.fnerd();
- dbg.memory.trackingAllocationSites = false;
-
- census = saveHeapSnapshotAndTakeCensus(dbg, {
- breakdown: { by: "objectClass",
- then: { by: "allocationStack" }
- }
- });
-
- let seen = 0;
- census.AllocationMarker.forEach((v, k) => {
- equal(k.functionDisplayName, "fnerd");
- switch (k.line) {
- case 4:
- equal(v.count, 1);
- equal(v.bytes, sizeOfAM);
- seen++;
- break;
-
- case 6:
- equal(v.count, 10);
- equal(v.bytes, 10 * sizeOfAM);
- seen++;
- break;
-
- default:
- dumpn("Unexpected stack:");
- k.toString().split(/\n/g).forEach(s => dumpn(s));
- ok(false);
- break;
- }
- });
-
- equal(seen, 2);
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_11.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_11.js
deleted file mode 100644
index 3d898b2d1..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_11.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that Debugger.Memory.prototype.takeCensus and
-// HeapSnapshot.prototype.takeCensus return the same data for the same heap
-// graph.
-
-function doLiveAndOfflineCensus(g, dbg, opts) {
- dbg.memory.allocationSamplingProbability = 1;
- dbg.memory.trackingAllocationSites = true;
- g.eval(` // 1
- (function unsafeAtAnySpeed() { // 2
- for (var i = 0; i < 100; i++) { // 3
- this.markers.push(allocationMarker()); // 4
- } // 5
- }()); // 6
- `); // 7
- dbg.memory.trackingAllocationSites = false;
-
- return {
- live: dbg.memory.takeCensus(opts),
- offline: saveHeapSnapshotAndTakeCensus(dbg, opts)
- };
-}
-
-function run_test() {
- var g = newGlobal();
- var dbg = new Debugger(g);
-
- g.eval("this.markers = []");
- const markerSize = byteSize(allocationMarker());
-
- // First, test that we get the same counts and sizes as we allocate and retain
- // more things.
-
- let prevCount = 0;
- let prevBytes = 0;
-
- for (var i = 0; i < 10; i++) {
- const { live, offline } = doLiveAndOfflineCensus(g, dbg, {
- breakdown: { by: "objectClass",
- then: { by: "count"} }
- });
-
- equal(live.AllocationMarker.count, offline.AllocationMarker.count);
- equal(live.AllocationMarker.bytes, offline.AllocationMarker.bytes);
- equal(live.AllocationMarker.count, prevCount + 100);
- equal(live.AllocationMarker.bytes, prevBytes + 100 * markerSize);
-
- prevCount = live.AllocationMarker.count;
- prevBytes = live.AllocationMarker.bytes;
- }
-
- // Second, test that the reported allocation stacks and counts and sizes at
- // those allocation stacks match up.
-
- const { live, offline } = doLiveAndOfflineCensus(g, dbg, {
- breakdown: { by: "objectClass",
- then: { by: "allocationStack"} }
- });
-
- equal(live.AllocationMarker.size, offline.AllocationMarker.size);
- // One stack with the loop further above, and another stack featuring the call
- // right above.
- equal(live.AllocationMarker.size, 2);
-
- // Note that because SavedFrame stacks reconstructed from an offline heap
- // snapshot don't have the same principals as SavedFrame stacks captured from
- // a live stack, the live and offline allocation stacks won't be identity
- // equal, but should be structurally the same.
-
- const liveEntries = [];
- live.AllocationMarker.forEach((v, k) => {
- dumpn("Allocation stack:");
- k.toString().split(/\n/g).forEach(s => dumpn(s));
-
- equal(k.functionDisplayName, "unsafeAtAnySpeed");
- equal(k.line, 4);
-
- liveEntries.push([k.toString(), v]);
- });
-
- const offlineEntries = [];
- offline.AllocationMarker.forEach((v, k) => {
- dumpn("Allocation stack:");
- k.toString().split(/\n/g).forEach(s => dumpn(s));
-
- equal(k.functionDisplayName, "unsafeAtAnySpeed");
- equal(k.line, 4);
-
- offlineEntries.push([k.toString(), v]);
- });
-
- const sortEntries = (a, b) => {
- if (a[0] < b[0]) {
- return -1;
- } else if (a[0] > b[0]) {
- return 1;
- } else {
- return 0;
- }
- };
- liveEntries.sort(sortEntries);
- offlineEntries.sort(sortEntries);
-
- equal(liveEntries.length, live.AllocationMarker.size);
- equal(liveEntries.length, offlineEntries.length);
-
- for (let i = 0; i < liveEntries.length; i++) {
- equal(liveEntries[i][0], offlineEntries[i][0]);
- equal(liveEntries[i][1].count, offlineEntries[i][1].count);
- equal(liveEntries[i][1].bytes, offlineEntries[i][1].bytes);
- }
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_12.js b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_12.js
deleted file mode 100644
index f10dd5b03..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_takeCensus_12.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that when we take a census and get a bucket list of ids that matched the
-// given category, that the returned ids are all in the snapshot and their
-// reported category.
-
-function run_test() {
- const g = newGlobal();
- const dbg = new Debugger(g);
-
- const path = saveNewHeapSnapshot({ debugger: dbg });
- const snapshot = readHeapSnapshot(path);
-
- const bucket = { by: "bucket" };
- const count = { by: "count", count: true, bytes: false };
- const objectClassCount = { by: "objectClass", then: count, other: count };
-
- const byClassName = snapshot.takeCensus({
- breakdown: {
- by: "objectClass",
- then: bucket,
- other: bucket,
- }
- });
-
- const byClassNameCount = snapshot.takeCensus({
- breakdown: objectClassCount
- });
-
- const keys = new Set(Object.keys(byClassName));
- equal(keys.size, Object.keys(byClassNameCount).length,
- "Should have the same number of keys.");
- for (let k of Object.keys(byClassNameCount)) {
- ok(keys.has(k), "Should not have any unexpected class names");
- }
-
- for (let key of Object.keys(byClassName)) {
- equal(byClassNameCount[key].count, byClassName[key].length,
- "Length of the bucket and count should be equal");
-
- for (let id of byClassName[key]) {
- const desc = snapshot.describeNode(objectClassCount, id);
- equal(desc[key].count, 1,
- "Describing the bucketed node confirms that it belongs to the category");
- }
- }
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot.js b/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot.js
deleted file mode 100644
index dde139ffd..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can read core dumps into HeapSnapshot instances.
-
-if (typeof Debugger != "function") {
- const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {});
- addDebuggerToGlobal(this);
-}
-
-function run_test() {
- const filePath = ChromeUtils.saveHeapSnapshot({ globals: [this] });
- ok(true, "Should be able to save a snapshot.");
-
- const snapshot = ChromeUtils.readHeapSnapshot(filePath);
- ok(snapshot, "Should be able to read a heap snapshot");
- ok(snapshot instanceof HeapSnapshot, "Should be an instanceof HeapSnapshot");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_with_allocations.js b/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_with_allocations.js
deleted file mode 100644
index d91f36f56..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_with_allocations.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can save a core dump with allocation stacks and read it back
-// into a HeapSnapshot.
-
-if (typeof Debugger != "function") {
- const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {});
- addDebuggerToGlobal(this);
-}
-
-function run_test() {
- // Create a Debugger observing a debuggee's allocations.
- const debuggee = new Cu.Sandbox(null);
- const dbg = new Debugger(debuggee);
- dbg.memory.trackingAllocationSites = true;
-
- // Allocate some objects in the debuggee that will have their allocation
- // stacks recorded by the Debugger.
- debuggee.eval("this.objects = []");
- for (let i = 0; i < 100; i++) {
- debuggee.eval("this.objects.push({})");
- }
-
- // Now save a snapshot that will include the allocation stacks and read it
- // back again.
-
- const filePath = ChromeUtils.saveHeapSnapshot({ runtime: true });
- ok(true, "Should be able to save a snapshot.");
-
- const snapshot = ChromeUtils.readHeapSnapshot(filePath);
- ok(snapshot, "Should be able to read a heap snapshot");
- ok(snapshot instanceof HeapSnapshot, "Should be an instanceof HeapSnapshot");
-
- do_test_finished();
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_worker.js b/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_worker.js
deleted file mode 100644
index 76461b694..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_ReadHeapSnapshot_worker.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that we can read core dumps into HeapSnapshot instances in a worker.
-
-add_task(function* () {
- const worker = new ChromeWorker("resource://test/heap-snapshot-worker.js");
- worker.postMessage({});
-
- let assertionCount = 0;
- worker.onmessage = e => {
- if (e.data.type !== "assertion") {
- return;
- }
-
- ok(e.data.passed, e.data.msg + "\n" + e.data.stack);
- assertionCount++;
- };
-
- yield waitForDone(worker);
-
- ok(assertionCount > 0);
- worker.terminate();
-});
-
-function waitForDone(w) {
- return new Promise((resolve, reject) => {
- w.onerror = e => {
- reject();
- ok(false, "Error in worker: " + e);
- };
-
- w.addEventListener("message", function listener(e) {
- if (e.data.type === "done") {
- w.removeEventListener("message", listener, false);
- resolve();
- }
- }, false);
- });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_SaveHeapSnapshot.js b/devtools/shared/heapsnapshot/tests/unit/test_SaveHeapSnapshot.js
deleted file mode 100644
index affd8d1e4..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_SaveHeapSnapshot.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the ChromeUtils interface.
-
-if (typeof Debugger != "function") {
- const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {});
- addDebuggerToGlobal(this);
-}
-
-function run_test() {
- ok(ChromeUtils, "Should be able to get the ChromeUtils interface");
-
- testBadParameters();
- testGoodParameters();
-
- do_test_finished();
-}
-
-function testBadParameters() {
- throws(() => ChromeUtils.saveHeapSnapshot(),
- "Should throw if arguments aren't passed in.");
-
- throws(() => ChromeUtils.saveHeapSnapshot(null),
- "Should throw if boundaries isn't an object.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({}),
- "Should throw if the boundaries object doesn't have any properties.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ runtime: true,
- globals: [this] }),
- "Should throw if the boundaries object has more than one property.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ debugger: {} }),
- "Should throw if the debuggees object is not a Debugger object");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ globals: [{}] }),
- "Should throw if the globals array contains non-global objects.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ runtime: false }),
- "Should throw if runtime is supplied and is not true.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ globals: null }),
- "Should throw if globals is not an object.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ globals: {} }),
- "Should throw if globals is not an array.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ debugger: Debugger.prototype }),
- "Should throw if debugger is the Debugger.prototype object.");
-
- throws(() => ChromeUtils.saveHeapSnapshot({ get globals() { return [this]; } }),
- "Should throw if boundaries property is a getter.");
-}
-
-const makeNewSandbox = () =>
- Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")());
-
-function testGoodParameters() {
- let sandbox = makeNewSandbox();
- let dbg = new Debugger(sandbox);
-
- ChromeUtils.saveHeapSnapshot({ debugger: dbg });
- ok(true, "Should be able to save a snapshot for a debuggee global.");
-
- dbg = new Debugger;
- let sandboxes = Array(10).fill(null).map(makeNewSandbox);
- sandboxes.forEach(sb => dbg.addDebuggee(sb));
-
- ChromeUtils.saveHeapSnapshot({ debugger: dbg });
- ok(true, "Should be able to save a snapshot for many debuggee globals.");
-
- dbg = new Debugger;
- ChromeUtils.saveHeapSnapshot({ debugger: dbg });
- ok(true, "Should be able to save a snapshot with no debuggee globals.");
-
- ChromeUtils.saveHeapSnapshot({ globals: [this] });
- ok(true, "Should be able to save a snapshot for a specific global.");
-
- ChromeUtils.saveHeapSnapshot({ runtime: true });
- ok(true, "Should be able to save a snapshot of the full runtime.");
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-01.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-01.js
deleted file mode 100644
index 16038c5c4..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-01.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests CensusTreeNode with `internalType` breakdown.
- */
-
-const BREAKDOWN = {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
-};
-
-const REPORT = {
- "JSObject": {
- "bytes": 100,
- "count": 10,
- },
- "js::Shape": {
- "bytes": 500,
- "count": 50,
- },
- "JSString": {
- "bytes": 10,
- "count": 1,
- },
-};
-
-const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 610,
- count: 0,
- totalCount: 61,
- children: [
- {
- name: "js::Shape",
- bytes: 500,
- totalBytes: 500,
- count: 50,
- totalCount: 50,
- children: undefined,
- id: 3,
- parent: 1,
- reportLeafIndex: 2,
- },
- {
- name: "JSObject",
- bytes: 100,
- totalBytes: 100,
- count: 10,
- totalCount: 10,
- children: undefined,
- id: 2,
- parent: 1,
- reportLeafIndex: 1,
- },
- {
- name: "JSString",
- bytes: 10,
- totalBytes: 10,
- count: 1,
- totalCount: 1,
- children: undefined,
- id: 4,
- parent: 1,
- reportLeafIndex: 3,
- },
- ],
- id: 1,
- parent: undefined,
- reportLeafIndex: undefined,
-};
-
-function run_test() {
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-02.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-02.js
deleted file mode 100644
index 37d039954..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-02.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests CensusTreeNode with `coarseType` breakdown.
- */
-
-const countBreakdown = { by: "count", count: true, bytes: true };
-
-const BREAKDOWN = {
- by: "coarseType",
- objects: { by: "objectClass", then: countBreakdown },
- strings: countBreakdown,
- scripts: countBreakdown,
- other: { by: "internalType", then: countBreakdown },
-};
-
-const REPORT = {
- "objects": {
- "Function": { bytes: 10, count: 1 },
- "Array": { bytes: 20, count: 2 },
- },
- "strings": { bytes: 10, count: 1 },
- "scripts": { bytes: 1, count: 1 },
- "other": {
- "js::Shape": { bytes: 30, count: 3 },
- "js::Shape2": { bytes: 40, count: 4 }
- },
-};
-
-const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 111,
- count: 0,
- totalCount: 12,
- children: [
- {
- name: "other",
- count: 0,
- totalCount: 7,
- bytes: 0,
- totalBytes: 70,
- children: [
- {
- name: "js::Shape2",
- bytes: 40,
- totalBytes: 40,
- count: 4,
- totalCount: 4,
- children: undefined,
- id: 9,
- parent: 7,
- reportLeafIndex: 8,
- },
- {
- name: "js::Shape",
- bytes: 30,
- totalBytes: 30,
- count: 3,
- totalCount: 3,
- children: undefined,
- id: 8,
- parent: 7,
- reportLeafIndex: 7,
- },
- ],
- id: 7,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "objects",
- count: 0,
- totalCount: 3,
- bytes: 0,
- totalBytes: 30,
- children: [
- {
- name: "Array",
- bytes: 20,
- totalBytes: 20,
- count: 2,
- totalCount: 2,
- children: undefined,
- id: 4,
- parent: 2,
- reportLeafIndex: 3,
- },
- {
- name: "Function",
- bytes: 10,
- totalBytes: 10,
- count: 1,
- totalCount: 1,
- children: undefined,
- id: 3,
- parent: 2,
- reportLeafIndex: 2,
- },
- ],
- id: 2,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "strings",
- count: 1,
- totalCount: 1,
- bytes: 10,
- totalBytes: 10,
- children: undefined,
- id: 6,
- parent: 1,
- reportLeafIndex: 5,
- },
- {
- name: "scripts",
- count: 1,
- totalCount: 1,
- bytes: 1,
- totalBytes: 1,
- children: undefined,
- id: 5,
- parent: 1,
- reportLeafIndex: 4,
- },
- ],
- id: 1,
- parent: undefined,
- reportLeafIndex: undefined,
-};
-
-function run_test() {
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-03.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-03.js
deleted file mode 100644
index bdf932099..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-03.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests CensusTreeNode with `objectClass` breakdown.
- */
-
-const countBreakdown = { by: "count", count: true, bytes: true };
-
-const BREAKDOWN = {
- by: "objectClass",
- then: countBreakdown,
- other: { by: "internalType", then: countBreakdown }
-};
-
-const REPORT = {
- "Function": { bytes: 10, count: 10 },
- "Array": { bytes: 100, count: 1 },
- "other": {
- "JIT::CODE::NOW!!!": { bytes: 20, count: 2 },
- "JIT::CODE::LATER!!!": { bytes: 40, count: 4 }
- }
-};
-
-const EXPECTED = {
- name: null,
- count: 0,
- totalCount: 17,
- bytes: 0,
- totalBytes: 170,
- children: [
- {
- name: "Array",
- bytes: 100,
- totalBytes: 100,
- count: 1,
- totalCount: 1,
- children: undefined,
- id: 3,
- parent: 1,
- reportLeafIndex: 2,
- },
- {
- name: "other",
- count: 0,
- totalCount: 6,
- bytes: 0,
- totalBytes: 60,
- children: [
- {
- name: "JIT::CODE::LATER!!!",
- bytes: 40,
- totalBytes: 40,
- count: 4,
- totalCount: 4,
- children: undefined,
- id: 6,
- parent: 4,
- reportLeafIndex: 5,
- },
- {
- name: "JIT::CODE::NOW!!!",
- bytes: 20,
- totalBytes: 20,
- count: 2,
- totalCount: 2,
- children: undefined,
- id: 5,
- parent: 4,
- reportLeafIndex: 4,
- },
- ],
- id: 4,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "Function",
- bytes: 10,
- totalBytes: 10,
- count: 10,
- totalCount: 10,
- children: undefined,
- id: 2,
- parent: 1,
- reportLeafIndex: 1,
- },
- ],
- id: 1,
- parent: undefined,
- reportLeafIndex: undefined,
-};
-
-function run_test() {
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-04.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-04.js
deleted file mode 100644
index cc0c3bac0..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-04.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests CensusTreeNode with `allocationStack` breakdown.
- */
-
-function run_test() {
- const countBreakdown = { by: "count", count: true, bytes: true };
-
- const BREAKDOWN = {
- by: "allocationStack",
- then: countBreakdown,
- noStack: countBreakdown,
- };
-
- let stack1, stack2, stack3, stack4, stack5;
-
- (function a() {
- (function b() {
- (function c() {
- stack1 = saveStack(3);
- }());
- (function d() {
- stack2 = saveStack(3);
- stack3 = saveStack(3);
- }());
- stack4 = saveStack(2);
- }());
- }());
-
- stack5 = saveStack(1);
-
- const REPORT = new Map([
- [stack1, { bytes: 10, count: 1 }],
- [stack2, { bytes: 20, count: 2 }],
- [stack3, { bytes: 30, count: 3 }],
- [stack4, { bytes: 40, count: 4 }],
- [stack5, { bytes: 50, count: 5 }],
- ["noStack", { bytes: 60, count: 6 }],
- ]);
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 210,
- count: 0,
- totalCount: 21,
- children: [
- {
- name: stack4.parent,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: [
- {
- name: stack3.parent,
- bytes: 0,
- totalBytes: 50,
- count: 0,
- totalCount: 5,
- children: [
- {
- name: stack3,
- bytes: 30,
- totalBytes: 30,
- count: 3,
- totalCount: 3,
- children: undefined,
- id: 7,
- parent: 5,
- reportLeafIndex: 3,
- },
- {
- name: stack2,
- bytes: 20,
- totalBytes: 20,
- count: 2,
- totalCount: 2,
- children: undefined,
- id: 6,
- parent: 5,
- reportLeafIndex: 2,
- }
- ],
- id: 5,
- parent: 2,
- reportLeafIndex: undefined,
- },
- {
- name: stack4,
- bytes: 40,
- totalBytes: 40,
- count: 4,
- totalCount: 4,
- children: undefined,
- id: 8,
- parent: 2,
- reportLeafIndex: 4,
- },
- {
- name: stack1.parent,
- bytes: 0,
- totalBytes: 10,
- count: 0,
- totalCount: 1,
- children: [
- {
- name: stack1,
- bytes: 10,
- totalBytes: 10,
- count: 1,
- totalCount: 1,
- children: undefined,
- id: 4,
- parent: 3,
- reportLeafIndex: 1,
- },
- ],
- id: 3,
- parent: 2,
- reportLeafIndex: undefined,
- },
- ],
- id: 2,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "noStack",
- bytes: 60,
- totalBytes: 60,
- count: 6,
- totalCount: 6,
- children: undefined,
- id: 10,
- parent: 1,
- reportLeafIndex: 6,
- },
- {
- name: stack5,
- bytes: 50,
- totalBytes: 50,
- count: 5,
- totalCount: 5,
- children: undefined,
- id: 9,
- parent: 1,
- reportLeafIndex: 5
- },
- ],
- id: 1,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-05.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-05.js
deleted file mode 100644
index 20fb76bd2..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-05.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests CensusTreeNode with `allocationStack` => `objectClass` breakdown.
- */
-
-function run_test() {
- const countBreakdown = { by: "count", count: true, bytes: true };
-
- const BREAKDOWN = {
- by: "allocationStack",
- then: {
- by: "objectClass",
- then: countBreakdown,
- other: countBreakdown
- },
- noStack: countBreakdown,
- };
-
- let stack;
-
- (function a() {
- (function b() {
- (function c() {
- stack = saveStack(3);
- }());
- }());
- }());
-
- const REPORT = new Map([
- [stack, { Foo: { bytes: 10, count: 1 },
- Bar: { bytes: 20, count: 2 },
- Baz: { bytes: 30, count: 3 },
- other: { bytes: 40, count: 4 }
- }],
- ["noStack", { bytes: 50, count: 5 }],
- ]);
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 150,
- count: 0,
- totalCount: 15,
- children: [
- {
- name: stack.parent.parent,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: [
- {
- name: stack.parent,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: [
- {
- name: stack,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: [
- {
- name: "other",
- bytes: 40,
- totalBytes: 40,
- count: 4,
- totalCount: 4,
- children: undefined,
- id: 8,
- parent: 4,
- reportLeafIndex: 5,
- },
- {
- name: "Baz",
- bytes: 30,
- totalBytes: 30,
- count: 3,
- totalCount: 3,
- children: undefined,
- id: 7,
- parent: 4,
- reportLeafIndex: 4,
- },
- {
- name: "Bar",
- bytes: 20,
- totalBytes: 20,
- count: 2,
- totalCount: 2,
- children: undefined,
- id: 6,
- parent: 4,
- reportLeafIndex: 3,
- },
- {
- name: "Foo",
- bytes: 10,
- totalBytes: 10,
- count: 1,
- totalCount: 1,
- children: undefined,
- id: 5,
- parent: 4,
- reportLeafIndex: 2,
- },
- ],
- id: 4,
- parent: 3,
- reportLeafIndex: undefined,
- }
- ],
- id: 3,
- parent: 2,
- reportLeafIndex: undefined,
- }
- ],
- id: 2,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "noStack",
- bytes: 50,
- totalBytes: 50,
- count: 5,
- totalCount: 5,
- children: undefined,
- id: 9,
- parent: 1,
- reportLeafIndex: 6,
- },
- ],
- id: 1,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-06.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-06.js
deleted file mode 100644
index eb1801207..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-06.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Test inverting CensusTreeNode with a by alloaction stack breakdown.
- */
-
-function run_test() {
- const BREAKDOWN = {
- by: "allocationStack",
- then: { by: "count", count: true, bytes: true },
- noStack: { by: "count", count: true, bytes: true },
- };
-
- let stack1, stack2, stack3, stack4;
-
- function a(n) {
- return b(n);
- }
- function b(n) {
- return c(n);
- }
- function c(n) {
- return saveStack(n);
- }
- function d(n) {
- return b(n);
- }
- function e(n) {
- return c(n);
- }
-
- const abc_Stack = a(3);
- const bc_Stack = b(2);
- const c_Stack = c(1);
- const dbc_Stack = d(3);
- const ec_Stack = e(2);
-
- const REPORT = new Map([
- [abc_Stack, { bytes: 10, count: 1 }],
- [ bc_Stack, { bytes: 10, count: 1 }],
- [ c_Stack, { bytes: 10, count: 1 }],
- [dbc_Stack, { bytes: 10, count: 1 }],
- [ ec_Stack, { bytes: 10, count: 1 }],
- ["noStack", { bytes: 50, count: 5 }],
- ]);
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: [
- {
- name: "noStack",
- bytes: 50,
- totalBytes: 50,
- count: 5,
- totalCount: 5,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: undefined,
- id: 16,
- parent: 15,
- reportLeafIndex: undefined,
- }
- ],
- id: 15,
- parent: 14,
- reportLeafIndex: 6,
- },
- {
- name: abc_Stack,
- bytes: 50,
- totalBytes: 10,
- count: 5,
- totalCount: 1,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: undefined,
- id: 18,
- parent: 17,
- reportLeafIndex: undefined,
- },
- {
- name: abc_Stack.parent,
- bytes: 0,
- totalBytes: 10,
- count: 0,
- totalCount: 1,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: undefined,
- id: 22,
- parent: 19,
- reportLeafIndex: undefined,
- },
- {
- name: abc_Stack.parent.parent,
- bytes: 0,
- totalBytes: 10,
- count: 0,
- totalCount: 1,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: undefined,
- id: 21,
- parent: 20,
- reportLeafIndex: undefined,
- }
- ],
- id: 20,
- parent: 19,
- reportLeafIndex: undefined,
- },
- {
- name: dbc_Stack.parent.parent,
- bytes: 0,
- totalBytes: 10,
- count: 0,
- totalCount: 1,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: undefined,
- id: 24,
- parent: 23,
- reportLeafIndex: undefined,
- }
- ],
- id: 23,
- parent: 19,
- reportLeafIndex: undefined,
- }
- ],
- id: 19,
- parent: 17,
- reportLeafIndex: undefined,
- },
- {
- name: ec_Stack.parent,
- bytes: 0,
- totalBytes: 10,
- count: 0,
- totalCount: 1,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: undefined,
- id: 26,
- parent: 25,
- reportLeafIndex: undefined,
- },
- ],
- id: 25,
- parent: 17,
- reportLeafIndex: undefined,
- },
- ],
- id: 17,
- parent: 14,
- reportLeafIndex: new Set([1, 2, 3, 4, 5]),
- }
- ],
- id: 14,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED, { invert: true });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-07.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-07.js
deleted file mode 100644
index 6bc085257..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-07.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Test inverting CensusTreeNode with a non-allocation stack breakdown.
- */
-
-function run_test() {
- const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other:{
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- };
-
- const REPORT = {
- objects: {
- Array: { bytes: 50, count: 5 },
- other: { bytes: 0, count: 0 },
- },
- scripts: {
- "js::jit::JitScript": { bytes: 30, count: 3 },
- },
- strings: {
- JSAtom: { bytes: 60, count: 6 },
- },
- other: {
- "js::Shape": { bytes: 80, count: 8 },
- }
- };
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 220,
- count: 0,
- totalCount: 22,
- children: [
- {
- name: "js::Shape",
- bytes: 80,
- totalBytes: 80,
- count: 8,
- totalCount: 8,
- children: [
- {
- name: "other",
- bytes: 0,
- totalBytes: 80,
- count: 0,
- totalCount: 8,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 220,
- count: 0,
- totalCount: 22,
- children: undefined,
- id: 14,
- parent: 13,
- reportLeafIndex: undefined,
- }
- ],
- id: 13,
- parent: 12,
- reportLeafIndex: undefined,
- }
- ],
- id: 12,
- parent: 11,
- reportLeafIndex: 9,
- },
- {
- name: "JSAtom",
- bytes: 60,
- totalBytes: 60,
- count: 6,
- totalCount: 6,
- children: [
- {
- name: "strings",
- bytes: 0,
- totalBytes: 60,
- count: 0,
- totalCount: 6,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 220,
- count: 0,
- totalCount: 22,
- children: undefined,
- id: 17,
- parent: 16,
- reportLeafIndex: undefined,
- }
- ],
- id: 16,
- parent: 15,
- reportLeafIndex: undefined,
- }
- ],
- id: 15,
- parent: 11,
- reportLeafIndex: 7,
- },
- {
- name: "Array",
- bytes: 50,
- totalBytes: 50,
- count: 5,
- totalCount: 5,
- children: [
- {
- name: "objects",
- bytes: 0,
- totalBytes: 50,
- count: 0,
- totalCount: 5,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 220,
- count: 0,
- totalCount: 22,
- children: undefined,
- id: 20,
- parent: 19,
- reportLeafIndex: undefined,
- }
- ],
- id: 19,
- parent: 18,
- reportLeafIndex: undefined,
- }
- ],
- id: 18,
- parent: 11,
- reportLeafIndex: 2,
- },
- {
- name: "js::jit::JitScript",
- bytes: 30,
- totalBytes: 30,
- count: 3,
- totalCount: 3,
- children: [
- {
- name: "scripts",
- bytes: 0,
- totalBytes: 30,
- count: 0,
- totalCount: 3,
- children: [
- {
- name: null,
- bytes: 0,
- totalBytes: 220,
- count: 0,
- totalCount: 22,
- children: undefined,
- id: 23,
- parent: 22,
- reportLeafIndex: undefined,
- }
- ],
- id: 22,
- parent: 21,
- reportLeafIndex: undefined,
- }
- ],
- id: 21,
- parent: 11,
- reportLeafIndex: 5,
- },
- ],
- id: 11,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED, { invert: true });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-08.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-08.js
deleted file mode 100644
index 1c686c810..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-08.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Test inverting CensusTreeNode with a non-allocation stack breakdown.
- */
-
-function run_test() {
- const BREAKDOWN = {
- by: "filename",
- then: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
- },
- noFilename: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
- },
- };
-
- const REPORT = {
- "http://example.com/app.js": {
- JSScript: { count: 10, bytes: 100 }
- },
- "http://example.com/ads.js": {
- "js::LazyScript": { count: 20, bytes: 200 }
- },
- "http://example.com/trackers.js": {
- JSScript: { count: 30, bytes: 300 }
- },
- noFilename: {
- "js::jit::JitCode": { count: 40, bytes: 400 }
- }
- };
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 1000,
- count: 0,
- totalCount: 100,
- children: [
- {
- name: "noFilename",
- bytes: 0,
- totalBytes: 400,
- count: 0,
- totalCount: 40,
- children: [
- {
- name: "js::jit::JitCode",
- bytes: 400,
- totalBytes: 400,
- count: 40,
- totalCount: 40,
- children: undefined,
- id: 9,
- parent: 8,
- reportLeafIndex: 8,
- }
- ],
- id: 8,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "http://example.com/trackers.js",
- bytes: 0,
- totalBytes: 300,
- count: 0,
- totalCount: 30,
- children: [
- {
- name: "JSScript",
- bytes: 300,
- totalBytes: 300,
- count: 30,
- totalCount: 30,
- children: undefined,
- id: 7,
- parent: 6,
- reportLeafIndex: 6,
- }
- ],
- id: 6,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "http://example.com/ads.js",
- bytes: 0,
- totalBytes: 200,
- count: 0,
- totalCount: 20,
- children: [
- {
- name: "js::LazyScript",
- bytes: 200,
- totalBytes: 200,
- count: 20,
- totalCount: 20,
- children: undefined,
- id: 5,
- parent: 4,
- reportLeafIndex: 4,
- }
- ],
- id: 4,
- parent: 1,
- reportLeafIndex: undefined,
- },
- {
- name: "http://example.com/app.js",
- bytes: 0,
- totalBytes: 100,
- count: 0,
- totalCount: 10,
- children: [
- {
- name: "JSScript",
- bytes: 100,
- totalBytes: 100,
- count: 10,
- totalCount: 10,
- children: undefined,
- id: 3,
- parent: 2,
- reportLeafIndex: 2,
- }
- ],
- id: 2,
- parent: 1,
- reportLeafIndex: undefined,
- }
- ],
- id: 1,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-09.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-09.js
deleted file mode 100644
index 3efed04b0..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-09.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-/**
- * Test that repeatedly converting the same census report to a CensusTreeNode
- * tree results in the same CensusTreeNode tree.
- */
-
-function run_test() {
- const BREAKDOWN = {
- by: "filename",
- then: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
- },
- noFilename: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
- },
- };
-
- const REPORT = {
- "http://example.com/app.js": {
- JSScript: { count: 10, bytes: 100 }
- },
- "http://example.com/ads.js": {
- "js::LazyScript": { count: 20, bytes: 200 }
- },
- "http://example.com/trackers.js": {
- JSScript: { count: 30, bytes: 300 }
- },
- noFilename: {
- "js::jit::JitCode": { count: 40, bytes: 400 }
- }
- };
-
- const first = censusReportToCensusTreeNode(BREAKDOWN, REPORT);
- const second = censusReportToCensusTreeNode(BREAKDOWN, REPORT);
- const third = censusReportToCensusTreeNode(BREAKDOWN, REPORT);
-
- assertStructurallyEquivalent(first, second);
- assertStructurallyEquivalent(second, third);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-10.js b/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-10.js
deleted file mode 100644
index b7798f23f..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census-tree-node-10.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-/**
- * Test when multiple leaves in the census report map to the same node in an
- * inverted CensusReportTree.
- */
-
-function run_test() {
- const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- strings: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- };
-
- const REPORT = {
- objects: {
- Array: { count: 1, bytes: 10 },
- },
- other: {
- Array: { count: 1, bytes: 10 },
- },
- strings: { count: 0, bytes: 0 },
- scripts: { count: 0, bytes: 0 },
- };
-
- const node = censusReportToCensusTreeNode(BREAKDOWN, REPORT, { invert: true });
-
- equal(node.children[0].name, "Array");
- equal(node.children[0].reportLeafIndex.size, 2);
- dumpn(`node.children[0].reportLeafIndex = ${[...node.children[0].reportLeafIndex]}`);
- ok(node.children[0].reportLeafIndex.has(2));
- ok(node.children[0].reportLeafIndex.has(6));
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_01.js b/devtools/shared/heapsnapshot/tests/unit/test_census_diff_01.js
deleted file mode 100644
index 75977bccb..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_01.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test diffing census reports of breakdown by "internalType".
-
-const BREAKDOWN = {
- by: "internalType",
- then: { by: "count", count: true, bytes: true }
-};
-
-const REPORT1 = {
- "JSObject": {
- "count": 10,
- "bytes": 100,
- },
- "js::Shape": {
- "count": 50,
- "bytes": 500,
- },
- "JSString": {
- "count": 0,
- "bytes": 0,
- },
- "js::LazyScript": {
- "count": 1,
- "bytes": 10,
- },
-};
-
-const REPORT2 = {
- "JSObject": {
- "count": 11,
- "bytes": 110,
- },
- "js::Shape": {
- "count": 51,
- "bytes": 510,
- },
- "JSString": {
- "count": 1,
- "bytes": 1,
- },
- "js::BaseShape": {
- "count": 1,
- "bytes": 42,
- },
-};
-
-const EXPECTED = {
- "JSObject": {
- "count": 1,
- "bytes": 10,
- },
- "js::Shape": {
- "count": 1,
- "bytes": 10,
- },
- "JSString": {
- "count": 1,
- "bytes": 1,
- },
- "js::LazyScript": {
- "count": -1,
- "bytes": -10,
- },
- "js::BaseShape": {
- "count": 1,
- "bytes": 42,
- },
-};
-
-function run_test() {
- assertDiff(BREAKDOWN, REPORT1, REPORT2, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_02.js b/devtools/shared/heapsnapshot/tests/unit/test_census_diff_02.js
deleted file mode 100644
index 169e3f036..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_02.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test diffing census reports of breakdown by "count".
-
-const BREAKDOWN = { by: "count", count: true, bytes: true };
-
-const REPORT1 = {
- "count": 10,
- "bytes": 100,
-};
-
-const REPORT2 = {
- "count": 11,
- "bytes": 110,
-};
-
-const EXPECTED = {
- "count": 1,
- "bytes": 10,
-};
-
-function run_test() {
- assertDiff(BREAKDOWN, REPORT1, REPORT2, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_03.js b/devtools/shared/heapsnapshot/tests/unit/test_census_diff_03.js
deleted file mode 100644
index 6dbca3e40..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_03.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test diffing census reports of breakdown by "coarseType".
-
-const BREAKDOWN = {
- by: "coarseType",
- objects: { by: "count", count: true, bytes: true },
- scripts: { by: "count", count: true, bytes: true },
- strings: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
-};
-
-const REPORT1 = {
- objects: {
- count: 1,
- bytes: 10,
- },
- scripts: {
- count: 1,
- bytes: 10,
- },
- strings: {
- count: 1,
- bytes: 10,
- },
- other: {
- count: 3,
- bytes: 30,
- },
-};
-
-const REPORT2 = {
- objects: {
- count: 1,
- bytes: 10,
- },
- scripts: {
- count: 0,
- bytes: 0,
- },
- strings: {
- count: 2,
- bytes: 20,
- },
- other: {
- count: 4,
- bytes: 40,
- },
-};
-
-const EXPECTED = {
- objects: {
- count: 0,
- bytes: 0,
- },
- scripts: {
- count: -1,
- bytes: -10,
- },
- strings: {
- count: 1,
- bytes: 10,
- },
- other: {
- count: 1,
- bytes: 10,
- },
-};
-
-function run_test() {
- assertDiff(BREAKDOWN, REPORT1, REPORT2, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_04.js b/devtools/shared/heapsnapshot/tests/unit/test_census_diff_04.js
deleted file mode 100644
index a10097945..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_04.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test diffing census reports of breakdown by "objectClass".
-
-const BREAKDOWN = {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
-};
-
-const REPORT1 = {
- "Array": {
- count: 1,
- bytes: 100,
- },
- "Function": {
- count: 10,
- bytes: 10,
- },
- "other": {
- count: 10,
- bytes: 100,
- }
-};
-
-const REPORT2 = {
- "Object": {
- count: 1,
- bytes: 100,
- },
- "Function": {
- count: 20,
- bytes: 20,
- },
- "other": {
- count: 10,
- bytes: 100,
- }
-};
-
-const EXPECTED = {
- "Array": {
- count: -1,
- bytes: -100,
- },
- "Function": {
- count: 10,
- bytes: 10,
- },
- "other": {
- count: 0,
- bytes: 0,
- },
- "Object": {
- count: 1,
- bytes: 100,
- },
-};
-
-function run_test() {
- assertDiff(BREAKDOWN, REPORT1, REPORT2, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_05.js b/devtools/shared/heapsnapshot/tests/unit/test_census_diff_05.js
deleted file mode 100644
index b6d99f823..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_05.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test diffing census reports of breakdown by "allocationStack".
-
-const BREAKDOWN = {
- by: "allocationStack",
- then: { by: "count", count: true, bytes: true },
- noStack: { by: "count", count: true, bytes: true },
-};
-
-const stack1 = saveStack();
-const stack2 = saveStack();
-const stack3 = saveStack();
-
-const REPORT1 = new Map([
- [stack1, { "count": 10, "bytes": 100 }],
- [stack2, { "count": 1, "bytes": 10 }],
-]);
-
-const REPORT2 = new Map([
- [stack2, { "count": 10, "bytes": 100 }],
- [stack3, { "count": 1, "bytes": 10 }],
-]);
-
-const EXPECTED = new Map([
- [stack1, { "count": -10, "bytes": -100 }],
- [stack2, { "count": 9, "bytes": 90 }],
- [stack3, { "count": 1, "bytes": 10 }],
-]);
-
-function run_test() {
- assertDiff(BREAKDOWN, REPORT1, REPORT2, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_06.js b/devtools/shared/heapsnapshot/tests/unit/test_census_diff_06.js
deleted file mode 100644
index 430ff8c9c..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_diff_06.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test diffing census reports of a "complex" and "realistic" breakdown.
-
-const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "allocationStack",
- then: {
- by: "objectClass",
- then: { by: "count", count: false, bytes: true },
- other: { by: "count", count: false, bytes: true }
- },
- noStack: {
- by: "objectClass",
- then: { by: "count", count: false, bytes: true },
- other: { by: "count", count: false, bytes: true }
- }
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: false, bytes: true }
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: false, bytes: true }
- },
- other: {
- by: "internalType",
- then: { by: "count", count: false, bytes: true }
- },
-};
-
-const stack1 = saveStack();
-const stack2 = saveStack();
-const stack3 = saveStack();
-
-const REPORT1 = {
- objects: new Map([
- [stack1, { Function: { bytes: 1 },
- Object: { bytes: 2 },
- other: { bytes: 0 },
- }],
- [stack2, { Array: { bytes: 3 },
- Date: { bytes: 4 },
- other: { bytes: 0 },
- }],
- ["noStack", { Object: { bytes: 3 }}],
- ]),
- strings: {
- JSAtom: { bytes: 10 },
- JSLinearString: { bytes: 5 },
- },
- scripts: {
- JSScript: { bytes: 1 },
- "js::jit::JitCode": { bytes: 2 },
- },
- other: {
- "mozilla::dom::Thing": { bytes: 1 },
- }
-};
-
-const REPORT2 = {
- objects: new Map([
- [stack2, { Array: { bytes: 1 },
- Date: { bytes: 2 },
- other: { bytes: 3 },
- }],
- [stack3, { Function: { bytes: 1 },
- Object: { bytes: 2 },
- other: { bytes: 0 },
- }],
- ["noStack", { Object: { bytes: 3 }}],
- ]),
- strings: {
- JSAtom: { bytes: 5 },
- JSLinearString: { bytes: 10 },
- },
- scripts: {
- JSScript: { bytes: 2 },
- "js::LazyScript": { bytes: 42 },
- "js::jit::JitCode": { bytes: 1 },
- },
- other: {
- "mozilla::dom::OtherThing": { bytes: 1 },
- }
-};
-
-const EXPECTED = {
- "objects": new Map([
- [stack1, { Function: { bytes: -1 },
- Object: { bytes: -2 },
- other: { bytes: 0 },
- }],
- [stack2, { Array: { bytes: -2 },
- Date: { bytes: -2 },
- other: { bytes: 3 },
- }],
- [stack3, { Function: { bytes: 1 },
- Object: { bytes: 2 },
- other: { bytes: 0 },
- }],
- ["noStack", { Object: { bytes: 0 }}],
- ]),
- "scripts": {
- "JSScript": {
- "bytes": 1
- },
- "js::jit::JitCode": {
- "bytes": -1
- },
- "js::LazyScript": {
- "bytes": 42
- }
- },
- "strings": {
- "JSAtom": {
- "bytes": -5
- },
- "JSLinearString": {
- "bytes": 5
- }
- },
- "other": {
- "mozilla::dom::Thing": {
- "bytes": -1
- },
- "mozilla::dom::OtherThing": {
- "bytes": 1
- }
- }
-};
-
-function run_test() {
- assertDiff(BREAKDOWN, REPORT1, REPORT2, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_01.js b/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_01.js
deleted file mode 100644
index 57724d7c1..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_01.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test filtering basic CensusTreeNode trees.
-
-function run_test() {
- const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other:{
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- };
-
- const REPORT = {
- objects: {
- Array: { bytes: 50, count: 5 },
- UInt8Array: { bytes: 80, count: 8 },
- Int32Array: { bytes: 320, count: 32 },
- other: { bytes: 0, count: 0 },
- },
- scripts: {
- "js::jit::JitScript": { bytes: 30, count: 3 },
- },
- strings: {
- JSAtom: { bytes: 60, count: 6 },
- },
- other: {
- "js::Shape": { bytes: 80, count: 8 },
- }
- };
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 620,
- count: 0,
- totalCount: 62,
- children: [
- {
- name: "objects",
- bytes: 0,
- totalBytes: 450,
- count: 0,
- totalCount: 45,
- children: [
- {
- name: "Int32Array",
- bytes: 320,
- totalBytes: 320,
- count: 32,
- totalCount: 32,
- children: undefined,
- id: 15,
- parent: 14,
- reportLeafIndex: 4,
- },
- {
- name: "UInt8Array",
- bytes: 80,
- totalBytes: 80,
- count: 8,
- totalCount: 8,
- children: undefined,
- id: 16,
- parent: 14,
- reportLeafIndex: 3,
- },
- {
- name: "Array",
- bytes: 50,
- totalBytes: 50,
- count: 5,
- totalCount: 5,
- children: undefined,
- id: 17,
- parent: 14,
- reportLeafIndex: 2,
- }
- ],
- id: 14,
- parent: 13,
- reportLeafIndex: undefined,
- }
- ],
- id: 13,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED, { filter: "Array" });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_02.js b/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_02.js
deleted file mode 100644
index 0a57ce66d..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_02.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test filtering CensusTreeNode trees with an `allocationStack` breakdown.
-
-function run_test() {
- const countBreakdown = { by: "count", count: true, bytes: true };
-
- const BREAKDOWN = {
- by: "allocationStack",
- then: countBreakdown,
- noStack: countBreakdown,
- };
-
- let stack1, stack2, stack3, stack4, stack5;
-
- (function foo() {
- (function bar() {
- (function baz() {
- stack1 = saveStack(3);
- }());
- (function quux() {
- stack2 = saveStack(3);
- stack3 = saveStack(3);
- }());
- }());
- stack4 = saveStack(2);
- }());
-
- stack5 = saveStack(1);
-
- const REPORT = new Map([
- [stack1, { bytes: 10, count: 1 }],
- [stack2, { bytes: 20, count: 2 }],
- [stack3, { bytes: 30, count: 3 }],
- [stack4, { bytes: 40, count: 4 }],
- [stack5, { bytes: 50, count: 5 }],
- ["noStack", { bytes: 60, count: 6 }],
- ]);
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 210,
- count: 0,
- totalCount: 21,
- children: [
- {
- name: stack1.parent.parent,
- bytes: 0,
- totalBytes: 60,
- count: 0,
- totalCount: 6,
- children: [
- {
- name: stack2.parent,
- bytes: 0,
- totalBytes: 50,
- count: 0,
- totalCount: 5,
- children: [
- {
- name: stack3,
- bytes: 30,
- totalBytes: 30,
- count: 3,
- totalCount: 3,
- children: undefined,
- id: 15,
- parent: 14,
- reportLeafIndex: 3,
- },
- {
- name: stack2,
- bytes: 20,
- totalBytes: 20,
- count: 2,
- totalCount: 2,
- children: undefined,
- id: 16,
- parent: 14,
- reportLeafIndex: 2,
- }
- ],
- id: 14,
- parent: 13,
- reportLeafIndex: undefined,
- },
- {
- name: stack1.parent,
- bytes: 0,
- totalBytes: 10,
- count: 0,
- totalCount: 1,
- children: [
- {
- name: stack1,
- bytes: 10,
- totalBytes: 10,
- count: 1,
- totalCount: 1,
- children: undefined,
- id: 18,
- parent: 17,
- reportLeafIndex: 1,
- }
- ],
- id: 17,
- parent: 13,
- reportLeafIndex: undefined,
- }
- ],
- id: 13,
- parent: 12,
- reportLeafIndex: undefined,
- }
- ],
- id: 12,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED, { filter: "bar" });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_03.js b/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_03.js
deleted file mode 100644
index 2c69a14b8..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_03.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test filtering with no matches.
-
-function run_test() {
- const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- scripts: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- strings: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- other:{
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- };
-
- const REPORT = {
- objects: {
- Array: { bytes: 50, count: 5 },
- UInt8Array: { bytes: 80, count: 8 },
- Int32Array: { bytes: 320, count: 32 },
- other: { bytes: 0, count: 0 },
- },
- scripts: {
- "js::jit::JitScript": { bytes: 30, count: 3 },
- },
- strings: {
- JSAtom: { bytes: 60, count: 6 },
- },
- other: {
- "js::Shape": { bytes: 80, count: 8 },
- }
- };
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 620,
- count: 0,
- totalCount: 62,
- children: undefined,
- id: 13,
- parent: undefined,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED, { filter: "zzzzzzzzzzzzzzzzzzzz" });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_04.js b/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_04.js
deleted file mode 100644
index c9871436b..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_04.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the filtered nodes' counts and bytes are the same as they were when
-// unfiltered.
-
-function run_test() {
- const COUNT = { by: "count", count: true, bytes: true };
- const INTERNAL_TYPE = { by: "internalType", then: COUNT };
-
- const BREAKDOWN = {
- by: "coarseType",
- objects: { by: "objectClass", then: COUNT, other: COUNT },
- strings: COUNT,
- scripts: {
- by: "filename",
- then: INTERNAL_TYPE,
- noFilename: INTERNAL_TYPE
- },
- other: INTERNAL_TYPE,
- };
-
- const REPORT = {
- objects: {
- Function: {
- count: 7,
- bytes: 70
- },
- Array: {
- count: 6,
- bytes: 60
- }
- },
- scripts: {
- "http://mozilla.github.io/pdf.js/build/pdf.js": {
- "js::LazyScript": {
- count: 4,
- bytes: 40
- },
- }
- },
- strings: {
- count: 2,
- bytes: 20
- },
- other: {
- "js::Shape": {
- count: 1,
- bytes: 10
- }
- }
- };
-
- const EXPECTED = {
- name: null,
- bytes: 0,
- totalBytes: 200,
- count: 0,
- totalCount: 20,
- parent: undefined,
- children: [
- {
- name: "objects",
- bytes: 0,
- totalBytes: 130,
- count: 0,
- totalCount: 13,
- children: [
- {
- name: "Function",
- bytes: 70,
- totalBytes: 70,
- count: 7,
- totalCount: 7,
- id: 13,
- parent: 12,
- children: undefined,
- reportLeafIndex: 2,
- },
- {
- name: "Array",
- bytes: 60,
- totalBytes: 60,
- count: 6,
- totalCount: 6,
- id: 14,
- parent: 12,
- children: undefined,
- reportLeafIndex: 3,
- },
- ],
- id: 12,
- parent: 11,
- reportLeafIndex: undefined,
- }
- ],
- id: 11,
- reportLeafIndex: undefined,
- };
-
- compareCensusViewData(BREAKDOWN, REPORT, EXPECTED, { filter: "objects" });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_05.js b/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_05.js
deleted file mode 100644
index 1d1f4fa55..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_census_filtering_05.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that filtered and inverted allocation stack census trees are sorted
-// properly.
-
-function run_test() {
- const countBreakdown = { by: "count", count: true, bytes: true };
-
- const BREAKDOWN = {
- by: "allocationStack",
- then: countBreakdown,
- noStack: countBreakdown,
- };
-
- const stacks = [];
-
- function foo(depth = 1) {
- stacks.push(saveStack(depth));
- bar(depth + 1);
- baz(depth + 1);
- stacks.push(saveStack(depth));
- }
-
- function bar(depth = 1) {
- stacks.push(saveStack(depth));
- stacks.push(saveStack(depth));
- }
-
- function baz(depth = 1) {
- stacks.push(saveStack(depth));
- bang(depth + 1);
- stacks.push(saveStack(depth));
- }
-
- function bang(depth = 1) {
- stacks.push(saveStack(depth));
- stacks.push(saveStack(depth));
- stacks.push(saveStack(depth));
- }
-
- foo();
- bar();
- baz();
- bang();
-
- const REPORT = new Map(stacks.map((s, i) => {
- return [s, {
- count: i + 1,
- bytes: (i + 1) * 10
- }];
- }));
-
- const tree = censusReportToCensusTreeNode(BREAKDOWN, REPORT, {
- filter: "baz",
- invert: true
- });
-
- dumpn("tree = " + JSON.stringify(tree, savedFrameReplacer, 4));
-
- (function assertSortedBySelf(node) {
- if (node.children) {
- let lastSelfBytes = Infinity;
- for (let child of node.children) {
- ok(child.bytes <= lastSelfBytes, `${child.bytes} <= ${lastSelfBytes}`);
- lastSelfBytes = child.bytes;
- assertSortedBySelf(child);
- }
- }
- }(tree));
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_countToBucketBreakdown_01.js b/devtools/shared/heapsnapshot/tests/unit/test_countToBucketBreakdown_01.js
deleted file mode 100644
index e89048c33..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_countToBucketBreakdown_01.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test that we can turn a breakdown with { by: "count" } leaves into a
-// breakdown with { by: "bucket" } leaves.
-
-const COUNT = { by: "count", count: true, bytes: true };
-const BUCKET = { by: "bucket" };
-
-const BREAKDOWN = {
- by: "coarseType",
- objects: { by: "objectClass", then: COUNT, other: COUNT },
- strings: COUNT,
- scripts: {
- by: "filename",
- then: { by: "internalType", then: COUNT },
- noFilename: { by: "internalType", then: COUNT },
- },
- other: { by: "internalType", then: COUNT },
-};
-
-const EXPECTED = {
- by: "coarseType",
- objects: { by: "objectClass", then: BUCKET, other: BUCKET },
- strings: BUCKET,
- scripts: {
- by: "filename",
- then: { by: "internalType", then: BUCKET },
- noFilename: { by: "internalType", then: BUCKET },
- },
- other: { by: "internalType", then: BUCKET },
-};
-
-function run_test() {
- assertCountToBucketBreakdown(BREAKDOWN, EXPECTED);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_deduplicatePaths_01.js b/devtools/shared/heapsnapshot/tests/unit/test_deduplicatePaths_01.js
deleted file mode 100644
index 418b49db3..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_deduplicatePaths_01.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test the behavior of the deduplicatePaths utility function.
-
-function edge(from, to, name) {
- return { from, to, name };
-}
-
-function run_test() {
- const a = 1;
- const b = 2;
- const c = 3;
- const d = 4;
- const e = 5;
- const f = 6;
- const g = 7;
-
- dumpn("Single long path");
- assertDeduplicatedPaths({
- target: g,
- paths: [
- [
- pathEntry(a, "e1"),
- pathEntry(b, "e2"),
- pathEntry(c, "e3"),
- pathEntry(d, "e4"),
- pathEntry(e, "e5"),
- pathEntry(f, "e6"),
- ]
- ],
- expectedNodes: [a, b, c, d, e, f, g],
- expectedEdges: [
- edge(a, b, "e1"),
- edge(b, c, "e2"),
- edge(c, d, "e3"),
- edge(d, e, "e4"),
- edge(e, f, "e5"),
- edge(f, g, "e6"),
- ]
- });
-
- dumpn("Multiple edges from and to the same nodes");
- assertDeduplicatedPaths({
- target: a,
- paths: [
- [pathEntry(b, "x")],
- [pathEntry(b, "y")],
- [pathEntry(b, "z")],
- ],
- expectedNodes: [a, b],
- expectedEdges: [
- edge(b, a, "x"),
- edge(b, a, "y"),
- edge(b, a, "z"),
- ]
- });
-
- dumpn("Multiple paths sharing some nodes and edges");
- assertDeduplicatedPaths({
- target: g,
- paths: [
- [
- pathEntry(a, "a->b"),
- pathEntry(b, "b->c"),
- pathEntry(c, "foo"),
- ],
- [
- pathEntry(a, "a->b"),
- pathEntry(b, "b->d"),
- pathEntry(d, "bar"),
- ],
- [
- pathEntry(a, "a->b"),
- pathEntry(b, "b->e"),
- pathEntry(e, "baz"),
- ],
- ],
- expectedNodes: [a, b, c, d, e, g],
- expectedEdges: [
- edge(a, b, "a->b"),
- edge(b, c, "b->c"),
- edge(b, d, "b->d"),
- edge(b, e, "b->e"),
- edge(c, g, "foo"),
- edge(d, g, "bar"),
- edge(e, g, "baz"),
- ]
- });
-
- dumpn("Second shortest path contains target itself");
- assertDeduplicatedPaths({
- target: g,
- paths: [
- [
- pathEntry(a, "a->b"),
- pathEntry(b, "b->g"),
- ],
- [
- pathEntry(a, "a->b"),
- pathEntry(b, "b->g"),
- pathEntry(g, "g->f"),
- pathEntry(f, "f->g"),
- ],
- ],
- expectedNodes: [a, b, g],
- expectedEdges: [
- edge(a, b, "a->b"),
- edge(b, g, "b->g"),
- ]
- });
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_getCensusIndividuals_01.js b/devtools/shared/heapsnapshot/tests/unit/test_getCensusIndividuals_01.js
deleted file mode 100644
index 9c4f60991..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_getCensusIndividuals_01.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test basic functionality of `CensusUtils.getCensusIndividuals`.
-
-function run_test() {
- const stack1 = saveStack(1);
- const stack2 = saveStack(1);
- const stack3 = saveStack(1);
-
- const COUNT = { by: "count", count: true, bytes: true };
- const INTERNAL_TYPE = { by: "internalType", then: COUNT };
-
- const BREAKDOWN = {
- by: "allocationStack",
- then: INTERNAL_TYPE,
- noStack: INTERNAL_TYPE,
- };
-
- const MOCK_SNAPSHOT = {
- takeCensus: ({ breakdown }) => {
- assertStructurallyEquivalent(
- breakdown,
- CensusUtils.countToBucketBreakdown(BREAKDOWN));
-
- // DFS Index
- return new Map([ // 0
- [stack1, { // 1
- JSObject: [101, 102, 103], // 2
- JSString: [111, 112, 113], // 3
- }],
- [stack2, { // 4
- JSObject: [201, 202, 203], // 5
- JSString: [211, 212, 213], // 6
- }],
- [stack3, { // 7
- JSObject: [301, 302, 303], // 8
- JSString: [311, 312, 313], // 9
- }],
- ["noStack", { // 10
- JSObject: [401, 402, 403], // 11
- JSString: [411, 412, 413], // 12
- }],
- ]);
- }
- };
-
- const INDICES = new Set([3, 5, 9]);
-
- const EXPECTED = new Set([111, 112, 113,
- 201, 202, 203,
- 311, 312, 313]);
-
- const actual = new Set(CensusUtils.getCensusIndividuals(INDICES,
- BREAKDOWN,
- MOCK_SNAPSHOT));
-
- assertStructurallyEquivalent(EXPECTED, actual);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_getReportLeaves_01.js b/devtools/shared/heapsnapshot/tests/unit/test_getReportLeaves_01.js
deleted file mode 100644
index 4c4298b6a..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_getReportLeaves_01.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-// Test basic functionality of `CensusUtils.getReportLeaves`.
-
-function run_test() {
- const BREAKDOWN = {
- by: "coarseType",
- objects: {
- by: "objectClass",
- then: { by: "count", count: true, bytes: true },
- other: { by: "count", count: true, bytes: true },
- },
- strings: { by: "count", count: true, bytes: true },
- scripts: {
- by: "filename",
- then: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- noFilename: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- },
- other: {
- by: "internalType",
- then: { by: "count", count: true, bytes: true },
- },
- };
-
- const REPORT = {
- objects: {
- Array: { count: 6, bytes: 60 },
- Function: { count: 1, bytes: 10 },
- Object: { count: 1, bytes: 10 },
- RegExp: { count: 1, bytes: 10 },
- other: { count: 0, bytes: 0 },
- },
- strings: { count: 1, bytes: 10 },
- scripts: {
- "foo.js": {
- JSScript: { count: 1, bytes: 10 },
- "js::jit::IonScript": { count: 1, bytes: 10 },
- },
- noFilename: {
- JSScript: { count: 1, bytes: 10 },
- "js::jit::IonScript": { count: 1, bytes: 10 },
- },
- },
- other: {
- "js::Shape": { count: 7, bytes: 70 },
- "js::BaseShape": { count: 1, bytes: 10 },
- },
- };
-
- const root = censusReportToCensusTreeNode(BREAKDOWN, REPORT);
- dumpn("CensusTreeNode tree = " + JSON.stringify(root, null, 4));
-
- (function assertEveryNodeCanFindItsLeaf(node) {
- if (node.reportLeafIndex) {
- const [ leaf ] = CensusUtils.getReportLeaves(new Set([node.reportLeafIndex]),
- BREAKDOWN,
- REPORT);
- ok(leaf, "Should be able to find leaf for a node with a reportLeafIndex = " + node.reportLeafIndex);
- }
-
- if (node.children) {
- for (let child of node.children) {
- assertEveryNodeCanFindItsLeaf(child);
- }
- }
- }(root));
-
- // Test finding multiple leaves at a time.
-
- function find(name, node) {
- if (node.name === name) {
- return node;
- }
-
- if (node.children) {
- for (let child of node.children) {
- const found = find(name, child);
- if (found) {
- return found;
- }
- }
- }
- }
-
- const arrayNode = find("Array", root);
- ok(arrayNode);
- equal(typeof arrayNode.reportLeafIndex, "number");
-
- const shapeNode = find("js::Shape", root);
- ok(shapeNode);
- equal(typeof shapeNode.reportLeafIndex, "number");
-
- const indices = new Set([arrayNode.reportLeafIndex, shapeNode.reportLeafIndex]);
- const leaves = CensusUtils.getReportLeaves(indices, BREAKDOWN, REPORT);
- equal(leaves.length, 2);
-
- // `getReportLeaves` does not guarantee order of the results, so handle both
- // cases.
- ok(leaves.some(l => l === REPORT.objects.Array));
- ok(leaves.some(l => l === REPORT.other["js::Shape"]));
-
- // Test that bad indices do not yield results.
-
- const none = CensusUtils.getReportLeaves(new Set([999999999999]), BREAKDOWN, REPORT);
- equal(none.length, 0);
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/test_saveHeapSnapshot_e10s_01.js b/devtools/shared/heapsnapshot/tests/unit/test_saveHeapSnapshot_e10s_01.js
deleted file mode 100644
index 067b9effb..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/test_saveHeapSnapshot_e10s_01.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test saving a heap snapshot in the sandboxed e10s child process.
-
-function run_test() {
- run_test_in_child("../unit/test_SaveHeapSnapshot.js");
-}
diff --git a/devtools/shared/heapsnapshot/tests/unit/xpcshell.ini b/devtools/shared/heapsnapshot/tests/unit/xpcshell.ini
deleted file mode 100644
index f84b282d1..000000000
--- a/devtools/shared/heapsnapshot/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,98 +0,0 @@
-[DEFAULT]
-tags = devtools heapsnapshot devtools-memory
-head = head_heapsnapshot.js
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-
-support-files =
- Census.jsm
- dominator-tree-worker.js
- heap-snapshot-worker.js
- Match.jsm
-
-[test_census_diff_01.js]
-[test_census_diff_02.js]
-[test_census_diff_03.js]
-[test_census_diff_04.js]
-[test_census_diff_05.js]
-[test_census_diff_06.js]
-[test_census_filtering_01.js]
-[test_census_filtering_02.js]
-[test_census_filtering_03.js]
-[test_census_filtering_04.js]
-[test_census_filtering_05.js]
-[test_census-tree-node-01.js]
-[test_census-tree-node-02.js]
-[test_census-tree-node-03.js]
-[test_census-tree-node-04.js]
-[test_census-tree-node-05.js]
-[test_census-tree-node-06.js]
-[test_census-tree-node-07.js]
-[test_census-tree-node-08.js]
-[test_census-tree-node-09.js]
-[test_census-tree-node-10.js]
-[test_countToBucketBreakdown_01.js]
-[test_deduplicatePaths_01.js]
-[test_DominatorTree_01.js]
-[test_DominatorTree_02.js]
-[test_DominatorTree_03.js]
-[test_DominatorTree_04.js]
-[test_DominatorTree_05.js]
-[test_DominatorTree_06.js]
-[test_DominatorTreeNode_attachShortestPaths_01.js]
-[test_DominatorTreeNode_getNodeByIdAlongPath_01.js]
-[test_DominatorTreeNode_insert_01.js]
-[test_DominatorTreeNode_insert_02.js]
-[test_DominatorTreeNode_insert_03.js]
-[test_DominatorTreeNode_LabelAndShallowSize_01.js]
-[test_DominatorTreeNode_LabelAndShallowSize_02.js]
-[test_DominatorTreeNode_LabelAndShallowSize_03.js]
-[test_DominatorTreeNode_LabelAndShallowSize_04.js]
-[test_DominatorTreeNode_partialTraversal_01.js]
-[test_getCensusIndividuals_01.js]
-[test_getReportLeaves_01.js]
-[test_HeapAnalyses_computeDominatorTree_01.js]
-[test_HeapAnalyses_computeDominatorTree_02.js]
-[test_HeapAnalyses_deleteHeapSnapshot_01.js]
-[test_HeapAnalyses_deleteHeapSnapshot_02.js]
-[test_HeapAnalyses_deleteHeapSnapshot_03.js]
-[test_HeapAnalyses_getCensusIndividuals_01.js]
-[test_HeapAnalyses_getCreationTime_01.js]
-[test_HeapAnalyses_getDominatorTree_01.js]
-[test_HeapAnalyses_getDominatorTree_02.js]
-[test_HeapAnalyses_getImmediatelyDominated_01.js]
-[test_HeapAnalyses_readHeapSnapshot_01.js]
-[test_HeapAnalyses_takeCensusDiff_01.js]
-[test_HeapAnalyses_takeCensusDiff_02.js]
-[test_HeapAnalyses_takeCensus_01.js]
-[test_HeapAnalyses_takeCensus_02.js]
-[test_HeapAnalyses_takeCensus_03.js]
-[test_HeapAnalyses_takeCensus_04.js]
-[test_HeapAnalyses_takeCensus_05.js]
-[test_HeapAnalyses_takeCensus_06.js]
-[test_HeapAnalyses_takeCensus_07.js]
-[test_HeapSnapshot_creationTime_01.js]
-[test_HeapSnapshot_deepStack_01.js]
-[test_HeapSnapshot_describeNode_01.js]
-[test_HeapSnapshot_computeShortestPaths_01.js]
-[test_HeapSnapshot_computeShortestPaths_02.js]
-[test_HeapSnapshot_takeCensus_01.js]
-[test_HeapSnapshot_takeCensus_02.js]
-[test_HeapSnapshot_takeCensus_03.js]
-[test_HeapSnapshot_takeCensus_04.js]
-[test_HeapSnapshot_takeCensus_05.js]
-[test_HeapSnapshot_takeCensus_06.js]
-[test_HeapSnapshot_takeCensus_07.js]
-[test_HeapSnapshot_takeCensus_08.js]
-[test_HeapSnapshot_takeCensus_09.js]
-[test_HeapSnapshot_takeCensus_10.js]
-[test_HeapSnapshot_takeCensus_11.js]
-[test_HeapSnapshot_takeCensus_12.js]
-[test_ReadHeapSnapshot.js]
-[test_ReadHeapSnapshot_with_allocations.js]
-skip-if = os == 'linux' # Bug 1176173
-[test_ReadHeapSnapshot_worker.js]
-skip-if = os == 'linux' # Bug 1176173
-[test_SaveHeapSnapshot.js]
-[test_saveHeapSnapshot_e10s_01.js]