Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/NullPtr.h"
15 #include "mozilla/PodOperations.h"
17 #include <string.h>
19 #include "jsalloc.h"
20 #include "jspubtd.h"
22 #include "js/HashTable.h"
23 #include "js/Utility.h"
24 #include "js/Vector.h"
26 class nsISupports; // Needed for ObjectPrivateVisitor.
28 namespace JS {
30 struct TabSizes
31 {
32 enum Kind {
33 Objects,
34 Strings,
35 Private,
36 Other
37 };
39 TabSizes() { mozilla::PodZero(this); }
41 void add(Kind kind, size_t n) {
42 switch (kind) {
43 case Objects: objects += n; break;
44 case Strings: strings += n; break;
45 case Private: private_ += n; break;
46 case Other: other += n; break;
47 default: MOZ_CRASH("bad TabSizes kind");
48 }
49 }
51 size_t objects;
52 size_t strings;
53 size_t private_;
54 size_t other;
55 };
57 } // namespace JS
59 namespace js {
61 // In memory reporting, we have concept of "sundries", line items which are too
62 // small to be worth reporting individually. Under some circumstances, a memory
63 // reporter gets tossed into the sundries bucket if it's smaller than
64 // MemoryReportingSundriesThreshold() bytes.
65 //
66 // We need to define this value here, rather than in the code which actually
67 // generates the memory reports, because NotableStringInfo uses this value.
68 JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold();
70 // This hash policy avoids flattening ropes (which perturbs the site being
71 // measured and requires a JSContext) at the expense of doing a FULL ROPE COPY
72 // on every hash and match! Beware.
73 struct InefficientNonFlatteningStringHashPolicy
74 {
75 typedef JSString *Lookup;
76 static HashNumber hash(const Lookup &l);
77 static bool match(const JSString *const &k, const Lookup &l);
78 };
80 struct CStringHashPolicy
81 {
82 typedef const char *Lookup;
83 static HashNumber hash(const Lookup &l);
84 static bool match(const char *const &k, const Lookup &l);
85 };
87 // This file features many classes with numerous size_t fields, and each such
88 // class has one or more methods that need to operate on all of these fields.
89 // Writing these individually is error-prone -- it's easy to add a new field
90 // without updating all the required methods. So we define a single macro list
91 // in each class to name the fields (and notable characteristics of them), and
92 // then use the following macros to transform those lists into the required
93 // methods.
94 //
95 // In some classes, one or more of the macro arguments aren't used. We use '_'
96 // for those.
97 //
98 #define DECL_SIZE(kind, gc, mSize) size_t mSize;
99 #define ZERO_SIZE(kind, gc, mSize) mSize(0),
100 #define COPY_OTHER_SIZE(kind, gc, mSize) mSize(other.mSize),
101 #define ADD_OTHER_SIZE(kind, gc, mSize) mSize += other.mSize;
102 #define SUB_OTHER_SIZE(kind, gc, mSize) MOZ_ASSERT(mSize >= other.mSize); \
103 mSize -= other.mSize;
104 #define ADD_SIZE_TO_N(kind, gc, mSize) n += mSize;
105 #define ADD_SIZE_TO_N_IF_LIVE_GC_THING(kind, gc, mSize) n += (js::gc) ? mSize : 0;
106 #define ADD_TO_TAB_SIZES(kind, gc, mSize) sizes->add(JS::TabSizes::kind, mSize);
108 // Used to annotate which size_t fields measure live GC things and which don't.
109 enum {
110 NotLiveGCThing = false,
111 IsLiveGCThing = true
112 };
114 } // namespace js
116 namespace JS {
118 // Data for tracking memory usage of things hanging off objects.
119 struct ObjectsExtraSizes
120 {
121 #define FOR_EACH_SIZE(macro) \
122 macro(Objects, NotLiveGCThing, mallocHeapSlots) \
123 macro(Objects, NotLiveGCThing, mallocHeapElementsNonAsmJS) \
124 macro(Objects, NotLiveGCThing, mallocHeapElementsAsmJS) \
125 macro(Objects, NotLiveGCThing, nonHeapElementsAsmJS) \
126 macro(Objects, NotLiveGCThing, nonHeapElementsMapped) \
127 macro(Objects, NotLiveGCThing, nonHeapCodeAsmJS) \
128 macro(Objects, NotLiveGCThing, mallocHeapAsmJSModuleData) \
129 macro(Objects, NotLiveGCThing, mallocHeapArgumentsData) \
130 macro(Objects, NotLiveGCThing, mallocHeapRegExpStatics) \
131 macro(Objects, NotLiveGCThing, mallocHeapPropertyIteratorData) \
132 macro(Objects, NotLiveGCThing, mallocHeapCtypesData)
134 ObjectsExtraSizes()
135 : FOR_EACH_SIZE(ZERO_SIZE)
136 dummy()
137 {}
139 void add(const ObjectsExtraSizes &other) {
140 FOR_EACH_SIZE(ADD_OTHER_SIZE)
141 }
143 size_t sizeOfLiveGCThings() const {
144 size_t n = 0;
145 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
146 return n;
147 }
149 void addToTabSizes(TabSizes *sizes) const {
150 FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
151 }
153 FOR_EACH_SIZE(DECL_SIZE)
154 int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
156 #undef FOR_EACH_SIZE
157 };
159 // Data for tracking JIT-code memory usage.
160 struct CodeSizes
161 {
162 #define FOR_EACH_SIZE(macro) \
163 macro(_, _, ion) \
164 macro(_, _, baseline) \
165 macro(_, _, regexp) \
166 macro(_, _, other) \
167 macro(_, _, unused)
169 CodeSizes()
170 : FOR_EACH_SIZE(ZERO_SIZE)
171 dummy()
172 {}
174 FOR_EACH_SIZE(DECL_SIZE)
175 int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
177 #undef FOR_EACH_SIZE
178 };
180 // Data for tracking GC memory usage.
181 struct GCSizes
182 {
183 #define FOR_EACH_SIZE(macro) \
184 macro(_, _, marker) \
185 macro(_, _, nurseryCommitted) \
186 macro(_, _, nurseryDecommitted) \
187 macro(_, _, nurseryHugeSlots) \
188 macro(_, _, storeBufferVals) \
189 macro(_, _, storeBufferCells) \
190 macro(_, _, storeBufferSlots) \
191 macro(_, _, storeBufferWholeCells) \
192 macro(_, _, storeBufferRelocVals) \
193 macro(_, _, storeBufferRelocCells) \
194 macro(_, _, storeBufferGenerics)
196 GCSizes()
197 : FOR_EACH_SIZE(ZERO_SIZE)
198 dummy()
199 {}
201 FOR_EACH_SIZE(DECL_SIZE)
202 int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
204 #undef FOR_EACH_SIZE
205 };
207 // This class holds information about the memory taken up by identical copies of
208 // a particular string. Multiple JSStrings may have their sizes aggregated
209 // together into one StringInfo object. Note that two strings with identical
210 // chars will not be aggregated together if one is a short string and the other
211 // is not.
212 struct StringInfo
213 {
214 #define FOR_EACH_SIZE(macro) \
215 macro(Strings, IsLiveGCThing, gcHeap) \
216 macro(Strings, NotLiveGCThing, mallocHeap) \
218 StringInfo()
219 : FOR_EACH_SIZE(ZERO_SIZE)
220 numCopies(0)
221 {}
223 void add(const StringInfo &other) {
224 FOR_EACH_SIZE(ADD_OTHER_SIZE);
225 numCopies++;
226 }
228 void subtract(const StringInfo &other) {
229 FOR_EACH_SIZE(SUB_OTHER_SIZE);
230 numCopies--;
231 }
233 bool isNotable() const {
234 static const size_t NotabilityThreshold = 16 * 1024;
235 size_t n = 0;
236 FOR_EACH_SIZE(ADD_SIZE_TO_N)
237 return n >= NotabilityThreshold;
238 }
240 size_t sizeOfLiveGCThings() const {
241 size_t n = 0;
242 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
243 return n;
244 }
246 void addToTabSizes(TabSizes *sizes) const {
247 FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
248 }
250 FOR_EACH_SIZE(DECL_SIZE)
251 uint32_t numCopies; // How many copies of the string have we seen?
253 #undef FOR_EACH_SIZE
254 };
256 // Holds data about a notable string (one which, counting all duplicates, uses
257 // more than a certain amount of memory) so we can report it individually.
258 //
259 // The only difference between this class and StringInfo is that
260 // NotableStringInfo holds a copy of some or all of the string's chars.
261 struct NotableStringInfo : public StringInfo
262 {
263 static const size_t MAX_SAVED_CHARS = 1024;
265 NotableStringInfo();
266 NotableStringInfo(JSString *str, const StringInfo &info);
267 NotableStringInfo(NotableStringInfo &&info);
268 NotableStringInfo &operator=(NotableStringInfo &&info);
270 ~NotableStringInfo() {
271 js_free(buffer);
272 }
274 char *buffer;
275 size_t length;
277 private:
278 NotableStringInfo(const NotableStringInfo& info) MOZ_DELETE;
279 };
281 // This class holds information about the memory taken up by script sources
282 // from a particular file.
283 struct ScriptSourceInfo
284 {
285 #define FOR_EACH_SIZE(macro) \
286 macro(_, _, compressed) \
287 macro(_, _, uncompressed) \
288 macro(_, _, misc)
290 ScriptSourceInfo()
291 : FOR_EACH_SIZE(ZERO_SIZE)
292 numScripts(0)
293 {}
295 void add(const ScriptSourceInfo &other) {
296 FOR_EACH_SIZE(ADD_OTHER_SIZE)
297 numScripts++;
298 }
300 void subtract(const ScriptSourceInfo &other) {
301 FOR_EACH_SIZE(SUB_OTHER_SIZE)
302 numScripts--;
303 }
305 bool isNotable() const {
306 static const size_t NotabilityThreshold = 16 * 1024;
307 size_t n = 0;
308 FOR_EACH_SIZE(ADD_SIZE_TO_N)
309 return n >= NotabilityThreshold;
310 }
312 FOR_EACH_SIZE(DECL_SIZE)
313 uint32_t numScripts; // How many ScriptSources come from this file? (It
314 // can be more than one in XML files that have
315 // multiple scripts in CDATA sections.)
316 #undef FOR_EACH_SIZE
317 };
319 // Holds data about a notable script source file (one whose combined
320 // script sources use more than a certain amount of memory) so we can report it
321 // individually.
322 //
323 // The only difference between this class and ScriptSourceInfo is that this
324 // class holds a copy of the filename.
325 struct NotableScriptSourceInfo : public ScriptSourceInfo
326 {
327 NotableScriptSourceInfo();
328 NotableScriptSourceInfo(const char *filename, const ScriptSourceInfo &info);
329 NotableScriptSourceInfo(NotableScriptSourceInfo &&info);
330 NotableScriptSourceInfo &operator=(NotableScriptSourceInfo &&info);
332 ~NotableScriptSourceInfo() {
333 js_free(filename_);
334 }
336 char *filename_;
338 private:
339 NotableScriptSourceInfo(const NotableScriptSourceInfo& info) MOZ_DELETE;
340 };
342 // These measurements relate directly to the JSRuntime, and not to zones and
343 // compartments within it.
344 struct RuntimeSizes
345 {
346 #define FOR_EACH_SIZE(macro) \
347 macro(_, _, object) \
348 macro(_, _, atomsTable) \
349 macro(_, _, contexts) \
350 macro(_, _, dtoa) \
351 macro(_, _, temporary) \
352 macro(_, _, regexpData) \
353 macro(_, _, interpreterStack) \
354 macro(_, _, mathCache) \
355 macro(_, _, sourceDataCache) \
356 macro(_, _, scriptData) \
358 RuntimeSizes()
359 : FOR_EACH_SIZE(ZERO_SIZE)
360 scriptSourceInfo(),
361 code(),
362 gc(),
363 notableScriptSources()
364 {
365 allScriptSources = js_new<ScriptSourcesHashMap>();
366 if (!allScriptSources || !allScriptSources->init())
367 MOZ_CRASH("oom");
368 }
370 ~RuntimeSizes() {
371 // |allScriptSources| is usually deleted and set to nullptr before this
372 // destructor runs. But there are failure cases due to OOMs that may
373 // prevent that, so it doesn't hurt to try again here.
374 js_delete(allScriptSources);
375 }
377 // The script source measurements in |scriptSourceInfo| are initially for
378 // all script sources. At the end, if the measurement granularity is
379 // FineGrained, we subtract the measurements of the notable script sources
380 // and move them into |notableScriptSources|.
381 FOR_EACH_SIZE(DECL_SIZE)
382 ScriptSourceInfo scriptSourceInfo;
383 CodeSizes code;
384 GCSizes gc;
386 typedef js::HashMap<const char*, ScriptSourceInfo,
387 js::CStringHashPolicy,
388 js::SystemAllocPolicy> ScriptSourcesHashMap;
390 // |allScriptSources| is only used transiently. During the reporting phase
391 // it is filled with info about every script source in the runtime. It's
392 // then used to fill in |notableScriptSources| (which actually gets
393 // reported), and immediately discarded afterwards.
394 ScriptSourcesHashMap *allScriptSources;
395 js::Vector<NotableScriptSourceInfo, 0, js::SystemAllocPolicy> notableScriptSources;
397 #undef FOR_EACH_SIZE
398 };
400 struct ZoneStats
401 {
402 #define FOR_EACH_SIZE(macro) \
403 macro(Other, NotLiveGCThing, gcHeapArenaAdmin) \
404 macro(Other, NotLiveGCThing, unusedGCThings) \
405 macro(Other, IsLiveGCThing, lazyScriptsGCHeap) \
406 macro(Other, NotLiveGCThing, lazyScriptsMallocHeap) \
407 macro(Other, IsLiveGCThing, jitCodesGCHeap) \
408 macro(Other, IsLiveGCThing, typeObjectsGCHeap) \
409 macro(Other, NotLiveGCThing, typeObjectsMallocHeap) \
410 macro(Other, NotLiveGCThing, typePool) \
411 macro(Other, NotLiveGCThing, baselineStubsOptimized) \
413 ZoneStats()
414 : FOR_EACH_SIZE(ZERO_SIZE)
415 stringInfo(),
416 extra(),
417 allStrings(nullptr),
418 notableStrings(),
419 isTotals(true)
420 {}
422 ZoneStats(ZoneStats &&other)
423 : FOR_EACH_SIZE(COPY_OTHER_SIZE)
424 stringInfo(mozilla::Move(other.stringInfo)),
425 extra(other.extra),
426 allStrings(other.allStrings),
427 notableStrings(mozilla::Move(other.notableStrings)),
428 isTotals(other.isTotals)
429 {
430 other.allStrings = nullptr;
431 MOZ_ASSERT(!other.isTotals);
432 }
434 ~ZoneStats() {
435 // |allStrings| is usually deleted and set to nullptr before this
436 // destructor runs. But there are failure cases due to OOMs that may
437 // prevent that, so it doesn't hurt to try again here.
438 js_delete(allStrings);
439 }
441 bool initStrings(JSRuntime *rt);
443 void addSizes(const ZoneStats &other) {
444 MOZ_ASSERT(isTotals);
445 FOR_EACH_SIZE(ADD_OTHER_SIZE)
446 stringInfo.add(other.stringInfo);
447 }
449 size_t sizeOfLiveGCThings() const {
450 MOZ_ASSERT(isTotals);
451 size_t n = 0;
452 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
453 n += stringInfo.sizeOfLiveGCThings();
454 return n;
455 }
457 void addToTabSizes(JS::TabSizes *sizes) const {
458 MOZ_ASSERT(isTotals);
459 FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
460 stringInfo.addToTabSizes(sizes);
461 }
463 // These string measurements are initially for all strings. At the end,
464 // if the measurement granularity is FineGrained, we subtract the
465 // measurements of the notable script sources and move them into
466 // |notableStrings|.
467 FOR_EACH_SIZE(DECL_SIZE)
468 StringInfo stringInfo;
469 void *extra; // This field can be used by embedders.
471 typedef js::HashMap<JSString*, StringInfo,
472 js::InefficientNonFlatteningStringHashPolicy,
473 js::SystemAllocPolicy> StringsHashMap;
475 // |allStrings| is only used transiently. During the zone traversal it is
476 // filled with info about every string in the zone. It's then used to fill
477 // in |notableStrings| (which actually gets reported), and immediately
478 // discarded afterwards.
479 StringsHashMap *allStrings;
480 js::Vector<NotableStringInfo, 0, js::SystemAllocPolicy> notableStrings;
481 bool isTotals;
483 #undef FOR_EACH_SIZE
484 };
486 struct CompartmentStats
487 {
488 #define FOR_EACH_SIZE(macro) \
489 macro(Objects, IsLiveGCThing, objectsGCHeapOrdinary) \
490 macro(Objects, IsLiveGCThing, objectsGCHeapFunction) \
491 macro(Objects, IsLiveGCThing, objectsGCHeapDenseArray) \
492 macro(Objects, IsLiveGCThing, objectsGCHeapSlowArray) \
493 macro(Objects, IsLiveGCThing, objectsGCHeapCrossCompartmentWrapper) \
494 macro(Private, NotLiveGCThing, objectsPrivate) \
495 macro(Other, IsLiveGCThing, shapesGCHeapTreeGlobalParented) \
496 macro(Other, IsLiveGCThing, shapesGCHeapTreeNonGlobalParented) \
497 macro(Other, IsLiveGCThing, shapesGCHeapDict) \
498 macro(Other, IsLiveGCThing, shapesGCHeapBase) \
499 macro(Other, NotLiveGCThing, shapesMallocHeapTreeTables) \
500 macro(Other, NotLiveGCThing, shapesMallocHeapDictTables) \
501 macro(Other, NotLiveGCThing, shapesMallocHeapTreeShapeKids) \
502 macro(Other, NotLiveGCThing, shapesMallocHeapCompartmentTables) \
503 macro(Other, IsLiveGCThing, scriptsGCHeap) \
504 macro(Other, NotLiveGCThing, scriptsMallocHeapData) \
505 macro(Other, NotLiveGCThing, baselineData) \
506 macro(Other, NotLiveGCThing, baselineStubsFallback) \
507 macro(Other, NotLiveGCThing, ionData) \
508 macro(Other, NotLiveGCThing, typeInferenceTypeScripts) \
509 macro(Other, NotLiveGCThing, typeInferenceAllocationSiteTables) \
510 macro(Other, NotLiveGCThing, typeInferenceArrayTypeTables) \
511 macro(Other, NotLiveGCThing, typeInferenceObjectTypeTables) \
512 macro(Other, NotLiveGCThing, compartmentObject) \
513 macro(Other, NotLiveGCThing, crossCompartmentWrappersTable) \
514 macro(Other, NotLiveGCThing, regexpCompartment) \
515 macro(Other, NotLiveGCThing, debuggeesSet) \
516 macro(Other, NotLiveGCThing, savedStacksSet)
518 CompartmentStats()
519 : FOR_EACH_SIZE(ZERO_SIZE)
520 objectsExtra(),
521 extra()
522 {}
524 CompartmentStats(const CompartmentStats &other)
525 : FOR_EACH_SIZE(COPY_OTHER_SIZE)
526 objectsExtra(other.objectsExtra),
527 extra(other.extra)
528 {}
530 void add(const CompartmentStats &other) {
531 FOR_EACH_SIZE(ADD_OTHER_SIZE)
532 objectsExtra.add(other.objectsExtra);
533 // Do nothing with |extra|.
534 }
536 size_t sizeOfLiveGCThings() const {
537 size_t n = 0;
538 FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
539 n += objectsExtra.sizeOfLiveGCThings();
540 // Do nothing with |extra|.
541 return n;
542 }
544 void addToTabSizes(TabSizes *sizes) const {
545 FOR_EACH_SIZE(ADD_TO_TAB_SIZES);
546 objectsExtra.addToTabSizes(sizes);
547 // Do nothing with |extra|.
548 }
550 FOR_EACH_SIZE(DECL_SIZE)
551 ObjectsExtraSizes objectsExtra;
552 void *extra; // This field can be used by embedders.
554 #undef FOR_EACH_SIZE
555 };
557 typedef js::Vector<CompartmentStats, 0, js::SystemAllocPolicy> CompartmentStatsVector;
558 typedef js::Vector<ZoneStats, 0, js::SystemAllocPolicy> ZoneStatsVector;
560 struct RuntimeStats
561 {
562 #define FOR_EACH_SIZE(macro) \
563 macro(_, _, gcHeapChunkTotal) \
564 macro(_, _, gcHeapDecommittedArenas) \
565 macro(_, _, gcHeapUnusedChunks) \
566 macro(_, _, gcHeapUnusedArenas) \
567 macro(_, _, gcHeapChunkAdmin) \
568 macro(_, _, gcHeapGCThings) \
570 RuntimeStats(mozilla::MallocSizeOf mallocSizeOf)
571 : FOR_EACH_SIZE(ZERO_SIZE)
572 runtime(),
573 cTotals(),
574 zTotals(),
575 compartmentStatsVector(),
576 zoneStatsVector(),
577 currZoneStats(nullptr),
578 mallocSizeOf_(mallocSizeOf)
579 {}
581 // Here's a useful breakdown of the GC heap.
582 //
583 // - rtStats.gcHeapChunkTotal
584 // - decommitted bytes
585 // - rtStats.gcHeapDecommittedArenas (decommitted arenas in non-empty chunks)
586 // - unused bytes
587 // - rtStats.gcHeapUnusedChunks (empty chunks)
588 // - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks)
589 // - rtStats.zTotals.unusedGCThings (empty GC thing slots within non-empty arenas)
590 // - used bytes
591 // - rtStats.gcHeapChunkAdmin
592 // - rtStats.zTotals.gcHeapArenaAdmin
593 // - rtStats.gcHeapGCThings (in-use GC things)
594 // == rtStats.zTotals.sizeOfLiveGCThings() + rtStats.cTotals.sizeOfLiveGCThings()
595 //
596 // It's possible that some arenas in empty chunks may be decommitted, but
597 // we don't count those under rtStats.gcHeapDecommittedArenas because (a)
598 // it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a
599 // multiple of the chunk size, which is good.
601 FOR_EACH_SIZE(DECL_SIZE)
603 RuntimeSizes runtime;
605 CompartmentStats cTotals; // The sum of this runtime's compartments' measurements.
606 ZoneStats zTotals; // The sum of this runtime's zones' measurements.
608 CompartmentStatsVector compartmentStatsVector;
609 ZoneStatsVector zoneStatsVector;
611 ZoneStats *currZoneStats;
613 mozilla::MallocSizeOf mallocSizeOf_;
615 virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0;
616 virtual void initExtraZoneStats(JS::Zone *zone, ZoneStats *zstats) = 0;
618 #undef FOR_EACH_SIZE
619 };
621 class ObjectPrivateVisitor
622 {
623 public:
624 // Within CollectRuntimeStats, this method is called for each JS object
625 // that has an nsISupports pointer.
626 virtual size_t sizeOfIncludingThis(nsISupports *aSupports) = 0;
628 // A callback that gets a JSObject's nsISupports pointer, if it has one.
629 // Note: this function does *not* addref |iface|.
630 typedef bool(*GetISupportsFun)(JSObject *obj, nsISupports **iface);
631 GetISupportsFun getISupports_;
633 ObjectPrivateVisitor(GetISupportsFun getISupports)
634 : getISupports_(getISupports)
635 {}
636 };
638 extern JS_PUBLIC_API(bool)
639 CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *opv);
641 extern JS_PUBLIC_API(size_t)
642 SystemCompartmentCount(JSRuntime *rt);
644 extern JS_PUBLIC_API(size_t)
645 UserCompartmentCount(JSRuntime *rt);
647 extern JS_PUBLIC_API(size_t)
648 PeakSizeOfTemporary(const JSRuntime *rt);
650 extern JS_PUBLIC_API(bool)
651 AddSizeOfTab(JSRuntime *rt, JS::HandleObject obj, mozilla::MallocSizeOf mallocSizeOf,
652 ObjectPrivateVisitor *opv, TabSizes *sizes);
654 } // namespace JS
656 #undef DECL_SIZE
657 #undef ZERO_SIZE
658 #undef COPY_OTHER_SIZE
659 #undef ADD_OTHER_SIZE
660 #undef SUB_OTHER_SIZE
661 #undef ADD_SIZE_TO_N
662 #undef ADD_SIZE_TO_N_IF_LIVE_GC_THING
663 #undef ADD_TO_TAB_SIZES
665 #endif /* js_MemoryMetrics_h */