From ffd963dd3fb816e65fed642d888e621700888d46 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 16 Dec 2015 09:19:00 +0100 Subject: [PATCH] Bug 1231763 - Extract breakdown parsing from JS::ubi::Census. r=jimb --- .../shared/heapsnapshot/DominatorTree.cpp | 18 +- devtools/shared/heapsnapshot/HeapSnapshot.cpp | 16 +- devtools/shared/heapsnapshot/HeapSnapshot.h | 3 + js/public/UbiNodeCensus.h | 51 ++-- js/src/vm/DebuggerMemory.cpp | 4 +- js/src/vm/UbiNodeCensus.cpp | 267 ++++++++---------- 6 files changed, 169 insertions(+), 190 deletions(-) diff --git a/devtools/shared/heapsnapshot/DominatorTree.cpp b/devtools/shared/heapsnapshot/DominatorTree.cpp index 96f0e68593f2..e53c196cf3e1 100644 --- a/devtools/shared/heapsnapshot/DominatorTree.cpp +++ b/devtools/shared/heapsnapshot/DominatorTree.cpp @@ -4,25 +4,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/devtools/DominatorTree.h" -#include "js/Debug.h" -#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/dom/DominatorTreeBinding.h" namespace mozilla { namespace devtools { -static MallocSizeOf -getCurrentThreadDebuggerMallocSizeOf() -{ - auto ccrt = CycleCollectedJSRuntime::Get(); - MOZ_ASSERT(ccrt); - auto rt = ccrt->Runtime(); - MOZ_ASSERT(rt); - auto mallocSizeOf = JS::dbg::GetDebuggerMallocSizeOf(rt); - MOZ_ASSERT(mallocSizeOf); - return mallocSizeOf; -} - dom::Nullable DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv) { @@ -31,7 +17,7 @@ DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv) if (node.isNothing()) return dom::Nullable(); - auto mallocSizeOf = getCurrentThreadDebuggerMallocSizeOf(); + auto mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf(); JS::ubi::Node::Size size = 0; if (!mDominatorTree.getRetainedSize(*node, mallocSizeOf, size)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); @@ -83,7 +69,7 @@ DominatorTree::GetImmediatelyDominated(uint64_t aNodeId, return; // Get all immediately dominated nodes and their retained sizes. - MallocSizeOf mallocSizeOf = getCurrentThreadDebuggerMallocSizeOf(); + MallocSizeOf mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf(); Maybe 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(); diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.cpp b/devtools/shared/heapsnapshot/HeapSnapshot.cpp index 854bd3cdc949..9cae51a56ea9 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp +++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp @@ -55,6 +55,18 @@ using ::google::protobuf::io::ZeroCopyInputStream; using JS::ubi::AtomOrTwoByteChars; +MallocSizeOf +GetCurrentThreadDebuggerMallocSizeOf() +{ + auto ccrt = CycleCollectedJSRuntime::Get(); + MOZ_ASSERT(ccrt); + auto rt = ccrt->Runtime(); + MOZ_ASSERT(rt); + auto mallocSizeOf = JS::dbg::GetDebuggerMallocSizeOf(rt); + MOZ_ASSERT(mallocSizeOf); + return mallocSizeOf; +} + /*** Cycle Collection Boilerplate *****************************************************************/ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HeapSnapshot, mParent) @@ -482,7 +494,7 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options, return; } - JS::ubi::CensusHandler handler(census, rootCount); + JS::ubi::CensusHandler handler(census, rootCount, GetCurrentThreadDebuggerMallocSizeOf()); { JS::AutoCheckCannotGC nogc; @@ -504,7 +516,7 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options, } } - if (NS_WARN_IF(!handler.report(rval))) { + if (NS_WARN_IF(!handler.report(cx, rval))) { rv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.h b/devtools/shared/heapsnapshot/HeapSnapshot.h index c869c74ae5dc..c8e4557c4790 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.h +++ b/devtools/shared/heapsnapshot/HeapSnapshot.h @@ -221,6 +221,9 @@ WriteHeapGraph(JSContext* cx, ignoreNodeCount, ignoreEdgeCount); } +// Get the mozilla::MallocSizeOf for the current thread's JSRuntime. +MallocSizeOf GetCurrentThreadDebuggerMallocSizeOf(); + } // namespace devtools } // namespace mozilla diff --git a/js/public/UbiNodeCensus.h b/js/public/UbiNodeCensus.h index e881eb188483..891694efa07d 100644 --- a/js/public/UbiNodeCensus.h +++ b/js/public/UbiNodeCensus.h @@ -87,7 +87,7 @@ using CountBasePtr = UniquePtr; // Abstract base class for CountType nodes. struct CountType { - explicit CountType(Census& census) : census(census) { } + explicit CountType() { } virtual ~CountType() { } // Destruct a count tree node that this type instance constructed. @@ -102,14 +102,13 @@ struct CountType { // Implement the 'count' method for counts returned by this CountType // instance's 'newCount' method. - virtual bool count(CountBase& count, const Node& node) = 0; + virtual bool count(CountBase& count, + mozilla::MallocSizeOf mallocSizeOf, + const Node& node) = 0; // Implement the 'report' method for counts returned by this CountType // instance's 'newCount' method. - virtual bool report(CountBase& count, MutableHandleValue report) = 0; - - protected: - Census& census; + virtual bool report(JSContext* cx, CountBase& count, MutableHandleValue report) = 0; }; using CountTypePtr = UniquePtr>; @@ -129,12 +128,16 @@ class CountBase { explicit CountBase(CountType& type) : type(type), total_(0) { } // Categorize and count |node| as appropriate for this count's type. - bool count(const Node& node) { return type.count(*this, node); } + bool count(mozilla::MallocSizeOf mallocSizeOf, const Node& node) { + return type.count(*this, mallocSizeOf, node); + } // Construct a JavaScript object reporting the counts recorded in this // count, and store it in |report|. Return true on success, or false on // failure. - bool report(MutableHandleValue report) { return type.report(*this, report); } + bool report(JSContext* cx, MutableHandleValue report) { + return type.report(cx, *this, report); + } // Down-cast this CountBase to its true type, based on its 'type' member, // and run its destructor. @@ -173,18 +176,6 @@ struct Census { explicit Census(JSContext* cx) : cx(cx), atomsZone(nullptr) { } bool init(); - - // A 'new' work-alike that behaves like TempAllocPolicy: report OOM on this - // census's context, but don't charge the memory allocated to our context's - // GC pressure counters. - template - T* new_(Args&&... args) MOZ_HEAP_ALLOCATOR { - void* memory = js_malloc(sizeof(T)); - if (MOZ_UNLIKELY(!memory)) { - return nullptr; - } - return new(memory) T(mozilla::Forward(args)...); - } }; // A BreadthFirst handler type that conducts a census, using a CountBase to @@ -192,15 +183,17 @@ struct Census { class CensusHandler { Census& census; CountBasePtr& rootCount; + mozilla::MallocSizeOf mallocSizeOf; public: - CensusHandler(Census& census, CountBasePtr& rootCount) + CensusHandler(Census& census, CountBasePtr& rootCount, mozilla::MallocSizeOf mallocSizeOf) : census(census), - rootCount(rootCount) + rootCount(rootCount), + mallocSizeOf(mallocSizeOf) { } - bool report(MutableHandleValue report) { - return rootCount->report(report); + bool report(JSContext* cx, MutableHandleValue report) { + return rootCount->report(cx, report); } // This class needs to retain no per-node data. @@ -213,11 +206,17 @@ class CensusHandler { using CensusTraversal = BreadthFirst; -// Examine the census options supplied by the API consumer, and use that to -// build a CountType tree. +// Examine the census options supplied by the API consumer, and (among other +// things) use that to build a CountType tree. bool ParseCensusOptions(JSContext* cx, Census& census, HandleObject options, CountTypePtr& outResult); +// Parse the breakdown language (as described in +// js/src/doc/Debugger/Debugger.Memory.md) into a CountTypePtr. A null pointer +// is returned on error and is reported to the cx. +CountTypePtr ParseBreakdown(JSContext* cx, HandleValue breakdownValue); + + } // namespace ubi } // namespace JS diff --git a/js/src/vm/DebuggerMemory.cpp b/js/src/vm/DebuggerMemory.cpp index 950c7524a4e4..f763dcc09828 100644 --- a/js/src/vm/DebuggerMemory.cpp +++ b/js/src/vm/DebuggerMemory.cpp @@ -539,7 +539,7 @@ DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) JS::ubi::RootedCount rootCount(cx, rootType->makeCount()); if (!rootCount) return false; - JS::ubi::CensusHandler handler(census, rootCount); + JS::ubi::CensusHandler handler(census, rootCount, cx->runtime()->debuggerMallocSizeOf); Debugger* dbg = memory->getDebugger(); RootedObject dbgObj(cx, dbg->object); @@ -573,7 +573,7 @@ DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) } } - return handler.report(args.rval()); + return handler.report(cx, args.rval()); } diff --git a/js/src/vm/UbiNodeCensus.cpp b/js/src/vm/UbiNodeCensus.cpp index 93bb04b64991..1f9b293cb7f4 100644 --- a/js/src/vm/UbiNodeCensus.cpp +++ b/js/src/vm/UbiNodeCensus.cpp @@ -54,18 +54,17 @@ class SimpleCount : public CountType { bool reportBytes : 1; public: - SimpleCount(Census& census, - UniquePtr& label, - bool reportCount=true, - bool reportBytes=true) - : CountType(census), + explicit SimpleCount(UniquePtr& label, + bool reportCount=true, + bool reportBytes=true) + : CountType(), label(Move(label)), reportCount(reportCount), reportBytes(reportBytes) { } - explicit SimpleCount(Census& census) - : CountType(census), + explicit SimpleCount() + : CountType(), label(nullptr), reportCount(true), reportBytes(true) @@ -76,45 +75,45 @@ class SimpleCount : public CountType { count.~Count(); } - CountBasePtr makeCount() override { return CountBasePtr(census.new_(*this)); } + CountBasePtr makeCount() override { return CountBasePtr(js_new(*this)); } void traceCount(CountBase& countBase, JSTracer* trc) override { } - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; bool -SimpleCount::count(CountBase& countBase, const Node& node) +SimpleCount::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; if (reportBytes) - count.totalBytes_ += node.size(census.cx->runtime()->debuggerMallocSizeOf); + count.totalBytes_ += node.size(mallocSizeOf); return true; } bool -SimpleCount::report(CountBase& countBase, MutableHandleValue report) +SimpleCount::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - RootedPlainObject obj(census.cx, NewBuiltinClassInstance(census.cx)); + RootedPlainObject obj(cx, NewBuiltinClassInstance(cx)); if (!obj) return false; - RootedValue countValue(census.cx, NumberValue(count.total_)); - if (reportCount && !DefineProperty(census.cx, obj, census.cx->names().count, countValue)) + RootedValue countValue(cx, NumberValue(count.total_)); + if (reportCount && !DefineProperty(cx, obj, cx->names().count, countValue)) return false; - RootedValue bytesValue(census.cx, NumberValue(count.totalBytes_)); - if (reportBytes && !DefineProperty(census.cx, obj, census.cx->names().bytes, bytesValue)) + RootedValue bytesValue(cx, NumberValue(count.totalBytes_)); + if (reportBytes && !DefineProperty(cx, obj, cx->names().bytes, bytesValue)) return false; if (label) { - JSString* labelString = JS_NewUCStringCopyZ(census.cx, label.get()); + JSString* labelString = JS_NewUCStringCopyZ(cx, label.get()); if (!labelString) return false; - RootedValue labelValue(census.cx, StringValue(labelString)); - if (!DefineProperty(census.cx, obj, census.cx->names().label, labelValue)) + RootedValue labelValue(cx, StringValue(labelString)); + if (!DefineProperty(cx, obj, cx->names().label, labelValue)) return false; } @@ -155,12 +154,11 @@ class ByCoarseType : public CountType { }; public: - ByCoarseType(Census& census, - CountTypePtr& objects, + ByCoarseType(CountTypePtr& objects, CountTypePtr& scripts, CountTypePtr& strings, CountTypePtr& other) - : CountType(census), + : CountType(), objects(Move(objects)), scripts(Move(scripts)), strings(Move(strings)), @@ -174,8 +172,8 @@ class ByCoarseType : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -189,11 +187,11 @@ ByCoarseType::makeCount() if (!objectsCount || !scriptsCount || !stringsCount || !otherCount) return CountBasePtr(nullptr); - return CountBasePtr(census.new_(*this, - objectsCount, - scriptsCount, - stringsCount, - otherCount)); + return CountBasePtr(js_new(*this, + objectsCount, + scriptsCount, + stringsCount, + otherCount)); } void @@ -207,20 +205,20 @@ ByCoarseType::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByCoarseType::count(CountBase& countBase, const Node& node) +ByCoarseType::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; switch (node.coarseType()) { case JS::ubi::CoarseType::Object: - return count.objects->count(node); + return count.objects->count(mallocSizeOf, node); case JS::ubi::CoarseType::Script: - return count.scripts->count(node); + return count.scripts->count(mallocSizeOf, node); case JS::ubi::CoarseType::String: - return count.strings->count(node); + return count.strings->count(mallocSizeOf, node); case JS::ubi::CoarseType::Other: - return count.other->count(node); + return count.other->count(mallocSizeOf, node); default: MOZ_CRASH("bad JS::ubi::CoarseType in JS::ubi::ByCoarseType::count"); return false; @@ -228,32 +226,31 @@ ByCoarseType::count(CountBase& countBase, const Node& node) } bool -ByCoarseType::report(CountBase& countBase, MutableHandleValue report) +ByCoarseType::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; RootedPlainObject obj(cx, NewBuiltinClassInstance(cx)); if (!obj) return false; RootedValue objectsReport(cx); - if (!count.objects->report(&objectsReport) || + if (!count.objects->report(cx, &objectsReport) || !DefineProperty(cx, obj, cx->names().objects, objectsReport)) return false; RootedValue scriptsReport(cx); - if (!count.scripts->report(&scriptsReport) || + if (!count.scripts->report(cx, &scriptsReport) || !DefineProperty(cx, obj, cx->names().scripts, scriptsReport)) return false; RootedValue stringsReport(cx); - if (!count.strings->report(&stringsReport) || + if (!count.strings->report(cx, &stringsReport) || !DefineProperty(cx, obj, cx->names().strings, stringsReport)) return false; RootedValue otherReport(cx); - if (!count.other->report(&otherReport) || + if (!count.other->report(cx, &otherReport) || !DefineProperty(cx, obj, cx->names().other, otherReport)) return false; @@ -320,7 +317,7 @@ cStringCountMapToObject(JSContext* cx, CStringCountMap& map) { for (auto& entry : entries) { CountBasePtr& thenCount = entry->value(); RootedValue thenReport(cx); - if (!thenCount->report(&thenReport)) + if (!thenCount->report(cx, &thenReport)) return nullptr; const char* name = entry->key(); @@ -365,10 +362,8 @@ class ByObjectClass : public CountType { CountTypePtr otherType; public: - ByObjectClass(Census& census, - CountTypePtr& classesType, - CountTypePtr& otherType) - : CountType(census), + ByObjectClass(CountTypePtr& classesType, CountTypePtr& otherType) + : CountType(), classesType(Move(classesType)), otherType(Move(otherType)) { } @@ -380,8 +375,8 @@ class ByObjectClass : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -391,7 +386,7 @@ ByObjectClass::makeCount() if (!otherCount) return nullptr; - UniquePtr count(census.new_(*this, otherCount)); + UniquePtr count(js_new(*this, otherCount)); if (!count || !count->init()) return nullptr; @@ -408,14 +403,14 @@ ByObjectClass::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByObjectClass::count(CountBase& countBase, const Node& node) +ByObjectClass::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; const char* className = node.jsObjectClassName(); if (!className) - return count.other->count(node); + return count.other->count(mallocSizeOf, node); Table::AddPtr p = count.table.lookupForAdd(className); if (!p) { @@ -423,21 +418,20 @@ ByObjectClass::count(CountBase& countBase, const Node& node) if (!classCount || !count.table.add(p, className, Move(classCount))) return false; } - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } bool -ByObjectClass::report(CountBase& countBase, MutableHandleValue report) +ByObjectClass::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; RootedPlainObject obj(cx, cStringCountMapToObject(cx, count.table)); if (!obj) return false; RootedValue otherReport(cx); - if (!count.other->report(&otherReport) || + if (!count.other->report(cx, &otherReport) || !DefineProperty(cx, obj, cx->names().other, otherReport)) return false; @@ -466,8 +460,8 @@ class ByUbinodeType : public CountType { CountTypePtr entryType; public: - ByUbinodeType(Census& census, CountTypePtr& entryType) - : CountType(census), + explicit ByUbinodeType(CountTypePtr& entryType) + : CountType(), entryType(Move(entryType)) { } @@ -478,14 +472,14 @@ class ByUbinodeType : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr ByUbinodeType::makeCount() { - UniquePtr count(census.new_(*this)); + UniquePtr count(js_new(*this)); if (!count || !count->init()) return nullptr; @@ -501,7 +495,7 @@ ByUbinodeType::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByUbinodeType::count(CountBase& countBase, const Node& node) +ByUbinodeType::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; @@ -514,14 +508,13 @@ ByUbinodeType::count(CountBase& countBase, const Node& node) if (!typesCount || !count.table.add(p, key, Move(typesCount))) return false; } - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } bool -ByUbinodeType::report(CountBase& countBase, MutableHandleValue report) +ByUbinodeType::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; // Build a vector of pointers to entries; sort by total; and then use // that to build the result object. This makes the ordering of entries @@ -541,7 +534,7 @@ ByUbinodeType::report(CountBase& countBase, MutableHandleValue report) Entry& entry = **entryPtr; CountBasePtr& typeCount = entry.value(); RootedValue typeReport(cx); - if (!typeCount->report(&typeReport)) + if (!typeCount->report(cx, &typeReport)) return false; const char16_t* name = entry.key(); @@ -609,8 +602,8 @@ class ByAllocationStack : public CountType { CountTypePtr noStackType; public: - ByAllocationStack(Census& census, CountTypePtr& entryType, CountTypePtr& noStackType) - : CountType(census), + ByAllocationStack(CountTypePtr& entryType, CountTypePtr& noStackType) + : CountType(), entryType(Move(entryType)), noStackType(Move(noStackType)) { } @@ -622,8 +615,8 @@ class ByAllocationStack : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -633,7 +626,7 @@ ByAllocationStack::makeCount() if (!noStackCount) return nullptr; - UniquePtr count(census.new_(*this, noStackCount)); + UniquePtr count(js_new(*this, noStackCount)); if (!count || !count->init()) return nullptr; return CountBasePtr(count.release()); @@ -657,7 +650,7 @@ ByAllocationStack::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByAllocationStack::count(CountBase& countBase, const Node& node) +ByAllocationStack::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; @@ -673,18 +666,17 @@ ByAllocationStack::count(CountBase& countBase, const Node& node) return false; } MOZ_ASSERT(p); - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } // Otherwise, count it in the "no stack" category. - return count.noStack->count(node); + return count.noStack->count(mallocSizeOf, node); } bool -ByAllocationStack::report(CountBase& countBase, MutableHandleValue report) +ByAllocationStack::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; #ifdef DEBUG // Check that nothing rehashes our table while we hold pointers into it. @@ -719,7 +711,7 @@ ByAllocationStack::report(CountBase& countBase, MutableHandleValue report) CountBasePtr& stackCount = entry.value(); RootedValue stackReport(cx); - if (!stackCount->report(&stackReport)) + if (!stackCount->report(cx, &stackReport)) return false; if (!MapObject::set(cx, map, stackVal, stackReport)) @@ -728,7 +720,7 @@ ByAllocationStack::report(CountBase& countBase, MutableHandleValue report) if (count.noStack->total_ > 0) { RootedValue noStackReport(cx); - if (!count.noStack->report(&noStackReport)) + if (!count.noStack->report(cx, &noStackReport)) return false; RootedValue noStack(cx, StringValue(cx->names().noStack)); if (!MapObject::set(cx, map, noStack, noStackReport)) @@ -767,10 +759,8 @@ class ByFilename : public CountType { CountTypePtr noFilenameType; public: - ByFilename(Census& census, - CountTypePtr& thenType, - CountTypePtr& noFilenameType) - : CountType(census), + ByFilename(CountTypePtr& thenType, CountTypePtr& noFilenameType) + : CountType(), thenType(Move(thenType)), noFilenameType(Move(noFilenameType)) { } @@ -782,8 +772,8 @@ class ByFilename : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -797,7 +787,7 @@ ByFilename::makeCount() if (!noFilenameCount) return nullptr; - UniquePtr count(census.new_(*this, Move(thenCount), Move(noFilenameCount))); + UniquePtr count(js_new(*this, Move(thenCount), Move(noFilenameCount))); if (!count || !count->init()) return nullptr; @@ -814,14 +804,14 @@ ByFilename::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByFilename::count(CountBase& countBase, const Node& node) +ByFilename::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; const char* filename = node.scriptFilename(); if (!filename) - return count.noFilename->count(node); + return count.noFilename->count(mallocSizeOf, node); Table::AddPtr p = count.table.lookupForAdd(filename); if (!p) { @@ -829,21 +819,20 @@ ByFilename::count(CountBase& countBase, const Node& node) if (!thenCount || !count.table.add(p, filename, Move(thenCount))) return false; } - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } bool -ByFilename::report(CountBase& countBase, MutableHandleValue report) +ByFilename::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; RootedPlainObject obj(cx, cStringCountMapToObject(cx, count.table)); if (!obj) return false; RootedValue noFilenameReport(cx); - if (!count.noFilename->report(&noFilenameReport) || + if (!count.noFilename->report(cx, &noFilenameReport) || !DefineProperty(cx, obj, cx->names().noFilename, noFilenameReport)) { return false; @@ -876,11 +865,11 @@ CensusHandler::operator() (BreadthFirst& traversal, Zone* zone = referent.zone(); if (census.targetZones.count() == 0 || census.targetZones.has(zone)) - return rootCount->count(referent); + return rootCount->count(mallocSizeOf, referent); if (zone == census.atomsZone) { traversal.abandonReferent(); - return rootCount->count(referent); + return rootCount->count(mallocSizeOf, referent); } traversal.abandonReferent(); @@ -890,26 +879,21 @@ CensusHandler::operator() (BreadthFirst& traversal, /*** Parsing Breakdowns ***************************************************************************/ -static CountTypePtr ParseBreakdown(Census& census, HandleValue breakdownValue); - static CountTypePtr -ParseChildBreakdown(Census& census, HandleObject breakdown, PropertyName* prop) +ParseChildBreakdown(JSContext* cx, HandleObject breakdown, PropertyName* prop) { - JSContext* cx = census.cx; RootedValue v(cx); if (!GetProperty(cx, breakdown, breakdown, prop, &v)) return nullptr; - return ParseBreakdown(census, v); + return ParseBreakdown(cx, v); } -static CountTypePtr -ParseBreakdown(Census& census, HandleValue breakdownValue) +CountTypePtr +ParseBreakdown(JSContext* cx, HandleValue breakdownValue) { - JSContext* cx = census.cx; - if (breakdownValue.isUndefined()) { // Construct the default type, { by: 'count' } - CountTypePtr simple(census.new_(census)); + CountTypePtr simple(js_new()); return simple; } @@ -967,75 +951,73 @@ ParseBreakdown(Census& census, HandleValue breakdownValue) return nullptr; } - CountTypePtr simple(census.new_(census, - labelUnique, - ToBoolean(countValue), - ToBoolean(bytesValue))); + CountTypePtr simple(js_new(labelUnique, + ToBoolean(countValue), + ToBoolean(bytesValue))); return simple; } if (StringEqualsAscii(by, "objectClass")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - CountTypePtr otherType(ParseChildBreakdown(census, breakdown, cx->names().other)); + CountTypePtr otherType(ParseChildBreakdown(cx, breakdown, cx->names().other)); if (!otherType) return nullptr; - return CountTypePtr(census.new_(census, thenType, otherType)); + return CountTypePtr(js_new(thenType, otherType)); } if (StringEqualsAscii(by, "coarseType")) { - CountTypePtr objectsType(ParseChildBreakdown(census, breakdown, cx->names().objects)); + CountTypePtr objectsType(ParseChildBreakdown(cx, breakdown, cx->names().objects)); if (!objectsType) return nullptr; - CountTypePtr scriptsType(ParseChildBreakdown(census, breakdown, cx->names().scripts)); + CountTypePtr scriptsType(ParseChildBreakdown(cx, breakdown, cx->names().scripts)); if (!scriptsType) return nullptr; - CountTypePtr stringsType(ParseChildBreakdown(census, breakdown, cx->names().strings)); + CountTypePtr stringsType(ParseChildBreakdown(cx, breakdown, cx->names().strings)); if (!stringsType) return nullptr; - CountTypePtr otherType(ParseChildBreakdown(census, breakdown, cx->names().other)); + CountTypePtr otherType(ParseChildBreakdown(cx, breakdown, cx->names().other)); if (!otherType) return nullptr; - return CountTypePtr(census.new_(census, - objectsType, - scriptsType, - stringsType, - otherType)); + return CountTypePtr(js_new(objectsType, + scriptsType, + stringsType, + otherType)); } if (StringEqualsAscii(by, "internalType")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - return CountTypePtr(census.new_(census, thenType)); + return CountTypePtr(js_new(thenType)); } if (StringEqualsAscii(by, "allocationStack")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - CountTypePtr noStackType(ParseChildBreakdown(census, breakdown, cx->names().noStack)); + CountTypePtr noStackType(ParseChildBreakdown(cx, breakdown, cx->names().noStack)); if (!noStackType) return nullptr; - return CountTypePtr(census.new_(census, thenType, noStackType)); + return CountTypePtr(js_new(thenType, noStackType)); } if (StringEqualsAscii(by, "filename")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - CountTypePtr noFilenameType(ParseChildBreakdown(census, breakdown, cx->names().noFilename)); + CountTypePtr noFilenameType(ParseChildBreakdown(cx, breakdown, cx->names().noFilename)); if (!noFilenameType) return nullptr; - return CountTypePtr(census.new_(census, thenType, noFilenameType)); + return CountTypePtr(js_new(thenType, noFilenameType)); } // We didn't recognize the breakdown type; complain. @@ -1059,25 +1041,22 @@ ParseBreakdown(Census& census, HandleValue breakdownValue) // other: { by: "internalType" } // } static CountTypePtr -GetDefaultBreakdown(Census& census) +GetDefaultBreakdown() { - CountTypePtr byClass(census.new_(census)); - CountTypePtr byClassElse(census.new_(census)); - CountTypePtr objects(census.new_(census, - byClass, - byClassElse)); + CountTypePtr byClass(js_new()); + CountTypePtr byClassElse(js_new()); + CountTypePtr objects(js_new(byClass, byClassElse)); - CountTypePtr scripts(census.new_(census)); - CountTypePtr strings(census.new_(census)); + CountTypePtr scripts(js_new()); + CountTypePtr strings(js_new()); - CountTypePtr byType(census.new_(census)); - CountTypePtr other(census.new_(census, byType)); + CountTypePtr byType(js_new()); + CountTypePtr other(js_new(byType)); - return CountTypePtr(census.new_(census, - objects, - scripts, - strings, - other)); + return CountTypePtr(js_new(objects, + scripts, + strings, + other)); } bool @@ -1088,8 +1067,8 @@ ParseCensusOptions(JSContext* cx, Census& census, HandleObject options, CountTyp return false; outResult = breakdown.isUndefined() - ? GetDefaultBreakdown(census) - : ParseBreakdown(census, breakdown); + ? GetDefaultBreakdown() + : ParseBreakdown(cx, breakdown); return !!outResult; }