xpcom/base/nsICycleCollectorListener.idl

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "nsISupports.idl"
michael@0 6
michael@0 7 /**
michael@0 8 * Interfaces for observing the cycle collector's work, both from C++ and
michael@0 9 * from JavaScript.
michael@0 10 *
michael@0 11 * If given an object implementing nsICycleCollectorListener, the cycle
michael@0 12 * collector calls that object's methods as it works, describing the
michael@0 13 * objects it visits, the edges it finds, and the conclusions it reaches
michael@0 14 * about which objects are live.
michael@0 15 *
michael@0 16 * Analyzing cycle collection from JS is harder: an nsICycleCollectorListener
michael@0 17 * mustn't mess with the object graph while the cycle collector is trying to
michael@0 18 * figure it out, which means it can't be implemented by JS code: JS can't do
michael@0 19 * much of anything useful within those constraints. Instead, JS code can
michael@0 20 * instantiate @mozilla.org/cycle-collector-logger;1, a C++ class implementing
michael@0 21 * nsICycleCollectorListener that logs the cycle collector's mumblings and then
michael@0 22 * replays them later to an nsICycleCollectorHandler --- which *can* be
michael@0 23 * implemented in JS.
michael@0 24 */
michael@0 25
michael@0 26 /**
michael@0 27 * The interface JS code should implement to receive annotations logged by an
michael@0 28 * @mozilla.org/cycle-collector-logger;1 instance. Pass an instance of this to
michael@0 29 * the logger's 'processNext' method.
michael@0 30 *
michael@0 31 * The methods are a subset of those in nsICycleCollectorListener; see the
michael@0 32 * descriptions there.
michael@0 33 */
michael@0 34 [scriptable, uuid(39a8f80e-7eee-4141-b9ef-6e2a7d6e466d)]
michael@0 35 interface nsICycleCollectorHandler : nsISupports
michael@0 36 {
michael@0 37 void noteRefCountedObject(in ACString aAddress,
michael@0 38 in unsigned long aRefCount,
michael@0 39 in ACString aObjectDescription);
michael@0 40 void noteGCedObject(in ACString aAddress,
michael@0 41 in boolean aMarked,
michael@0 42 in ACString aObjectDescription,
michael@0 43 in ACString aCompartmentAddress);
michael@0 44 void noteEdge(in ACString aFromAddress,
michael@0 45 in ACString aToAddress,
michael@0 46 in ACString aEdgeName);
michael@0 47 void describeRoot(in ACString aAddress,
michael@0 48 in unsigned long aKnownEdges);
michael@0 49 void describeGarbage(in ACString aAddress);
michael@0 50 };
michael@0 51
michael@0 52 /**
michael@0 53 * Given an instance of this interface, the cycle collector calls the instance's
michael@0 54 * methods to report the objects it visits, the edges between them, and its
michael@0 55 * conclusions about which objects are roots and which are garbage.
michael@0 56 *
michael@0 57 * For a single cycle collection pass, the cycle collector calls this
michael@0 58 * interface's methods in the following order:
michael@0 59 *
michael@0 60 * - First, |begin|. If |begin| returns an error, none of the listener's other
michael@0 61 * methods will be called.
michael@0 62 *
michael@0 63 * - Then, for each node in the graph:
michael@0 64 * - a call to either |noteRefCountedObject| or |noteGCedObject|, to describe
michael@0 65 * the node itself; and
michael@0 66 * - for each edge starting at that node, a call to |noteEdge|.
michael@0 67 *
michael@0 68 * - Then, zero or more calls to |noteIncrementalRoot|; an "incremental
michael@0 69 * root" is an object that may have had a new reference to it created
michael@0 70 * during an incremental collection, and must therefore be treated as
michael@0 71 * live for safety.
michael@0 72 *
michael@0 73 * - After all the nodes have been described, a call to |beginResults|.
michael@0 74 *
michael@0 75 * - A series of calls to:
michael@0 76 * - |describeRoot|, for reference-counted nodes that the CC has identified as
michael@0 77 * roots of collection. (The cycle collector didn't find enough incoming
michael@0 78 * edges to account for these nodes' reference counts, so there must be code
michael@0 79 * holding on to them that the cycle collector doesn't know about.)
michael@0 80 * - |describeGarbage|, for nodes the cycle collector has identified as garbage.
michael@0 81 *
michael@0 82 * Any node not mentioned in a call to |describeRoot| or |describeGarbage| is
michael@0 83 * neither a root nor garbage. (The cycle collector was able to find all the
michael@0 84 * edges implied by the node's reference count.)
michael@0 85 *
michael@0 86 * - Finally, a call to |end|.
michael@0 87 *
michael@0 88 *
michael@0 89 * This interface cannot be implemented by JavaScript code, as it is called
michael@0 90 * while the cycle collector works. To analyze cycle collection data in JS:
michael@0 91 *
michael@0 92 * - Create an instance of @mozilla.org/cycle-collector-logger;1, which
michael@0 93 * implements this interface.
michael@0 94 *
michael@0 95 * - Set its |disableLog| property to true. This prevents the logger from
michael@0 96 * printing messages about each method call to a temporary log file.
michael@0 97 *
michael@0 98 * - Set its |wantAfterProcessing| property to true. This tells the logger
michael@0 99 * to record calls to its methods in memory. The |processNext| method
michael@0 100 * returns events from this record.
michael@0 101 *
michael@0 102 * - Perform a collection using the logger. For example, call
michael@0 103 * |nsIDOMWindowUtils|'s |garbageCollect| method, passing the logger as
michael@0 104 * the |aListener| argument.
michael@0 105 *
michael@0 106 * - When the collection is complete, loop calling the logger's
michael@0 107 * |processNext| method, passing a JavaScript object that implements
michael@0 108 * nsICycleCollectorHandler. This JS code is free to allocate and operate
michael@0 109 * on objects however it pleases: the cycle collector has finished its
michael@0 110 * work, and the JS code is simply consuming recorded data.
michael@0 111 */
michael@0 112 [scriptable, builtinclass, uuid(c46e6947-9076-4a0e-bb27-d4aa3706c54d)]
michael@0 113 interface nsICycleCollectorListener : nsISupports
michael@0 114 {
michael@0 115 // Return a listener that directs the cycle collector to traverse
michael@0 116 // objects that it knows won't be collectable.
michael@0 117 //
michael@0 118 // Note that even this listener will not visit every node in the heap;
michael@0 119 // the cycle collector can't see the entire heap. But while this
michael@0 120 // listener is in use, the collector disables some optimizations it
michael@0 121 // normally uses to avoid certain classes of objects that are certainly
michael@0 122 // alive. So, if your purpose is to get a view of the portion of the
michael@0 123 // heap that is of interest to the cycle collector, and not simply find
michael@0 124 // garbage, then you should use the listener this returns.
michael@0 125 //
michael@0 126 // Note that this does not necessarily return a new listener; rather, it may
michael@0 127 // simply set a flag on this listener (a side effect!) and return it.
michael@0 128 nsICycleCollectorListener allTraces();
michael@0 129
michael@0 130 // True if this listener will behave like one returned by allTraces().
michael@0 131 readonly attribute boolean wantAllTraces;
michael@0 132
michael@0 133 // If true, do not log each method call to a temporary file.
michael@0 134 // Initially false.
michael@0 135 attribute boolean disableLog;
michael@0 136
michael@0 137 // This string will appear somewhere in the log's filename.
michael@0 138 attribute AString filenameIdentifier;
michael@0 139
michael@0 140 // If true, record all method calls in memory, to be retrieved later
michael@0 141 // using |processNext|. Initially false.
michael@0 142 attribute boolean wantAfterProcessing;
michael@0 143
michael@0 144 // This string will indicate the full path of the GC log if enabled.
michael@0 145 readonly attribute AString gcLogPath;
michael@0 146
michael@0 147 // This string will indicate the full path of the CC log if enabled.
michael@0 148 readonly attribute AString ccLogPath;
michael@0 149
michael@0 150 void begin();
michael@0 151 void noteRefCountedObject (in unsigned long long aAddress,
michael@0 152 in unsigned long aRefCount,
michael@0 153 in string aObjectDescription);
michael@0 154 void noteGCedObject (in unsigned long long aAddress,
michael@0 155 in boolean aMarked,
michael@0 156 in string aObjectDescription,
michael@0 157 in unsigned long long aCompartmentAddress);
michael@0 158 void noteEdge(in unsigned long long aToAddress,
michael@0 159 in string aEdgeName);
michael@0 160 void noteWeakMapEntry(in unsigned long long aMap,
michael@0 161 in unsigned long long aKey,
michael@0 162 in unsigned long long aKeyDelegate,
michael@0 163 in unsigned long long aValue);
michael@0 164 void noteIncrementalRoot(in unsigned long long aAddress);
michael@0 165
michael@0 166 void beginResults();
michael@0 167 void describeRoot(in unsigned long long aAddress,
michael@0 168 in unsigned long aKnownEdges);
michael@0 169 void describeGarbage(in unsigned long long aAddress);
michael@0 170 void end();
michael@0 171
michael@0 172 // Report the next recorded event to |aHandler|, and remove it from the
michael@0 173 // record. Return false if there isn't anything more to process.
michael@0 174 //
michael@0 175 // Note that we only record events to report here if our
michael@0 176 // |wantAfterProcessing| property is true.
michael@0 177 boolean processNext(in nsICycleCollectorHandler aHandler);
michael@0 178 };

mercurial