js/public/MemoryMetrics.h

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     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 */

mercurial