Bumping manifests a=b2g-bump
[gecko.git] / js / public / MemoryMetrics.h
blob2694abbeb76fd16d001ee4f4ef6c7639b0778719
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef js_MemoryMetrics_h
8 #define js_MemoryMetrics_h
10 // These declarations are highly likely to change in the future. Depend on them
11 // at your own risk.
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/PodOperations.h"
16 #include <string.h>
18 #include "jsalloc.h"
19 #include "jspubtd.h"
21 #include "js/HashTable.h"
22 #include "js/Utility.h"
23 #include "js/Vector.h"
25 class nsISupports; // Needed for ObjectPrivateVisitor.
27 namespace JS {
29 struct TabSizes
31 enum Kind {
32 Objects,
33 Strings,
34 Private,
35 Other
38 TabSizes() { mozilla::PodZero(this); }
40 void add(Kind kind, size_t n) {
41 switch (kind) {
42 case Objects: objects += n; break;
43 case Strings: strings += n; break;
44 case Private: private_ += n; break;
45 case Other: other += n; break;
46 default: MOZ_CRASH("bad TabSizes kind");
50 size_t objects;
51 size_t strings;
52 size_t private_;
53 size_t other;
56 } // namespace JS
58 namespace js {
60 // In memory reporting, we have concept of "sundries", line items which are too
61 // small to be worth reporting individually. Under some circumstances, a memory
62 // reporter gets tossed into the sundries bucket if it's smaller than
63 // MemoryReportingSundriesThreshold() bytes.
65 // We need to define this value here, rather than in the code which actually
66 // generates the memory reports, because NotableStringInfo uses this value.
67 JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold();
69 // This hash policy avoids flattening ropes (which perturbs the site being
70 // measured and requires a JSContext) at the expense of doing a FULL ROPE COPY
71 // on every hash and match! Beware.
72 struct InefficientNonFlatteningStringHashPolicy
74 typedef JSString* Lookup;
75 static HashNumber hash(const Lookup& l);
76 static bool match(const JSString* const& k, const Lookup& l);
79 struct CStringHashPolicy
81 typedef const char* Lookup;
82 static HashNumber hash(const Lookup& l);
83 static bool match(const char* const& k, const Lookup& l);
86 // This file features many classes with numerous size_t fields, and each such
87 // class has one or more methods that need to operate on all of these fields.
88 // Writing these individually is error-prone -- it's easy to add a new field
89 // without updating all the required methods. So we define a single macro list
90 // in each class to name the fields (and notable characteristics of them), and
91 // then use the following macros to transform those lists into the required
92 // methods.
94 // In some classes, one or more of the macro arguments aren't used. We use '_'
95 // for those.
97 #define DECL_SIZE(kind, gc, mSize) size_t mSize;
98 #define ZERO_SIZE(kind, gc, mSize) mSize(0),
99 #define COPY_OTHER_SIZE(kind, gc, mSize) mSize(other.mSize),
100 #define ADD_OTHER_SIZE(kind, gc, mSize) mSize += other.mSize;
101 #define SUB_OTHER_SIZE(kind, gc, mSize) MOZ_ASSERT(mSize >= other.mSize); \
102 mSize -= other.mSize;
103 #define ADD_SIZE_TO_N(kind, gc, mSize) n += mSize;
104 #define ADD_SIZE_TO_N_IF_LIVE_GC_THING(kind, gc, mSize) n += (js::gc) ? mSize : 0;
105 #define ADD_TO_TAB_SIZES(kind, gc, mSize) sizes->add(JS::TabSizes::kind, mSize);
107 // Used to annotate which size_t fields measure live GC things and which don't.
108 enum {
109 NotLiveGCThing = false,
110 IsLiveGCThing = true
113 } // namespace js
115 namespace JS {
117 struct ClassInfo
119 #define FOR_EACH_SIZE(macro) \
120 macro(Objects, IsLiveGCThing, objectsGCHeap) \
121 macro(Objects, NotLiveGCThing, objectsMallocHeapSlots) \
122 macro(Objects, NotLiveGCThing, objectsMallocHeapElementsNonAsmJS) \
123 macro(Objects, NotLiveGCThing, objectsMallocHeapElementsAsmJS) \
124 macro(Objects, NotLiveGCThing, objectsNonHeapElementsAsmJS) \
125 macro(Objects, NotLiveGCThing, objectsNonHeapElementsMapped) \
126 macro(Objects, NotLiveGCThing, objectsNonHeapCodeAsmJS) \
127 macro(Objects, NotLiveGCThing, objectsMallocHeapMisc) \
129 macro(Other, IsLiveGCThing, shapesGCHeapTree) \
130 macro(Other, IsLiveGCThing, shapesGCHeapDict) \
131 macro(Other, IsLiveGCThing, shapesGCHeapBase) \
132 macro(Other, NotLiveGCThing, shapesMallocHeapTreeTables) \
133 macro(Other, NotLiveGCThing, shapesMallocHeapDictTables) \
134 macro(Other, NotLiveGCThing, shapesMallocHeapTreeKids) \
136 ClassInfo()
137 : FOR_EACH_SIZE(ZERO_SIZE)
138 dummy()
141 void add(const ClassInfo& other) {
142 FOR_EACH_SIZE(ADD_OTHER_SIZE)
145 void subtract(const ClassInfo& other) {
146 FOR_EACH_SIZE(SUB_OTHER_SIZE)
149 bool isNotable() const {
150 static const size_t NotabilityThreshold = 16 * 1024;
151 size_t n = 0;
152 FOR_EACH_SIZE(ADD_SIZE_TO_N)
153 return n >= NotabilityThreshold;
156 size_t sizeOfLiveGCThings() const {
157 size_t n = 0;
158 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
159 return n;
162 void addToTabSizes(TabSizes* sizes) const {
163 FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
166 FOR_EACH_SIZE(DECL_SIZE)
167 int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
169 #undef FOR_EACH_SIZE
172 // Holds data about a notable class (one whose combined object and shape
173 // instances use more than a certain amount of memory) so we can report it
174 // individually.
176 // The only difference between this class and ClassInfo is that this class
177 // holds a copy of the filename.
178 struct NotableClassInfo : public ClassInfo
180 NotableClassInfo();
181 NotableClassInfo(const char* className, const ClassInfo& info);
182 NotableClassInfo(NotableClassInfo&& info);
183 NotableClassInfo& operator=(NotableClassInfo&& info);
185 ~NotableClassInfo() {
186 js_free(className_);
189 char* className_;
191 private:
192 NotableClassInfo(const NotableClassInfo& info) = delete;
195 // Data for tracking JIT-code memory usage.
196 struct CodeSizes
198 #define FOR_EACH_SIZE(macro) \
199 macro(_, _, ion) \
200 macro(_, _, baseline) \
201 macro(_, _, regexp) \
202 macro(_, _, other) \
203 macro(_, _, unused)
205 CodeSizes()
206 : FOR_EACH_SIZE(ZERO_SIZE)
207 dummy()
210 FOR_EACH_SIZE(DECL_SIZE)
211 int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
213 #undef FOR_EACH_SIZE
216 // Data for tracking GC memory usage.
217 struct GCSizes
219 #define FOR_EACH_SIZE(macro) \
220 macro(_, _, marker) \
221 macro(_, _, nurseryCommitted) \
222 macro(_, _, nurseryDecommitted) \
223 macro(_, _, nurseryHugeSlots) \
224 macro(_, _, storeBufferVals) \
225 macro(_, _, storeBufferCells) \
226 macro(_, _, storeBufferSlots) \
227 macro(_, _, storeBufferWholeCells) \
228 macro(_, _, storeBufferRelocVals) \
229 macro(_, _, storeBufferRelocCells) \
230 macro(_, _, storeBufferGenerics)
232 GCSizes()
233 : FOR_EACH_SIZE(ZERO_SIZE)
234 dummy()
237 FOR_EACH_SIZE(DECL_SIZE)
238 int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
240 #undef FOR_EACH_SIZE
243 // This class holds information about the memory taken up by identical copies of
244 // a particular string. Multiple JSStrings may have their sizes aggregated
245 // together into one StringInfo object. Note that two strings with identical
246 // chars will not be aggregated together if one is a short string and the other
247 // is not.
248 struct StringInfo
250 #define FOR_EACH_SIZE(macro) \
251 macro(Strings, IsLiveGCThing, gcHeapLatin1) \
252 macro(Strings, IsLiveGCThing, gcHeapTwoByte) \
253 macro(Strings, NotLiveGCThing, mallocHeapLatin1) \
254 macro(Strings, NotLiveGCThing, mallocHeapTwoByte)
256 StringInfo()
257 : FOR_EACH_SIZE(ZERO_SIZE)
258 numCopies(0)
261 void add(const StringInfo& other) {
262 FOR_EACH_SIZE(ADD_OTHER_SIZE);
263 numCopies++;
266 void subtract(const StringInfo& other) {
267 FOR_EACH_SIZE(SUB_OTHER_SIZE);
268 numCopies--;
271 bool isNotable() const {
272 static const size_t NotabilityThreshold = 16 * 1024;
273 size_t n = 0;
274 FOR_EACH_SIZE(ADD_SIZE_TO_N)
275 return n >= NotabilityThreshold;
278 size_t sizeOfLiveGCThings() const {
279 size_t n = 0;
280 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
281 return n;
284 void addToTabSizes(TabSizes* sizes) const {
285 FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
288 FOR_EACH_SIZE(DECL_SIZE)
289 uint32_t numCopies; // How many copies of the string have we seen?
291 #undef FOR_EACH_SIZE
294 // Holds data about a notable string (one which, counting all duplicates, uses
295 // more than a certain amount of memory) so we can report it individually.
297 // The only difference between this class and StringInfo is that
298 // NotableStringInfo holds a copy of some or all of the string's chars.
299 struct NotableStringInfo : public StringInfo
301 static const size_t MAX_SAVED_CHARS = 1024;
303 NotableStringInfo();
304 NotableStringInfo(JSString* str, const StringInfo& info);
305 NotableStringInfo(NotableStringInfo&& info);
306 NotableStringInfo& operator=(NotableStringInfo&& info);
308 ~NotableStringInfo() {
309 js_free(buffer);
312 char* buffer;
313 size_t length;
315 private:
316 NotableStringInfo(const NotableStringInfo& info) = delete;
319 // This class holds information about the memory taken up by script sources
320 // from a particular file.
321 struct ScriptSourceInfo
323 #define FOR_EACH_SIZE(macro) \
324 macro(_, _, compressed) \
325 macro(_, _, uncompressed) \
326 macro(_, _, misc)
328 ScriptSourceInfo()
329 : FOR_EACH_SIZE(ZERO_SIZE)
330 numScripts(0)
333 void add(const ScriptSourceInfo& other) {
334 FOR_EACH_SIZE(ADD_OTHER_SIZE)
335 numScripts++;
338 void subtract(const ScriptSourceInfo& other) {
339 FOR_EACH_SIZE(SUB_OTHER_SIZE)
340 numScripts--;
343 bool isNotable() const {
344 static const size_t NotabilityThreshold = 16 * 1024;
345 size_t n = 0;
346 FOR_EACH_SIZE(ADD_SIZE_TO_N)
347 return n >= NotabilityThreshold;
350 FOR_EACH_SIZE(DECL_SIZE)
351 uint32_t numScripts; // How many ScriptSources come from this file? (It
352 // can be more than one in XML files that have
353 // multiple scripts in CDATA sections.)
354 #undef FOR_EACH_SIZE
357 // Holds data about a notable script source file (one whose combined
358 // script sources use more than a certain amount of memory) so we can report it
359 // individually.
361 // The only difference between this class and ScriptSourceInfo is that this
362 // class holds a copy of the filename.
363 struct NotableScriptSourceInfo : public ScriptSourceInfo
365 NotableScriptSourceInfo();
366 NotableScriptSourceInfo(const char* filename, const ScriptSourceInfo& info);
367 NotableScriptSourceInfo(NotableScriptSourceInfo&& info);
368 NotableScriptSourceInfo& operator=(NotableScriptSourceInfo&& info);
370 ~NotableScriptSourceInfo() {
371 js_free(filename_);
374 char* filename_;
376 private:
377 NotableScriptSourceInfo(const NotableScriptSourceInfo& info) = delete;
380 // These measurements relate directly to the JSRuntime, and not to zones and
381 // compartments within it.
382 struct RuntimeSizes
384 #define FOR_EACH_SIZE(macro) \
385 macro(_, _, object) \
386 macro(_, _, atomsTable) \
387 macro(_, _, contexts) \
388 macro(_, _, dtoa) \
389 macro(_, _, temporary) \
390 macro(_, _, interpreterStack) \
391 macro(_, _, mathCache) \
392 macro(_, _, uncompressedSourceCache) \
393 macro(_, _, compressedSourceSet) \
394 macro(_, _, scriptData) \
396 RuntimeSizes()
397 : FOR_EACH_SIZE(ZERO_SIZE)
398 scriptSourceInfo(),
399 code(),
400 gc(),
401 notableScriptSources()
403 allScriptSources = js_new<ScriptSourcesHashMap>();
404 if (!allScriptSources || !allScriptSources->init())
405 MOZ_CRASH("oom");
408 ~RuntimeSizes() {
409 // |allScriptSources| is usually deleted and set to nullptr before this
410 // destructor runs. But there are failure cases due to OOMs that may
411 // prevent that, so it doesn't hurt to try again here.
412 js_delete(allScriptSources);
415 // The script source measurements in |scriptSourceInfo| are initially for
416 // all script sources. At the end, if the measurement granularity is
417 // FineGrained, we subtract the measurements of the notable script sources
418 // and move them into |notableScriptSources|.
419 FOR_EACH_SIZE(DECL_SIZE)
420 ScriptSourceInfo scriptSourceInfo;
421 CodeSizes code;
422 GCSizes gc;
424 typedef js::HashMap<const char*, ScriptSourceInfo,
425 js::CStringHashPolicy,
426 js::SystemAllocPolicy> ScriptSourcesHashMap;
428 // |allScriptSources| is only used transiently. During the reporting phase
429 // it is filled with info about every script source in the runtime. It's
430 // then used to fill in |notableScriptSources| (which actually gets
431 // reported), and immediately discarded afterwards.
432 ScriptSourcesHashMap* allScriptSources;
433 js::Vector<NotableScriptSourceInfo, 0, js::SystemAllocPolicy> notableScriptSources;
435 #undef FOR_EACH_SIZE
438 struct ZoneStats
440 #define FOR_EACH_SIZE(macro) \
441 macro(Other, IsLiveGCThing, symbolsGCHeap) \
442 macro(Other, NotLiveGCThing, gcHeapArenaAdmin) \
443 macro(Other, NotLiveGCThing, unusedGCThings) \
444 macro(Other, IsLiveGCThing, lazyScriptsGCHeap) \
445 macro(Other, NotLiveGCThing, lazyScriptsMallocHeap) \
446 macro(Other, IsLiveGCThing, jitCodesGCHeap) \
447 macro(Other, IsLiveGCThing, typeObjectsGCHeap) \
448 macro(Other, NotLiveGCThing, typeObjectsMallocHeap) \
449 macro(Other, NotLiveGCThing, typePool) \
450 macro(Other, NotLiveGCThing, baselineStubsOptimized) \
452 ZoneStats()
453 : FOR_EACH_SIZE(ZERO_SIZE)
454 stringInfo(),
455 extra(),
456 allStrings(nullptr),
457 notableStrings(),
458 isTotals(true)
461 ZoneStats(ZoneStats&& other)
462 : FOR_EACH_SIZE(COPY_OTHER_SIZE)
463 stringInfo(mozilla::Move(other.stringInfo)),
464 extra(other.extra),
465 allStrings(other.allStrings),
466 notableStrings(mozilla::Move(other.notableStrings)),
467 isTotals(other.isTotals)
469 other.allStrings = nullptr;
470 MOZ_ASSERT(!other.isTotals);
473 ~ZoneStats() {
474 // |allStrings| is usually deleted and set to nullptr before this
475 // destructor runs. But there are failure cases due to OOMs that may
476 // prevent that, so it doesn't hurt to try again here.
477 js_delete(allStrings);
480 bool initStrings(JSRuntime* rt);
482 void addSizes(const ZoneStats& other) {
483 MOZ_ASSERT(isTotals);
484 FOR_EACH_SIZE(ADD_OTHER_SIZE)
485 stringInfo.add(other.stringInfo);
488 size_t sizeOfLiveGCThings() const {
489 MOZ_ASSERT(isTotals);
490 size_t n = 0;
491 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
492 n += stringInfo.sizeOfLiveGCThings();
493 return n;
496 void addToTabSizes(JS::TabSizes* sizes) const {
497 MOZ_ASSERT(isTotals);
498 FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
499 stringInfo.addToTabSizes(sizes);
502 // These string measurements are initially for all strings. At the end,
503 // if the measurement granularity is FineGrained, we subtract the
504 // measurements of the notable script sources and move them into
505 // |notableStrings|.
506 FOR_EACH_SIZE(DECL_SIZE)
507 StringInfo stringInfo;
508 void* extra; // This field can be used by embedders.
510 typedef js::HashMap<JSString*, StringInfo,
511 js::InefficientNonFlatteningStringHashPolicy,
512 js::SystemAllocPolicy> StringsHashMap;
514 // |allStrings| is only used transiently. During the zone traversal it is
515 // filled with info about every string in the zone. It's then used to fill
516 // in |notableStrings| (which actually gets reported), and immediately
517 // discarded afterwards.
518 StringsHashMap* allStrings;
519 js::Vector<NotableStringInfo, 0, js::SystemAllocPolicy> notableStrings;
520 bool isTotals;
522 #undef FOR_EACH_SIZE
525 struct CompartmentStats
527 #define FOR_EACH_SIZE(macro) \
528 macro(Private, NotLiveGCThing, objectsPrivate) \
529 macro(Other, IsLiveGCThing, scriptsGCHeap) \
530 macro(Other, NotLiveGCThing, scriptsMallocHeapData) \
531 macro(Other, NotLiveGCThing, baselineData) \
532 macro(Other, NotLiveGCThing, baselineStubsFallback) \
533 macro(Other, NotLiveGCThing, ionData) \
534 macro(Other, NotLiveGCThing, typeInferenceTypeScripts) \
535 macro(Other, NotLiveGCThing, typeInferenceAllocationSiteTables) \
536 macro(Other, NotLiveGCThing, typeInferenceArrayTypeTables) \
537 macro(Other, NotLiveGCThing, typeInferenceObjectTypeTables) \
538 macro(Other, NotLiveGCThing, compartmentObject) \
539 macro(Other, NotLiveGCThing, compartmentTables) \
540 macro(Other, NotLiveGCThing, innerViewsTable) \
541 macro(Other, NotLiveGCThing, lazyArrayBuffersTable) \
542 macro(Other, NotLiveGCThing, crossCompartmentWrappersTable) \
543 macro(Other, NotLiveGCThing, regexpCompartment) \
544 macro(Other, NotLiveGCThing, savedStacksSet)
546 CompartmentStats()
547 : FOR_EACH_SIZE(ZERO_SIZE)
548 classInfo(),
549 extra(),
550 allClasses(nullptr),
551 notableClasses(),
552 isTotals(true)
555 CompartmentStats(CompartmentStats&& other)
556 : FOR_EACH_SIZE(COPY_OTHER_SIZE)
557 classInfo(mozilla::Move(other.classInfo)),
558 extra(other.extra),
559 allClasses(other.allClasses),
560 notableClasses(mozilla::Move(other.notableClasses)),
561 isTotals(other.isTotals)
563 other.allClasses = nullptr;
564 MOZ_ASSERT(!other.isTotals);
567 ~CompartmentStats() {
568 // |allClasses| is usually deleted and set to nullptr before this
569 // destructor runs. But there are failure cases due to OOMs that may
570 // prevent that, so it doesn't hurt to try again here.
571 js_delete(allClasses);
574 bool initClasses(JSRuntime* rt);
576 void addSizes(const CompartmentStats& other) {
577 MOZ_ASSERT(isTotals);
578 FOR_EACH_SIZE(ADD_OTHER_SIZE)
579 classInfo.add(other.classInfo);
582 size_t sizeOfLiveGCThings() const {
583 MOZ_ASSERT(isTotals);
584 size_t n = 0;
585 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
586 n += classInfo.sizeOfLiveGCThings();
587 return n;
590 void addToTabSizes(TabSizes* sizes) const {
591 MOZ_ASSERT(isTotals);
592 FOR_EACH_SIZE(ADD_TO_TAB_SIZES);
593 classInfo.addToTabSizes(sizes);
596 // The class measurements in |classInfo| are initially for all classes. At
597 // the end, if the measurement granularity is FineGrained, we subtract the
598 // measurements of the notable classes and move them into |notableClasses|.
599 FOR_EACH_SIZE(DECL_SIZE)
600 ClassInfo classInfo;
601 void* extra; // This field can be used by embedders.
603 typedef js::HashMap<const char*, ClassInfo,
604 js::CStringHashPolicy,
605 js::SystemAllocPolicy> ClassesHashMap;
607 // These are similar to |allStrings| and |notableStrings| in ZoneStats.
608 ClassesHashMap* allClasses;
609 js::Vector<NotableClassInfo, 0, js::SystemAllocPolicy> notableClasses;
610 bool isTotals;
612 #undef FOR_EACH_SIZE
615 typedef js::Vector<CompartmentStats, 0, js::SystemAllocPolicy> CompartmentStatsVector;
616 typedef js::Vector<ZoneStats, 0, js::SystemAllocPolicy> ZoneStatsVector;
618 struct RuntimeStats
620 #define FOR_EACH_SIZE(macro) \
621 macro(_, _, gcHeapChunkTotal) \
622 macro(_, _, gcHeapDecommittedArenas) \
623 macro(_, _, gcHeapUnusedChunks) \
624 macro(_, _, gcHeapUnusedArenas) \
625 macro(_, _, gcHeapChunkAdmin) \
626 macro(_, _, gcHeapGCThings) \
628 explicit RuntimeStats(mozilla::MallocSizeOf mallocSizeOf)
629 : FOR_EACH_SIZE(ZERO_SIZE)
630 runtime(),
631 cTotals(),
632 zTotals(),
633 compartmentStatsVector(),
634 zoneStatsVector(),
635 currZoneStats(nullptr),
636 mallocSizeOf_(mallocSizeOf)
639 // Here's a useful breakdown of the GC heap.
641 // - rtStats.gcHeapChunkTotal
642 // - decommitted bytes
643 // - rtStats.gcHeapDecommittedArenas (decommitted arenas in non-empty chunks)
644 // - unused bytes
645 // - rtStats.gcHeapUnusedChunks (empty chunks)
646 // - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks)
647 // - rtStats.zTotals.unusedGCThings (empty GC thing slots within non-empty arenas)
648 // - used bytes
649 // - rtStats.gcHeapChunkAdmin
650 // - rtStats.zTotals.gcHeapArenaAdmin
651 // - rtStats.gcHeapGCThings (in-use GC things)
652 // == rtStats.zTotals.sizeOfLiveGCThings() + rtStats.cTotals.sizeOfLiveGCThings()
654 // It's possible that some arenas in empty chunks may be decommitted, but
655 // we don't count those under rtStats.gcHeapDecommittedArenas because (a)
656 // it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a
657 // multiple of the chunk size, which is good.
659 FOR_EACH_SIZE(DECL_SIZE)
661 RuntimeSizes runtime;
663 CompartmentStats cTotals; // The sum of this runtime's compartments' measurements.
664 ZoneStats zTotals; // The sum of this runtime's zones' measurements.
666 CompartmentStatsVector compartmentStatsVector;
667 ZoneStatsVector zoneStatsVector;
669 ZoneStats* currZoneStats;
671 mozilla::MallocSizeOf mallocSizeOf_;
673 virtual void initExtraCompartmentStats(JSCompartment* c, CompartmentStats* cstats) = 0;
674 virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats) = 0;
676 #undef FOR_EACH_SIZE
679 class ObjectPrivateVisitor
681 public:
682 // Within CollectRuntimeStats, this method is called for each JS object
683 // that has an nsISupports pointer.
684 virtual size_t sizeOfIncludingThis(nsISupports* aSupports) = 0;
686 // A callback that gets a JSObject's nsISupports pointer, if it has one.
687 // Note: this function does *not* addref |iface|.
688 typedef bool(*GetISupportsFun)(JSObject* obj, nsISupports** iface);
689 GetISupportsFun getISupports_;
691 explicit ObjectPrivateVisitor(GetISupportsFun getISupports)
692 : getISupports_(getISupports)
696 extern JS_PUBLIC_API(bool)
697 CollectRuntimeStats(JSRuntime* rt, RuntimeStats* rtStats, ObjectPrivateVisitor* opv, bool anonymize);
699 extern JS_PUBLIC_API(size_t)
700 SystemCompartmentCount(JSRuntime* rt);
702 extern JS_PUBLIC_API(size_t)
703 UserCompartmentCount(JSRuntime* rt);
705 extern JS_PUBLIC_API(size_t)
706 PeakSizeOfTemporary(const JSRuntime* rt);
708 extern JS_PUBLIC_API(bool)
709 AddSizeOfTab(JSRuntime* rt, JS::HandleObject obj, mozilla::MallocSizeOf mallocSizeOf,
710 ObjectPrivateVisitor* opv, TabSizes* sizes);
712 } // namespace JS
714 #undef DECL_SIZE
715 #undef ZERO_SIZE
716 #undef COPY_OTHER_SIZE
717 #undef ADD_OTHER_SIZE
718 #undef SUB_OTHER_SIZE
719 #undef ADD_SIZE_TO_N
720 #undef ADD_SIZE_TO_N_IF_LIVE_GC_THING
721 #undef ADD_TO_TAB_SIZES
723 #endif /* js_MemoryMetrics_h */