1/* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5#include "nsISupports.idl" 6 7%{C++ 8#include <stdio.h> 9 10class nsCycleCollectorLogger; 11%} 12 13[ptr] native FILE(FILE); 14[ptr] native nsCycleCollectorLoggerPtr(nsCycleCollectorLogger); 15interface nsIFile; 16 17/** 18 * A set of interfaces for recording the cycle collector's work. An instance 19 * of nsICycleCollectorListener can be configured to enable various 20 * options, then passed to the cycle collector when it runs. 21 * Note that additional logging options are available by setting environment 22 * variables, as described at the top of nsCycleCollector.cpp. 23 */ 24 25/** 26 * nsICycleCollectorHandler is the interface JS code should implement to 27 * receive the results logged by an nsICycleCollectorListener 28 * instance. Pass an instance of this to the logger's 'processNext' method 29 * after the collection has run. This will describe the objects the cycle 30 * collector visited, the edges it found, and the conclusions it reached 31 * about the liveness of objects. 32 * 33 * In more detail: 34 * - For each node in the graph: 35 * - a call is made to either |noteRefCountedObject| or |noteGCedObject|, to 36 * describe the node itself; and 37 * - for each edge starting at that node, a call is made to |noteEdge|. 38 * 39 * - Then, a series of calls are made to: 40 * - |describeRoot|, for reference-counted nodes that the CC has identified as 41 * being alive because there are unknown references to those nodes. 42 * - |describeGarbage|, for nodes the cycle collector has identified as garbage. 43 * 44 * Any node not mentioned in a call to |describeRoot| or |describeGarbage| is 45 * neither a root nor garbage. The cycle collector was able to find all of the 46 * edges implied by the node's reference count. 47 */ 48[scriptable, uuid(7f093367-1492-4b89-87af-c01dbc831246)] 49interface nsICycleCollectorHandler : nsISupports 50{ 51 void noteRefCountedObject(in ACString aAddress, 52 in unsigned long aRefCount, 53 in ACString aObjectDescription); 54 void noteGCedObject(in ACString aAddress, 55 in boolean aMarked, 56 in ACString aObjectDescription, 57 in ACString aCompartmentAddress); 58 void noteEdge(in ACString aFromAddress, 59 in ACString aToAddress, 60 in ACString aEdgeName); 61 void describeRoot(in ACString aAddress, 62 in unsigned long aKnownEdges); 63 void describeGarbage(in ACString aAddress); 64}; 65 66 67/** 68 * This interface allows replacing the log-writing backend for an 69 * nsICycleCollectorListener. As this interface is also called while 70 * the cycle collector is running, it cannot be implemented in JS. 71 */ 72[scriptable, builtinclass, uuid(3ad9875f-d0e4-4ac2-87e3-f127f6c02ce1)] 73interface nsICycleCollectorLogSink : nsISupports 74{ 75 [noscript] void open(out FILE aGCLog, out FILE aCCLog); 76 void closeGCLog(); 77 void closeCCLog(); 78 79 // This string will appear somewhere in the log's filename. 80 attribute AString filenameIdentifier; 81 82 // This is the process ID; it can be changed if logging is on behalf 83 // of another process. 84 attribute int32_t processIdentifier; 85 86 // The GC log file, if logging to files. 87 readonly attribute nsIFile gcLog; 88 89 // The CC log file, if logging to files. 90 readonly attribute nsIFile ccLog; 91}; 92 93 94/** 95 * This interface is used to configure some reporting options for the cycle 96 * collector. This interface cannot be implemented by JavaScript code, as it 97 * is called while the cycle collector is running. 98 * 99 * To analyze cycle collection data in JS: 100 * 101 * - Create an instance of nsICycleCollectorListener, which implements this 102 * interface. In C++, this can be done by calling 103 * nsCycleCollector_createLogger(). In JS, this can be done by calling 104 * Components.utils.createCCLogger(). 105 * 106 * - Set its |disableLog| property to true. This prevents the logger from 107 * printing messages about each method call to a temporary log file. 108 * 109 * - Set its |wantAfterProcessing| property to true. This tells the logger 110 * to record calls to its methods in memory. The |processNext| method 111 * returns events from this record. 112 * 113 * - Perform a collection using the logger. For example, call 114 * |nsIDOMWindowUtils|'s |garbageCollect| method, passing the logger as 115 * the |aListener| argument. 116 * 117 * - When the collection is complete, loop calling the logger's 118 * |processNext| method, passing a JavaScript object that implements 119 * nsICycleCollectorHandler. This JS code is free to allocate and operate 120 * on objects however it pleases: the cycle collector has finished its 121 * work, and the JS code is simply consuming recorded data. 122 */ 123[scriptable, builtinclass, uuid(703b53b6-24f6-40c6-9ea9-aeb2dc53d170)] 124interface nsICycleCollectorListener : nsISupports 125{ 126 // Return a listener that directs the cycle collector to traverse 127 // objects that it knows won't be collectable. 128 // 129 // Note that even this listener will not visit every node in the heap; 130 // the cycle collector can't see the entire heap. But while this 131 // listener is in use, the collector disables some optimizations it 132 // normally uses to avoid certain classes of objects that are certainly 133 // alive. So, if your purpose is to get a view of the portion of the 134 // heap that is of interest to the cycle collector, and not simply find 135 // garbage, then you should use the listener this returns. 136 // 137 // Note that this does not necessarily return a new listener; rather, it may 138 // simply set a flag on this listener (a side effect!) and return it. 139 nsICycleCollectorListener allTraces(); 140 141 // True if this listener will behave like one returned by allTraces(). 142 readonly attribute boolean wantAllTraces; 143 144 // If true, do not log each method call to a temporary file. 145 // Initially false. 146 attribute boolean disableLog; 147 148 // If |disableLog| is false, this object will be sent the log text. 149 attribute nsICycleCollectorLogSink logSink; 150 151 // If true, record all method calls in memory, to be retrieved later 152 // using |processNext|. Initially false. 153 attribute boolean wantAfterProcessing; 154 155 // Report the next recorded event to |aHandler|, and remove it from the 156 // record. Return false if there isn't anything more to process. 157 // 158 // Note that we only record events to report here if our 159 // |wantAfterProcessing| property is true. 160 boolean processNext(in nsICycleCollectorHandler aHandler); 161 162 // Return the current object as an nsCycleCollectorLogger*, which is the 163 // only class that should be implementing this interface. We need the 164 // concrete implementation type to help the GC rooting analysis. 165 [noscript] nsCycleCollectorLoggerPtr asLogger(); 166}; 167