1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/public/TracingAPI.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,216 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef js_TracingAPI_h 1.11 +#define js_TracingAPI_h 1.12 + 1.13 +#include "mozilla/NullPtr.h" 1.14 + 1.15 +#include "jspubtd.h" 1.16 + 1.17 +class JS_PUBLIC_API(JSTracer); 1.18 + 1.19 +namespace JS { 1.20 +template <typename T> class Heap; 1.21 +template <typename T> class TenuredHeap; 1.22 +} 1.23 + 1.24 +// Tracer callback, called for each traceable thing directly referenced by a 1.25 +// particular object or runtime structure. It is the callback responsibility 1.26 +// to ensure the traversal of the full object graph via calling eventually 1.27 +// JS_TraceChildren on the passed thing. In this case the callback must be 1.28 +// prepared to deal with cycles in the traversal graph. 1.29 +// 1.30 +// kind argument is one of JSTRACE_OBJECT, JSTRACE_STRING or a tag denoting 1.31 +// internal implementation-specific traversal kind. In the latter case the only 1.32 +// operations on thing that the callback can do is to call JS_TraceChildren or 1.33 +// JS_GetTraceThingInfo. 1.34 +// 1.35 +// If eagerlyTraceWeakMaps is true, when we trace a WeakMap visit all 1.36 +// of its mappings. This should be used in cases where the tracer 1.37 +// wants to use the existing liveness of entries. 1.38 +typedef void 1.39 +(* JSTraceCallback)(JSTracer *trc, void **thingp, JSGCTraceKind kind); 1.40 + 1.41 +// Callback that JSTraceOp implementation can provide to return a string 1.42 +// describing the reference traced with JS_CallTracer. 1.43 +typedef void 1.44 +(* JSTraceNamePrinter)(JSTracer *trc, char *buf, size_t bufsize); 1.45 + 1.46 +enum WeakMapTraceKind { 1.47 + DoNotTraceWeakMaps = 0, 1.48 + TraceWeakMapValues = 1, 1.49 + TraceWeakMapKeysValues = 2 1.50 +}; 1.51 + 1.52 +class JS_PUBLIC_API(JSTracer) 1.53 +{ 1.54 + public: 1.55 + JSTracer(JSRuntime *rt, JSTraceCallback traceCallback, 1.56 + WeakMapTraceKind weakTraceKind = TraceWeakMapValues); 1.57 + 1.58 + // Set debugging information about a reference to a traceable thing to prepare 1.59 + // for the following call to JS_CallTracer. 1.60 + // 1.61 + // When printer is null, arg must be const char * or char * C string naming 1.62 + // the reference and index must be either (size_t)-1 indicating that the name 1.63 + // alone describes the reference or it must be an index into some array vector 1.64 + // that stores the reference. 1.65 + // 1.66 + // When printer callback is not null, the arg and index arguments are 1.67 + // available to the callback as debugPrintArg_ and debugPrintIndex_ fields 1.68 + // of JSTracer. 1.69 + // 1.70 + // The storage for name or callback's arguments needs to live only until 1.71 + // the following call to JS_CallTracer returns. 1.72 + void setTracingDetails(JSTraceNamePrinter printer, const void *arg, size_t index) { 1.73 + debugPrinter_ = printer; 1.74 + debugPrintArg_ = arg; 1.75 + debugPrintIndex_ = index; 1.76 + } 1.77 + 1.78 + void setTracingIndex(const char *name, size_t index) { 1.79 + setTracingDetails(nullptr, (void *)name, index); 1.80 + } 1.81 + 1.82 + void setTracingName(const char *name) { 1.83 + setTracingDetails(nullptr, (void *)name, size_t(-1)); 1.84 + } 1.85 + 1.86 + // Remove the currently set tracing details. 1.87 + void clearTracingDetails() { 1.88 + debugPrinter_ = nullptr; 1.89 + debugPrintArg_ = nullptr; 1.90 + } 1.91 + 1.92 + // Return true if tracing details are currently set. 1.93 + bool hasTracingDetails() const; 1.94 + 1.95 + // Get the string set with the most recent call to setTracingName or return 1.96 + // fallback if a name printer function has been installed. 1.97 + const char *tracingName(const char *fallback) const; 1.98 + 1.99 + // Build a description of this edge in the heap graph. This call may invoke 1.100 + // the debug printer, which may inspect arbitrary areas of the heap. 1.101 + const char *getTracingEdgeName(char *buffer, size_t bufferSize); 1.102 + 1.103 + // Access the currently active tracing details. 1.104 + JSTraceNamePrinter debugPrinter() const; 1.105 + const void *debugPrintArg() const; 1.106 + size_t debugPrintIndex() const; 1.107 + 1.108 + // Return the runtime set on the tracer. 1.109 + JSRuntime *runtime() const { return runtime_; } 1.110 + 1.111 + // Return the weak map tracing behavior set on this tracer. 1.112 + WeakMapTraceKind eagerlyTraceWeakMaps() const { return eagerlyTraceWeakMaps_; } 1.113 + 1.114 + // Update the trace callback. 1.115 + void setTraceCallback(JSTraceCallback traceCallback); 1.116 + 1.117 +#ifdef JS_GC_ZEAL 1.118 + // Sets the "real" location for a marked reference, when passing the address 1.119 + // directly is not feasable. This address is used for matching against the 1.120 + // store buffer when verifying the correctness of the entrees there. 1.121 + // 1.122 + // This is currently complicated by our need to nest calls for Values 1.123 + // stored as keys in hash tables. 1.124 + void setTracingLocation(void *location); 1.125 + void unsetTracingLocation(); 1.126 + void **tracingLocation(void **thingp); 1.127 +#else 1.128 + void setTracingLocation(void *location) {} 1.129 + void unsetTracingLocation() {} 1.130 + void **tracingLocation(void **thingp) { return nullptr; } 1.131 +#endif 1.132 + 1.133 + // We expose |callback| directly so that IS_GC_MARKING_TRACER can compare 1.134 + // it to GCMarker::GrayCallback. 1.135 + JSTraceCallback callback; 1.136 + 1.137 + private: 1.138 + JSRuntime *runtime_; 1.139 + JSTraceNamePrinter debugPrinter_; 1.140 + const void *debugPrintArg_; 1.141 + size_t debugPrintIndex_; 1.142 + WeakMapTraceKind eagerlyTraceWeakMaps_; 1.143 +#ifdef JS_GC_ZEAL 1.144 + void *realLocation_; 1.145 +#endif 1.146 +}; 1.147 + 1.148 +// The JS_Call*Tracer family of functions traces the given GC thing reference. 1.149 +// This performs the tracing action configured on the given JSTracer: 1.150 +// typically calling the JSTracer::callback or marking the thing as live. 1.151 +// 1.152 +// The argument to JS_Call*Tracer is an in-out param: when the function 1.153 +// returns, the garbage collector might have moved the GC thing. In this case, 1.154 +// the reference passed to JS_Call*Tracer will be updated to the object's new 1.155 +// location. Callers of this method are responsible for updating any state 1.156 +// that is dependent on the object's address. For example, if the object's 1.157 +// address is used as a key in a hashtable, then the object must be removed 1.158 +// and re-inserted with the correct hash. 1.159 +// 1.160 +extern JS_PUBLIC_API(void) 1.161 +JS_CallValueTracer(JSTracer *trc, JS::Value *valuep, const char *name); 1.162 + 1.163 +extern JS_PUBLIC_API(void) 1.164 +JS_CallIdTracer(JSTracer *trc, jsid *idp, const char *name); 1.165 + 1.166 +extern JS_PUBLIC_API(void) 1.167 +JS_CallObjectTracer(JSTracer *trc, JSObject **objp, const char *name); 1.168 + 1.169 +extern JS_PUBLIC_API(void) 1.170 +JS_CallStringTracer(JSTracer *trc, JSString **strp, const char *name); 1.171 + 1.172 +extern JS_PUBLIC_API(void) 1.173 +JS_CallScriptTracer(JSTracer *trc, JSScript **scriptp, const char *name); 1.174 + 1.175 +extern JS_PUBLIC_API(void) 1.176 +JS_CallHeapValueTracer(JSTracer *trc, JS::Heap<JS::Value> *valuep, const char *name); 1.177 + 1.178 +extern JS_PUBLIC_API(void) 1.179 +JS_CallHeapIdTracer(JSTracer *trc, JS::Heap<jsid> *idp, const char *name); 1.180 + 1.181 +extern JS_PUBLIC_API(void) 1.182 +JS_CallHeapObjectTracer(JSTracer *trc, JS::Heap<JSObject *> *objp, const char *name); 1.183 + 1.184 +extern JS_PUBLIC_API(void) 1.185 +JS_CallHeapStringTracer(JSTracer *trc, JS::Heap<JSString *> *strp, const char *name); 1.186 + 1.187 +extern JS_PUBLIC_API(void) 1.188 +JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap<JSScript *> *scriptp, const char *name); 1.189 + 1.190 +extern JS_PUBLIC_API(void) 1.191 +JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap<JSFunction *> *funp, const char *name); 1.192 + 1.193 +template <typename HashSetEnum> 1.194 +inline void 1.195 +JS_CallHashSetObjectTracer(JSTracer *trc, HashSetEnum &e, JSObject *const &key, const char *name) 1.196 +{ 1.197 + JSObject *updated = key; 1.198 + trc->setTracingLocation(reinterpret_cast<void *>(&const_cast<JSObject *&>(key))); 1.199 + JS_CallObjectTracer(trc, &updated, name); 1.200 + if (updated != key) 1.201 + e.rekeyFront(key, updated); 1.202 +} 1.203 + 1.204 +// Trace an object that is known to always be tenured. No post barriers are 1.205 +// required in this case. 1.206 +extern JS_PUBLIC_API(void) 1.207 +JS_CallTenuredObjectTracer(JSTracer *trc, JS::TenuredHeap<JSObject *> *objp, const char *name); 1.208 + 1.209 +extern JS_PUBLIC_API(void) 1.210 +JS_TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind); 1.211 + 1.212 +extern JS_PUBLIC_API(void) 1.213 +JS_TraceRuntime(JSTracer *trc); 1.214 + 1.215 +extern JS_PUBLIC_API(void) 1.216 +JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, 1.217 + void *thing, JSGCTraceKind kind, bool includeDetails); 1.218 + 1.219 +#endif /* js_TracingAPI_h */