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_TracingAPI_h
8 #define js_TracingAPI_h
13 #include "js/HashTable.h"
15 class JS_PUBLIC_API(JSTracer
);
18 template <typename T
> class Heap
;
19 template <typename T
> class TenuredHeap
;
22 // When tracing a thing, the GC needs to know about the layout of the object it
23 // is looking at. There are a fixed number of different layouts that the GC
24 // knows about. The "trace kind" is a static map which tells which layout a GC
27 // Although this map is public, the details are completely hidden. Not all of
28 // the matching C++ types are exposed, and those that are, are opaque.
30 // See Value::gcKind() and JSTraceCallback in Tracer.h for more details.
33 // These trace kinds have a publicly exposed, although opaque, C++ type.
34 // Note: The order here is determined by our Value packing. Other users
35 // should sort alphabetically, for consistency.
36 JSTRACE_OBJECT
= 0x00,
37 JSTRACE_STRING
= 0x01,
38 JSTRACE_SYMBOL
= 0x02,
39 JSTRACE_SCRIPT
= 0x03,
41 // Shape details are exposed through JS_TraceShapeCycleCollectorChildren.
44 // The kind associated with a nullptr.
47 // A kind that indicates the real kind should be looked up in the arena.
48 JSTRACE_OUTOFLINE
= 0x07,
50 // The following kinds do not have an exposed C++ idiom.
51 JSTRACE_BASE_SHAPE
= 0x0F,
52 JSTRACE_JITCODE
= 0x1F,
53 JSTRACE_LAZY_SCRIPT
= 0x2F,
54 JSTRACE_TYPE_OBJECT
= 0x3F,
56 JSTRACE_LAST
= JSTRACE_TYPE_OBJECT
60 // Returns a static string equivalent of |kind|.
61 JS_FRIEND_API(const char*)
62 GCTraceKindToAscii(JSGCTraceKind kind
);
65 // Tracer callback, called for each traceable thing directly referenced by a
66 // particular object or runtime structure. It is the callback responsibility
67 // to ensure the traversal of the full object graph via calling eventually
68 // JS_TraceChildren on the passed thing. In this case the callback must be
69 // prepared to deal with cycles in the traversal graph.
71 // kind argument is one of JSTRACE_OBJECT, JSTRACE_STRING or a tag denoting
72 // internal implementation-specific traversal kind. In the latter case the only
73 // operations on thing that the callback can do is to call JS_TraceChildren or
74 // JS_GetTraceThingInfo.
76 // If eagerlyTraceWeakMaps is true, when we trace a WeakMap visit all
77 // of its mappings. This should be used in cases where the tracer
78 // wants to use the existing liveness of entries.
80 (* JSTraceCallback
)(JSTracer
* trc
, void** thingp
, JSGCTraceKind kind
);
82 // Callback that JSTraceOp implementation can provide to return a string
83 // describing the reference traced with JS_CallTracer.
85 (* JSTraceNamePrinter
)(JSTracer
* trc
, char* buf
, size_t bufsize
);
87 enum WeakMapTraceKind
{
88 DoNotTraceWeakMaps
= 0,
89 TraceWeakMapValues
= 1,
90 TraceWeakMapKeysValues
= 2
93 class JS_PUBLIC_API(JSTracer
)
96 JSTracer(JSRuntime
* rt
, JSTraceCallback traceCallback
,
97 WeakMapTraceKind weakTraceKind
= TraceWeakMapValues
);
99 // Set debugging information about a reference to a traceable thing to prepare
100 // for the following call to JS_CallTracer.
102 // When printer is null, arg must be const char * or char * C string naming
103 // the reference and index must be either (size_t)-1 indicating that the name
104 // alone describes the reference or it must be an index into some array vector
105 // that stores the reference.
107 // When printer callback is not null, the arg and index arguments are
108 // available to the callback as debugPrintArg_ and debugPrintIndex_ fields
111 // The storage for name or callback's arguments needs to live only until
112 // the following call to JS_CallTracer returns.
113 void setTracingDetails(JSTraceNamePrinter printer
, const void* arg
, size_t index
) {
114 debugPrinter_
= printer
;
115 debugPrintArg_
= arg
;
116 debugPrintIndex_
= index
;
119 void setTracingIndex(const char* name
, size_t index
) {
120 setTracingDetails(nullptr, (void*)name
, index
);
123 void setTracingName(const char* name
) {
124 setTracingDetails(nullptr, (void*)name
, size_t(-1));
127 // Remove the currently set tracing details.
128 void clearTracingDetails() {
129 debugPrinter_
= nullptr;
130 debugPrintArg_
= nullptr;
133 // Return true if tracing details are currently set.
134 bool hasTracingDetails() const;
136 // Get the string set with the most recent call to setTracingName or return
137 // fallback if a name printer function has been installed.
138 const char* tracingName(const char* fallback
) const;
140 // Build a description of this edge in the heap graph. This call may invoke
141 // the debug printer, which may inspect arbitrary areas of the heap.
142 const char* getTracingEdgeName(char* buffer
, size_t bufferSize
);
144 // Access the currently active tracing details.
145 JSTraceNamePrinter
debugPrinter() const;
146 const void* debugPrintArg() const;
147 size_t debugPrintIndex() const;
149 // Return the runtime set on the tracer.
150 JSRuntime
* runtime() const { return runtime_
; }
152 // Return the weak map tracing behavior set on this tracer.
153 WeakMapTraceKind
eagerlyTraceWeakMaps() const { return eagerlyTraceWeakMaps_
; }
155 // Update the trace callback.
156 void setTraceCallback(JSTraceCallback traceCallback
);
159 // Sets the "real" location for a marked reference, when passing the address
160 // directly is not feasable. This address is used for matching against the
161 // store buffer when verifying the correctness of the entrees there.
163 // This is currently complicated by our need to nest calls for Values
164 // stored as keys in hash tables.
165 void setTracingLocation(void* location
);
166 void unsetTracingLocation();
167 void** tracingLocation(void** thingp
);
169 void setTracingLocation(void* location
) {}
170 void unsetTracingLocation() {}
171 void** tracingLocation(void** thingp
) { return nullptr; }
174 // We expose |callback| directly so that IS_GC_MARKING_TRACER can compare
175 // it to GCMarker::GrayCallback.
176 JSTraceCallback callback
;
180 JSTraceNamePrinter debugPrinter_
;
181 const void* debugPrintArg_
;
182 size_t debugPrintIndex_
;
183 WeakMapTraceKind eagerlyTraceWeakMaps_
;
189 // The JS_Call*Tracer family of functions traces the given GC thing reference.
190 // This performs the tracing action configured on the given JSTracer:
191 // typically calling the JSTracer::callback or marking the thing as live.
193 // The argument to JS_Call*Tracer is an in-out param: when the function
194 // returns, the garbage collector might have moved the GC thing. In this case,
195 // the reference passed to JS_Call*Tracer will be updated to the object's new
196 // location. Callers of this method are responsible for updating any state
197 // that is dependent on the object's address. For example, if the object's
198 // address is used as a key in a hashtable, then the object must be removed
199 // and re-inserted with the correct hash.
201 extern JS_PUBLIC_API(void)
202 JS_CallValueTracer(JSTracer
* trc
, JS::Heap
<JS::Value
>* valuep
, const char* name
);
204 extern JS_PUBLIC_API(void)
205 JS_CallIdTracer(JSTracer
* trc
, JS::Heap
<jsid
>* idp
, const char* name
);
207 extern JS_PUBLIC_API(void)
208 JS_CallObjectTracer(JSTracer
* trc
, JS::Heap
<JSObject
*>* objp
, const char* name
);
210 extern JS_PUBLIC_API(void)
211 JS_CallStringTracer(JSTracer
* trc
, JS::Heap
<JSString
*>* strp
, const char* name
);
213 extern JS_PUBLIC_API(void)
214 JS_CallScriptTracer(JSTracer
* trc
, JS::Heap
<JSScript
*>* scriptp
, const char* name
);
216 extern JS_PUBLIC_API(void)
217 JS_CallFunctionTracer(JSTracer
* trc
, JS::Heap
<JSFunction
*>* funp
, const char* name
);
219 // The following JS_CallUnbarriered*Tracer functions should only be called where
220 // you know for sure that a heap post barrier is not required. Use with extreme
222 extern JS_PUBLIC_API(void)
223 JS_CallUnbarrieredValueTracer(JSTracer
* trc
, JS::Value
* valuep
, const char* name
);
225 extern JS_PUBLIC_API(void)
226 JS_CallUnbarrieredIdTracer(JSTracer
* trc
, jsid
* idp
, const char* name
);
228 extern JS_PUBLIC_API(void)
229 JS_CallUnbarrieredObjectTracer(JSTracer
* trc
, JSObject
** objp
, const char* name
);
231 extern JS_PUBLIC_API(void)
232 JS_CallUnbarrieredStringTracer(JSTracer
* trc
, JSString
** strp
, const char* name
);
234 extern JS_PUBLIC_API(void)
235 JS_CallUnbarrieredScriptTracer(JSTracer
* trc
, JSScript
** scriptp
, const char* name
);
237 template <typename HashSetEnum
>
239 JS_CallHashSetObjectTracer(JSTracer
* trc
, HashSetEnum
& e
, JSObject
* const& key
, const char* name
)
241 JSObject
* updated
= key
;
242 trc
->setTracingLocation(reinterpret_cast<void*>(&const_cast<JSObject
*&>(key
)));
243 JS_CallUnbarrieredObjectTracer(trc
, &updated
, name
);
245 e
.rekeyFront(updated
);
248 // Trace an object that is known to always be tenured. No post barriers are
249 // required in this case.
250 extern JS_PUBLIC_API(void)
251 JS_CallTenuredObjectTracer(JSTracer
* trc
, JS::TenuredHeap
<JSObject
*>* objp
, const char* name
);
253 extern JS_PUBLIC_API(void)
254 JS_TraceChildren(JSTracer
* trc
, void* thing
, JSGCTraceKind kind
);
256 extern JS_PUBLIC_API(void)
257 JS_TraceRuntime(JSTracer
* trc
);
260 typedef js::HashSet
<Zone
*, js::DefaultHasher
<Zone
*>, js::SystemAllocPolicy
> ZoneSet
;
263 // Trace every value within |zones| that is wrapped by a cross-compartment
264 // wrapper from a zone that is not an element of |zones|.
265 extern JS_PUBLIC_API(void)
266 JS_TraceIncomingCCWs(JSTracer
* trc
, const JS::ZoneSet
& zones
);
268 extern JS_PUBLIC_API(void)
269 JS_GetTraceThingInfo(char* buf
, size_t bufsize
, JSTracer
* trc
,
270 void* thing
, JSGCTraceKind kind
, bool includeDetails
);
272 #endif /* js_TracingAPI_h */