js/public/TracingAPI.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef js_TracingAPI_h
michael@0 8 #define js_TracingAPI_h
michael@0 9
michael@0 10 #include "mozilla/NullPtr.h"
michael@0 11
michael@0 12 #include "jspubtd.h"
michael@0 13
michael@0 14 class JS_PUBLIC_API(JSTracer);
michael@0 15
michael@0 16 namespace JS {
michael@0 17 template <typename T> class Heap;
michael@0 18 template <typename T> class TenuredHeap;
michael@0 19 }
michael@0 20
michael@0 21 // Tracer callback, called for each traceable thing directly referenced by a
michael@0 22 // particular object or runtime structure. It is the callback responsibility
michael@0 23 // to ensure the traversal of the full object graph via calling eventually
michael@0 24 // JS_TraceChildren on the passed thing. In this case the callback must be
michael@0 25 // prepared to deal with cycles in the traversal graph.
michael@0 26 //
michael@0 27 // kind argument is one of JSTRACE_OBJECT, JSTRACE_STRING or a tag denoting
michael@0 28 // internal implementation-specific traversal kind. In the latter case the only
michael@0 29 // operations on thing that the callback can do is to call JS_TraceChildren or
michael@0 30 // JS_GetTraceThingInfo.
michael@0 31 //
michael@0 32 // If eagerlyTraceWeakMaps is true, when we trace a WeakMap visit all
michael@0 33 // of its mappings. This should be used in cases where the tracer
michael@0 34 // wants to use the existing liveness of entries.
michael@0 35 typedef void
michael@0 36 (* JSTraceCallback)(JSTracer *trc, void **thingp, JSGCTraceKind kind);
michael@0 37
michael@0 38 // Callback that JSTraceOp implementation can provide to return a string
michael@0 39 // describing the reference traced with JS_CallTracer.
michael@0 40 typedef void
michael@0 41 (* JSTraceNamePrinter)(JSTracer *trc, char *buf, size_t bufsize);
michael@0 42
michael@0 43 enum WeakMapTraceKind {
michael@0 44 DoNotTraceWeakMaps = 0,
michael@0 45 TraceWeakMapValues = 1,
michael@0 46 TraceWeakMapKeysValues = 2
michael@0 47 };
michael@0 48
michael@0 49 class JS_PUBLIC_API(JSTracer)
michael@0 50 {
michael@0 51 public:
michael@0 52 JSTracer(JSRuntime *rt, JSTraceCallback traceCallback,
michael@0 53 WeakMapTraceKind weakTraceKind = TraceWeakMapValues);
michael@0 54
michael@0 55 // Set debugging information about a reference to a traceable thing to prepare
michael@0 56 // for the following call to JS_CallTracer.
michael@0 57 //
michael@0 58 // When printer is null, arg must be const char * or char * C string naming
michael@0 59 // the reference and index must be either (size_t)-1 indicating that the name
michael@0 60 // alone describes the reference or it must be an index into some array vector
michael@0 61 // that stores the reference.
michael@0 62 //
michael@0 63 // When printer callback is not null, the arg and index arguments are
michael@0 64 // available to the callback as debugPrintArg_ and debugPrintIndex_ fields
michael@0 65 // of JSTracer.
michael@0 66 //
michael@0 67 // The storage for name or callback's arguments needs to live only until
michael@0 68 // the following call to JS_CallTracer returns.
michael@0 69 void setTracingDetails(JSTraceNamePrinter printer, const void *arg, size_t index) {
michael@0 70 debugPrinter_ = printer;
michael@0 71 debugPrintArg_ = arg;
michael@0 72 debugPrintIndex_ = index;
michael@0 73 }
michael@0 74
michael@0 75 void setTracingIndex(const char *name, size_t index) {
michael@0 76 setTracingDetails(nullptr, (void *)name, index);
michael@0 77 }
michael@0 78
michael@0 79 void setTracingName(const char *name) {
michael@0 80 setTracingDetails(nullptr, (void *)name, size_t(-1));
michael@0 81 }
michael@0 82
michael@0 83 // Remove the currently set tracing details.
michael@0 84 void clearTracingDetails() {
michael@0 85 debugPrinter_ = nullptr;
michael@0 86 debugPrintArg_ = nullptr;
michael@0 87 }
michael@0 88
michael@0 89 // Return true if tracing details are currently set.
michael@0 90 bool hasTracingDetails() const;
michael@0 91
michael@0 92 // Get the string set with the most recent call to setTracingName or return
michael@0 93 // fallback if a name printer function has been installed.
michael@0 94 const char *tracingName(const char *fallback) const;
michael@0 95
michael@0 96 // Build a description of this edge in the heap graph. This call may invoke
michael@0 97 // the debug printer, which may inspect arbitrary areas of the heap.
michael@0 98 const char *getTracingEdgeName(char *buffer, size_t bufferSize);
michael@0 99
michael@0 100 // Access the currently active tracing details.
michael@0 101 JSTraceNamePrinter debugPrinter() const;
michael@0 102 const void *debugPrintArg() const;
michael@0 103 size_t debugPrintIndex() const;
michael@0 104
michael@0 105 // Return the runtime set on the tracer.
michael@0 106 JSRuntime *runtime() const { return runtime_; }
michael@0 107
michael@0 108 // Return the weak map tracing behavior set on this tracer.
michael@0 109 WeakMapTraceKind eagerlyTraceWeakMaps() const { return eagerlyTraceWeakMaps_; }
michael@0 110
michael@0 111 // Update the trace callback.
michael@0 112 void setTraceCallback(JSTraceCallback traceCallback);
michael@0 113
michael@0 114 #ifdef JS_GC_ZEAL
michael@0 115 // Sets the "real" location for a marked reference, when passing the address
michael@0 116 // directly is not feasable. This address is used for matching against the
michael@0 117 // store buffer when verifying the correctness of the entrees there.
michael@0 118 //
michael@0 119 // This is currently complicated by our need to nest calls for Values
michael@0 120 // stored as keys in hash tables.
michael@0 121 void setTracingLocation(void *location);
michael@0 122 void unsetTracingLocation();
michael@0 123 void **tracingLocation(void **thingp);
michael@0 124 #else
michael@0 125 void setTracingLocation(void *location) {}
michael@0 126 void unsetTracingLocation() {}
michael@0 127 void **tracingLocation(void **thingp) { return nullptr; }
michael@0 128 #endif
michael@0 129
michael@0 130 // We expose |callback| directly so that IS_GC_MARKING_TRACER can compare
michael@0 131 // it to GCMarker::GrayCallback.
michael@0 132 JSTraceCallback callback;
michael@0 133
michael@0 134 private:
michael@0 135 JSRuntime *runtime_;
michael@0 136 JSTraceNamePrinter debugPrinter_;
michael@0 137 const void *debugPrintArg_;
michael@0 138 size_t debugPrintIndex_;
michael@0 139 WeakMapTraceKind eagerlyTraceWeakMaps_;
michael@0 140 #ifdef JS_GC_ZEAL
michael@0 141 void *realLocation_;
michael@0 142 #endif
michael@0 143 };
michael@0 144
michael@0 145 // The JS_Call*Tracer family of functions traces the given GC thing reference.
michael@0 146 // This performs the tracing action configured on the given JSTracer:
michael@0 147 // typically calling the JSTracer::callback or marking the thing as live.
michael@0 148 //
michael@0 149 // The argument to JS_Call*Tracer is an in-out param: when the function
michael@0 150 // returns, the garbage collector might have moved the GC thing. In this case,
michael@0 151 // the reference passed to JS_Call*Tracer will be updated to the object's new
michael@0 152 // location. Callers of this method are responsible for updating any state
michael@0 153 // that is dependent on the object's address. For example, if the object's
michael@0 154 // address is used as a key in a hashtable, then the object must be removed
michael@0 155 // and re-inserted with the correct hash.
michael@0 156 //
michael@0 157 extern JS_PUBLIC_API(void)
michael@0 158 JS_CallValueTracer(JSTracer *trc, JS::Value *valuep, const char *name);
michael@0 159
michael@0 160 extern JS_PUBLIC_API(void)
michael@0 161 JS_CallIdTracer(JSTracer *trc, jsid *idp, const char *name);
michael@0 162
michael@0 163 extern JS_PUBLIC_API(void)
michael@0 164 JS_CallObjectTracer(JSTracer *trc, JSObject **objp, const char *name);
michael@0 165
michael@0 166 extern JS_PUBLIC_API(void)
michael@0 167 JS_CallStringTracer(JSTracer *trc, JSString **strp, const char *name);
michael@0 168
michael@0 169 extern JS_PUBLIC_API(void)
michael@0 170 JS_CallScriptTracer(JSTracer *trc, JSScript **scriptp, const char *name);
michael@0 171
michael@0 172 extern JS_PUBLIC_API(void)
michael@0 173 JS_CallHeapValueTracer(JSTracer *trc, JS::Heap<JS::Value> *valuep, const char *name);
michael@0 174
michael@0 175 extern JS_PUBLIC_API(void)
michael@0 176 JS_CallHeapIdTracer(JSTracer *trc, JS::Heap<jsid> *idp, const char *name);
michael@0 177
michael@0 178 extern JS_PUBLIC_API(void)
michael@0 179 JS_CallHeapObjectTracer(JSTracer *trc, JS::Heap<JSObject *> *objp, const char *name);
michael@0 180
michael@0 181 extern JS_PUBLIC_API(void)
michael@0 182 JS_CallHeapStringTracer(JSTracer *trc, JS::Heap<JSString *> *strp, const char *name);
michael@0 183
michael@0 184 extern JS_PUBLIC_API(void)
michael@0 185 JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap<JSScript *> *scriptp, const char *name);
michael@0 186
michael@0 187 extern JS_PUBLIC_API(void)
michael@0 188 JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap<JSFunction *> *funp, const char *name);
michael@0 189
michael@0 190 template <typename HashSetEnum>
michael@0 191 inline void
michael@0 192 JS_CallHashSetObjectTracer(JSTracer *trc, HashSetEnum &e, JSObject *const &key, const char *name)
michael@0 193 {
michael@0 194 JSObject *updated = key;
michael@0 195 trc->setTracingLocation(reinterpret_cast<void *>(&const_cast<JSObject *&>(key)));
michael@0 196 JS_CallObjectTracer(trc, &updated, name);
michael@0 197 if (updated != key)
michael@0 198 e.rekeyFront(key, updated);
michael@0 199 }
michael@0 200
michael@0 201 // Trace an object that is known to always be tenured. No post barriers are
michael@0 202 // required in this case.
michael@0 203 extern JS_PUBLIC_API(void)
michael@0 204 JS_CallTenuredObjectTracer(JSTracer *trc, JS::TenuredHeap<JSObject *> *objp, const char *name);
michael@0 205
michael@0 206 extern JS_PUBLIC_API(void)
michael@0 207 JS_TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind);
michael@0 208
michael@0 209 extern JS_PUBLIC_API(void)
michael@0 210 JS_TraceRuntime(JSTracer *trc);
michael@0 211
michael@0 212 extern JS_PUBLIC_API(void)
michael@0 213 JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
michael@0 214 void *thing, JSGCTraceKind kind, bool includeDetails);
michael@0 215
michael@0 216 #endif /* js_TracingAPI_h */

mercurial