js/src/gc/Marking.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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 gc_Marking_h
michael@0 8 #define gc_Marking_h
michael@0 9
michael@0 10 #include "gc/Barrier.h"
michael@0 11
michael@0 12 class JSAtom;
michael@0 13 class JSLinearString;
michael@0 14
michael@0 15 namespace js {
michael@0 16
michael@0 17 class ArgumentsObject;
michael@0 18 class ArrayBufferObject;
michael@0 19 class ArrayBufferViewObject;
michael@0 20 class SharedArrayBufferObject;
michael@0 21 class BaseShape;
michael@0 22 class DebugScopeObject;
michael@0 23 struct GCMarker;
michael@0 24 class GlobalObject;
michael@0 25 class LazyScript;
michael@0 26 class ScopeObject;
michael@0 27 class Shape;
michael@0 28 class UnownedBaseShape;
michael@0 29
michael@0 30 template<class, typename> class HeapPtr;
michael@0 31
michael@0 32 namespace jit {
michael@0 33 class JitCode;
michael@0 34 class IonScript;
michael@0 35 class VMFunction;
michael@0 36 }
michael@0 37
michael@0 38 namespace types {
michael@0 39 class Type;
michael@0 40 }
michael@0 41
michael@0 42 namespace gc {
michael@0 43
michael@0 44 /*** Object Marking ***/
michael@0 45
michael@0 46 /*
michael@0 47 * These functions expose marking functionality for all of the different GC
michael@0 48 * thing kinds. For each GC thing, there are several variants. As an example,
michael@0 49 * these are the variants generated for JSObject. They are listed from most to
michael@0 50 * least desirable for use:
michael@0 51 *
michael@0 52 * MarkObject(JSTracer *trc, const HeapPtr<JSObject> &thing, const char *name);
michael@0 53 * This function should be used for marking JSObjects, in preference to all
michael@0 54 * others below. Use it when you have HeapPtr<JSObject>, which
michael@0 55 * automatically implements write barriers.
michael@0 56 *
michael@0 57 * MarkObjectRoot(JSTracer *trc, JSObject *thing, const char *name);
michael@0 58 * This function is only valid during the root marking phase of GC (i.e.,
michael@0 59 * when MarkRuntime is on the stack).
michael@0 60 *
michael@0 61 * MarkObjectUnbarriered(JSTracer *trc, JSObject *thing, const char *name);
michael@0 62 * Like MarkObject, this function can be called at any time. It is more
michael@0 63 * forgiving, since it doesn't demand a HeapPtr as an argument. Its use
michael@0 64 * should always be accompanied by a comment explaining how write barriers
michael@0 65 * are implemented for the given field.
michael@0 66 *
michael@0 67 * Additionally, the functions MarkObjectRange and MarkObjectRootRange are
michael@0 68 * defined for marking arrays of object pointers.
michael@0 69 *
michael@0 70 * The following functions are provided to test whether a GC thing is marked
michael@0 71 * under different circumstances:
michael@0 72 *
michael@0 73 * IsObjectAboutToBeFinalized(JSObject **thing);
michael@0 74 * This function is indended to be used in code used to sweep GC things. It
michael@0 75 * indicates whether the object will will be finialized in the current group
michael@0 76 * of compartments being swept. Note that this will return false for any
michael@0 77 * object not in the group of compartments currently being swept, as even if
michael@0 78 * it is unmarked it may still become marked before it is swept.
michael@0 79 *
michael@0 80 * IsObjectMarked(JSObject **thing);
michael@0 81 * This function is indended to be used in rare cases in code used to mark
michael@0 82 * GC things. It indicates whether the object is currently marked.
michael@0 83 *
michael@0 84 * UpdateObjectIfRelocated(JSObject **thingp);
michael@0 85 * In some circumstances -- e.g. optional weak marking -- it is necessary
michael@0 86 * to look at the pointer before marking it strongly or weakly. In these
michael@0 87 * cases, the following must be called to update the pointer before use.
michael@0 88 */
michael@0 89
michael@0 90 #define DeclMarker(base, type) \
michael@0 91 void Mark##base(JSTracer *trc, BarrieredPtr<type> *thing, const char *name); \
michael@0 92 void Mark##base##Root(JSTracer *trc, type **thingp, const char *name); \
michael@0 93 void Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name); \
michael@0 94 void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *thing, const char *name); \
michael@0 95 void Mark##base##RootRange(JSTracer *trc, size_t len, type **thing, const char *name); \
michael@0 96 bool Is##base##Marked(type **thingp); \
michael@0 97 bool Is##base##Marked(BarrieredPtr<type> *thingp); \
michael@0 98 bool Is##base##AboutToBeFinalized(type **thingp); \
michael@0 99 bool Is##base##AboutToBeFinalized(BarrieredPtr<type> *thingp); \
michael@0 100 type *Update##base##IfRelocated(JSRuntime *rt, BarrieredPtr<type> *thingp); \
michael@0 101 type *Update##base##IfRelocated(JSRuntime *rt, type **thingp);
michael@0 102
michael@0 103 DeclMarker(BaseShape, BaseShape)
michael@0 104 DeclMarker(BaseShape, UnownedBaseShape)
michael@0 105 DeclMarker(JitCode, jit::JitCode)
michael@0 106 DeclMarker(Object, ArgumentsObject)
michael@0 107 DeclMarker(Object, ArrayBufferObject)
michael@0 108 DeclMarker(Object, ArrayBufferViewObject)
michael@0 109 DeclMarker(Object, SharedArrayBufferObject)
michael@0 110 DeclMarker(Object, DebugScopeObject)
michael@0 111 DeclMarker(Object, GlobalObject)
michael@0 112 DeclMarker(Object, JSObject)
michael@0 113 DeclMarker(Object, JSFunction)
michael@0 114 DeclMarker(Object, ScopeObject)
michael@0 115 DeclMarker(Script, JSScript)
michael@0 116 DeclMarker(LazyScript, LazyScript)
michael@0 117 DeclMarker(Shape, Shape)
michael@0 118 DeclMarker(String, JSAtom)
michael@0 119 DeclMarker(String, JSString)
michael@0 120 DeclMarker(String, JSFlatString)
michael@0 121 DeclMarker(String, JSLinearString)
michael@0 122 DeclMarker(String, PropertyName)
michael@0 123 DeclMarker(TypeObject, types::TypeObject)
michael@0 124
michael@0 125 #undef DeclMarker
michael@0 126
michael@0 127 void
michael@0 128 MarkPermanentAtom(JSTracer *trc, JSAtom *atom, const char *name);
michael@0 129
michael@0 130 /* Return true if the pointer is nullptr, or if it is a tagged pointer to
michael@0 131 * nullptr.
michael@0 132 */
michael@0 133 MOZ_ALWAYS_INLINE bool
michael@0 134 IsNullTaggedPointer(void *p)
michael@0 135 {
michael@0 136 return uintptr_t(p) < 32;
michael@0 137 }
michael@0 138
michael@0 139 /*** Externally Typed Marking ***/
michael@0 140
michael@0 141 /*
michael@0 142 * Note: this must only be called by the GC and only when we are tracing through
michael@0 143 * MarkRoots. It is explicitly for ConservativeStackMarking and should go away
michael@0 144 * after we transition to exact rooting.
michael@0 145 */
michael@0 146 void
michael@0 147 MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind);
michael@0 148
michael@0 149 void
michael@0 150 MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name);
michael@0 151
michael@0 152 void
michael@0 153 MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name);
michael@0 154
michael@0 155 /*** ID Marking ***/
michael@0 156
michael@0 157 void
michael@0 158 MarkId(JSTracer *trc, BarrieredId *id, const char *name);
michael@0 159
michael@0 160 void
michael@0 161 MarkIdRoot(JSTracer *trc, jsid *id, const char *name);
michael@0 162
michael@0 163 void
michael@0 164 MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name);
michael@0 165
michael@0 166 void
michael@0 167 MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name);
michael@0 168
michael@0 169 void
michael@0 170 MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
michael@0 171
michael@0 172 /*** Value Marking ***/
michael@0 173
michael@0 174 void
michael@0 175 MarkValue(JSTracer *trc, BarrieredValue *v, const char *name);
michael@0 176
michael@0 177 void
michael@0 178 MarkValueRange(JSTracer *trc, size_t len, BarrieredValue *vec, const char *name);
michael@0 179
michael@0 180 inline void
michael@0 181 MarkValueRange(JSTracer *trc, HeapValue *begin, HeapValue *end, const char *name)
michael@0 182 {
michael@0 183 return MarkValueRange(trc, end - begin, begin, name);
michael@0 184 }
michael@0 185
michael@0 186 void
michael@0 187 MarkValueRoot(JSTracer *trc, Value *v, const char *name);
michael@0 188
michael@0 189 void
michael@0 190 MarkThingOrValueUnbarriered(JSTracer *trc, uintptr_t *word, const char *name);
michael@0 191
michael@0 192 void
michael@0 193 MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name);
michael@0 194
michael@0 195 inline void
michael@0 196 MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
michael@0 197 {
michael@0 198 MarkValueRootRange(trc, end - begin, begin, name);
michael@0 199 }
michael@0 200
michael@0 201 void
michael@0 202 MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name);
michael@0 203
michael@0 204 bool
michael@0 205 IsValueMarked(Value *v);
michael@0 206
michael@0 207 bool
michael@0 208 IsValueAboutToBeFinalized(Value *v);
michael@0 209
michael@0 210 /*** Slot Marking ***/
michael@0 211
michael@0 212 bool
michael@0 213 IsSlotMarked(HeapSlot *s);
michael@0 214
michael@0 215 void
michael@0 216 MarkSlot(JSTracer *trc, HeapSlot *s, const char *name);
michael@0 217
michael@0 218 void
michael@0 219 MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name);
michael@0 220
michael@0 221 void
michael@0 222 MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots);
michael@0 223
michael@0 224 void
michael@0 225 MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject *src, JSObject **dst_obj,
michael@0 226 const char *name);
michael@0 227
michael@0 228 void
michael@0 229 MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSObject *src, JSScript **dst_script,
michael@0 230 const char *name);
michael@0 231
michael@0 232 /*
michael@0 233 * Mark a value that may be in a different compartment from the compartment
michael@0 234 * being GC'd. (Although it won't be marked if it's in the wrong compartment.)
michael@0 235 */
michael@0 236 void
michael@0 237 MarkCrossCompartmentSlot(JSTracer *trc, JSObject *src, HeapSlot *dst_slot, const char *name);
michael@0 238
michael@0 239
michael@0 240 /*** Special Cases ***/
michael@0 241
michael@0 242 /*
michael@0 243 * The unioned HeapPtr stored in script->globalObj needs special treatment to
michael@0 244 * typecheck correctly.
michael@0 245 */
michael@0 246 void
michael@0 247 MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name);
michael@0 248
michael@0 249 /*
michael@0 250 * MarkChildren<JSObject> is exposed solely for preWriteBarrier on
michael@0 251 * JSObject::TradeGuts. It should not be considered external interface.
michael@0 252 */
michael@0 253 void
michael@0 254 MarkChildren(JSTracer *trc, JSObject *obj);
michael@0 255
michael@0 256 /*
michael@0 257 * Trace through the shape and any shapes it contains to mark
michael@0 258 * non-shape children. This is exposed to the JS API as
michael@0 259 * JS_TraceShapeCycleCollectorChildren.
michael@0 260 */
michael@0 261 void
michael@0 262 MarkCycleCollectorChildren(JSTracer *trc, Shape *shape);
michael@0 263
michael@0 264 void
michael@0 265 PushArena(GCMarker *gcmarker, ArenaHeader *aheader);
michael@0 266
michael@0 267 /*** Generic ***/
michael@0 268
michael@0 269 /*
michael@0 270 * The Mark() functions interface should only be used by code that must be
michael@0 271 * templated. Other uses should use the more specific, type-named functions.
michael@0 272 */
michael@0 273
michael@0 274 inline void
michael@0 275 Mark(JSTracer *trc, BarrieredValue *v, const char *name)
michael@0 276 {
michael@0 277 MarkValue(trc, v, name);
michael@0 278 }
michael@0 279
michael@0 280 inline void
michael@0 281 Mark(JSTracer *trc, BarrieredPtrObject *o, const char *name)
michael@0 282 {
michael@0 283 MarkObject(trc, o, name);
michael@0 284 }
michael@0 285
michael@0 286 inline void
michael@0 287 Mark(JSTracer *trc, BarrieredPtrScript *o, const char *name)
michael@0 288 {
michael@0 289 MarkScript(trc, o, name);
michael@0 290 }
michael@0 291
michael@0 292 inline void
michael@0 293 Mark(JSTracer *trc, HeapPtr<jit::JitCode> *code, const char *name)
michael@0 294 {
michael@0 295 MarkJitCode(trc, code, name);
michael@0 296 }
michael@0 297
michael@0 298 /* For use by WeakMap's HashKeyRef instantiation. */
michael@0 299 inline void
michael@0 300 Mark(JSTracer *trc, JSObject **objp, const char *name)
michael@0 301 {
michael@0 302 MarkObjectUnbarriered(trc, objp, name);
michael@0 303 }
michael@0 304
michael@0 305 /* For use by Debugger::WeakMap's proxiedScopes HashKeyRef instantiation. */
michael@0 306 inline void
michael@0 307 Mark(JSTracer *trc, ScopeObject **obj, const char *name)
michael@0 308 {
michael@0 309 MarkObjectUnbarriered(trc, obj, name);
michael@0 310 }
michael@0 311
michael@0 312 bool
michael@0 313 IsCellMarked(Cell **thingp);
michael@0 314
michael@0 315 bool
michael@0 316 IsCellAboutToBeFinalized(Cell **thing);
michael@0 317
michael@0 318 inline bool
michael@0 319 IsMarked(BarrieredValue *v)
michael@0 320 {
michael@0 321 if (!v->isMarkable())
michael@0 322 return true;
michael@0 323 return IsValueMarked(v->unsafeGet());
michael@0 324 }
michael@0 325
michael@0 326 inline bool
michael@0 327 IsMarked(BarrieredPtrObject *objp)
michael@0 328 {
michael@0 329 return IsObjectMarked(objp);
michael@0 330 }
michael@0 331
michael@0 332 inline bool
michael@0 333 IsMarked(BarrieredPtrScript *scriptp)
michael@0 334 {
michael@0 335 return IsScriptMarked(scriptp);
michael@0 336 }
michael@0 337
michael@0 338 inline bool
michael@0 339 IsAboutToBeFinalized(BarrieredValue *v)
michael@0 340 {
michael@0 341 if (!v->isMarkable())
michael@0 342 return false;
michael@0 343 return IsValueAboutToBeFinalized(v->unsafeGet());
michael@0 344 }
michael@0 345
michael@0 346 inline bool
michael@0 347 IsAboutToBeFinalized(BarrieredPtrObject *objp)
michael@0 348 {
michael@0 349 return IsObjectAboutToBeFinalized(objp);
michael@0 350 }
michael@0 351
michael@0 352 inline bool
michael@0 353 IsAboutToBeFinalized(BarrieredPtrScript *scriptp)
michael@0 354 {
michael@0 355 return IsScriptAboutToBeFinalized(scriptp);
michael@0 356 }
michael@0 357
michael@0 358 #ifdef JS_ION
michael@0 359 /* Nonsense to get WeakCache to work with new Marking semantics. */
michael@0 360
michael@0 361 inline bool
michael@0 362 IsAboutToBeFinalized(const js::jit::VMFunction **vmfunc)
michael@0 363 {
michael@0 364 /*
michael@0 365 * Preserves entries in the WeakCache<VMFunction, JitCode>
michael@0 366 * iff the JitCode has been marked.
michael@0 367 */
michael@0 368 return true;
michael@0 369 }
michael@0 370
michael@0 371 inline bool
michael@0 372 IsAboutToBeFinalized(ReadBarriered<js::jit::JitCode> code)
michael@0 373 {
michael@0 374 return IsJitCodeAboutToBeFinalized(code.unsafeGet());
michael@0 375 }
michael@0 376 #endif
michael@0 377
michael@0 378 inline Cell *
michael@0 379 ToMarkable(const Value &v)
michael@0 380 {
michael@0 381 if (v.isMarkable())
michael@0 382 return (Cell *)v.toGCThing();
michael@0 383 return nullptr;
michael@0 384 }
michael@0 385
michael@0 386 inline Cell *
michael@0 387 ToMarkable(Cell *cell)
michael@0 388 {
michael@0 389 return cell;
michael@0 390 }
michael@0 391
michael@0 392 inline JSGCTraceKind
michael@0 393 TraceKind(const Value &v)
michael@0 394 {
michael@0 395 JS_ASSERT(v.isMarkable());
michael@0 396 if (v.isObject())
michael@0 397 return JSTRACE_OBJECT;
michael@0 398 return JSTRACE_STRING;
michael@0 399 }
michael@0 400
michael@0 401 inline JSGCTraceKind
michael@0 402 TraceKind(JSObject *obj)
michael@0 403 {
michael@0 404 return JSTRACE_OBJECT;
michael@0 405 }
michael@0 406
michael@0 407 inline JSGCTraceKind
michael@0 408 TraceKind(JSScript *script)
michael@0 409 {
michael@0 410 return JSTRACE_SCRIPT;
michael@0 411 }
michael@0 412
michael@0 413 inline JSGCTraceKind
michael@0 414 TraceKind(LazyScript *lazy)
michael@0 415 {
michael@0 416 return JSTRACE_LAZY_SCRIPT;
michael@0 417 }
michael@0 418
michael@0 419 } /* namespace gc */
michael@0 420
michael@0 421 void
michael@0 422 TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind);
michael@0 423
michael@0 424 } /* namespace js */
michael@0 425
michael@0 426 #endif /* gc_Marking_h */

mercurial