Tue, 06 Jan 2015 21:39:09 +0100
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.
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_RootingAPI_h
8 #define js_RootingAPI_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/GuardObjects.h"
12 #include "mozilla/LinkedList.h"
13 #include "mozilla/NullPtr.h"
14 #include "mozilla/TypeTraits.h"
16 #include "jspubtd.h"
18 #include "js/TypeDecls.h"
19 #include "js/Utility.h"
21 /*
22 * Moving GC Stack Rooting
23 *
24 * A moving GC may change the physical location of GC allocated things, even
25 * when they are rooted, updating all pointers to the thing to refer to its new
26 * location. The GC must therefore know about all live pointers to a thing,
27 * not just one of them, in order to behave correctly.
28 *
29 * The |Rooted| and |Handle| classes below are used to root stack locations
30 * whose value may be held live across a call that can trigger GC. For a
31 * code fragment such as:
32 *
33 * JSObject *obj = NewObject(cx);
34 * DoSomething(cx);
35 * ... = obj->lastProperty();
36 *
37 * If |DoSomething()| can trigger a GC, the stack location of |obj| must be
38 * rooted to ensure that the GC does not move the JSObject referred to by
39 * |obj| without updating |obj|'s location itself. This rooting must happen
40 * regardless of whether there are other roots which ensure that the object
41 * itself will not be collected.
42 *
43 * If |DoSomething()| cannot trigger a GC, and the same holds for all other
44 * calls made between |obj|'s definitions and its last uses, then no rooting
45 * is required.
46 *
47 * SpiderMonkey can trigger a GC at almost any time and in ways that are not
48 * always clear. For example, the following innocuous-looking actions can
49 * cause a GC: allocation of any new GC thing; JSObject::hasProperty;
50 * JS_ReportError and friends; and ToNumber, among many others. The following
51 * dangerous-looking actions cannot trigger a GC: js_malloc, cx->malloc_,
52 * rt->malloc_, and friends and JS_ReportOutOfMemory.
53 *
54 * The following family of three classes will exactly root a stack location.
55 * Incorrect usage of these classes will result in a compile error in almost
56 * all cases. Therefore, it is very hard to be incorrectly rooted if you use
57 * these classes exclusively. These classes are all templated on the type T of
58 * the value being rooted.
59 *
60 * - Rooted<T> declares a variable of type T, whose value is always rooted.
61 * Rooted<T> may be automatically coerced to a Handle<T>, below. Rooted<T>
62 * should be used whenever a local variable's value may be held live across a
63 * call which can trigger a GC.
64 *
65 * - Handle<T> is a const reference to a Rooted<T>. Functions which take GC
66 * things or values as arguments and need to root those arguments should
67 * generally use handles for those arguments and avoid any explicit rooting.
68 * This has two benefits. First, when several such functions call each other
69 * then redundant rooting of multiple copies of the GC thing can be avoided.
70 * Second, if the caller does not pass a rooted value a compile error will be
71 * generated, which is quicker and easier to fix than when relying on a
72 * separate rooting analysis.
73 *
74 * - MutableHandle<T> is a non-const reference to Rooted<T>. It is used in the
75 * same way as Handle<T> and includes a |set(const T &v)| method to allow
76 * updating the value of the referenced Rooted<T>. A MutableHandle<T> can be
77 * created from a Rooted<T> by using |Rooted<T>::operator&()|.
78 *
79 * In some cases the small performance overhead of exact rooting (measured to
80 * be a few nanoseconds on desktop) is too much. In these cases, try the
81 * following:
82 *
83 * - Move all Rooted<T> above inner loops: this allows you to re-use the root
84 * on each iteration of the loop.
85 *
86 * - Pass Handle<T> through your hot call stack to avoid re-rooting costs at
87 * every invocation.
88 *
89 * The following diagram explains the list of supported, implicit type
90 * conversions between classes of this family:
91 *
92 * Rooted<T> ----> Handle<T>
93 * | ^
94 * | |
95 * | |
96 * +---> MutableHandle<T>
97 * (via &)
98 *
99 * All of these types have an implicit conversion to raw pointers.
100 */
102 namespace js {
104 class ScriptSourceObject;
106 template <typename T>
107 struct GCMethods {};
109 template <typename T>
110 class RootedBase {};
112 template <typename T>
113 class HandleBase {};
115 template <typename T>
116 class MutableHandleBase {};
118 template <typename T>
119 class HeapBase {};
121 /*
122 * js::NullPtr acts like a nullptr pointer in contexts that require a Handle.
123 *
124 * Handle provides an implicit constructor for js::NullPtr so that, given:
125 * foo(Handle<JSObject*> h);
126 * callers can simply write:
127 * foo(js::NullPtr());
128 * which avoids creating a Rooted<JSObject*> just to pass nullptr.
129 *
130 * This is the SpiderMonkey internal variant. js::NullPtr should be used in
131 * preference to JS::NullPtr to avoid the GOT access required for JS_PUBLIC_API
132 * symbols.
133 */
134 struct NullPtr
135 {
136 static void * const constNullValue;
137 };
139 namespace gc {
140 struct Cell;
141 template<typename T>
142 struct PersistentRootedMarker;
143 } /* namespace gc */
145 } /* namespace js */
147 namespace JS {
149 template <typename T> class Rooted;
150 template <typename T> class PersistentRooted;
152 /* This is exposing internal state of the GC for inlining purposes. */
153 JS_FRIEND_API(bool) isGCEnabled();
155 /*
156 * JS::NullPtr acts like a nullptr pointer in contexts that require a Handle.
157 *
158 * Handle provides an implicit constructor for JS::NullPtr so that, given:
159 * foo(Handle<JSObject*> h);
160 * callers can simply write:
161 * foo(JS::NullPtr());
162 * which avoids creating a Rooted<JSObject*> just to pass nullptr.
163 */
164 struct JS_PUBLIC_API(NullPtr)
165 {
166 static void * const constNullValue;
167 };
169 /*
170 * The Heap<T> class is a heap-stored reference to a JS GC thing. All members of
171 * heap classes that refer to GC things should use Heap<T> (or possibly
172 * TenuredHeap<T>, described below).
173 *
174 * Heap<T> is an abstraction that hides some of the complexity required to
175 * maintain GC invariants for the contained reference. It uses operator
176 * overloading to provide a normal pointer interface, but notifies the GC every
177 * time the value it contains is updated. This is necessary for generational GC,
178 * which keeps track of all pointers into the nursery.
179 *
180 * Heap<T> instances must be traced when their containing object is traced to
181 * keep the pointed-to GC thing alive.
182 *
183 * Heap<T> objects should only be used on the heap. GC references stored on the
184 * C/C++ stack must use Rooted/Handle/MutableHandle instead.
185 *
186 * Type T must be one of: JS::Value, jsid, JSObject*, JSString*, JSScript*
187 */
188 template <typename T>
189 class Heap : public js::HeapBase<T>
190 {
191 public:
192 Heap() {
193 static_assert(sizeof(T) == sizeof(Heap<T>),
194 "Heap<T> must be binary compatible with T.");
195 init(js::GCMethods<T>::initial());
196 }
197 explicit Heap(T p) { init(p); }
199 /*
200 * For Heap, move semantics are equivalent to copy semantics. In C++, a
201 * copy constructor taking const-ref is the way to get a single function
202 * that will be used for both lvalue and rvalue copies, so we can simply
203 * omit the rvalue variant.
204 */
205 explicit Heap(const Heap<T> &p) { init(p.ptr); }
207 ~Heap() {
208 if (js::GCMethods<T>::needsPostBarrier(ptr))
209 relocate();
210 }
212 bool operator==(const Heap<T> &other) { return ptr == other.ptr; }
213 bool operator!=(const Heap<T> &other) { return ptr != other.ptr; }
215 bool operator==(const T &other) const { return ptr == other; }
216 bool operator!=(const T &other) const { return ptr != other; }
218 operator T() const { return ptr; }
219 T operator->() const { return ptr; }
220 const T *address() const { return &ptr; }
221 const T &get() const { return ptr; }
223 T *unsafeGet() { return &ptr; }
225 Heap<T> &operator=(T p) {
226 set(p);
227 return *this;
228 }
230 Heap<T> &operator=(const Heap<T>& other) {
231 set(other.get());
232 return *this;
233 }
235 void set(T newPtr) {
236 MOZ_ASSERT(!js::GCMethods<T>::poisoned(newPtr));
237 if (js::GCMethods<T>::needsPostBarrier(newPtr)) {
238 ptr = newPtr;
239 post();
240 } else if (js::GCMethods<T>::needsPostBarrier(ptr)) {
241 relocate(); /* Called before overwriting ptr. */
242 ptr = newPtr;
243 } else {
244 ptr = newPtr;
245 }
246 }
248 /*
249 * Set the pointer to a value which will cause a crash if it is
250 * dereferenced.
251 */
252 void setToCrashOnTouch() {
253 ptr = reinterpret_cast<T>(crashOnTouchPointer);
254 }
256 bool isSetToCrashOnTouch() {
257 return ptr == crashOnTouchPointer;
258 }
260 private:
261 void init(T newPtr) {
262 MOZ_ASSERT(!js::GCMethods<T>::poisoned(newPtr));
263 ptr = newPtr;
264 if (js::GCMethods<T>::needsPostBarrier(ptr))
265 post();
266 }
268 void post() {
269 #ifdef JSGC_GENERATIONAL
270 MOZ_ASSERT(js::GCMethods<T>::needsPostBarrier(ptr));
271 js::GCMethods<T>::postBarrier(&ptr);
272 #endif
273 }
275 void relocate() {
276 #ifdef JSGC_GENERATIONAL
277 js::GCMethods<T>::relocate(&ptr);
278 #endif
279 }
281 enum {
282 crashOnTouchPointer = 1
283 };
285 T ptr;
286 };
288 #ifdef JS_DEBUG
289 /*
290 * For generational GC, assert that an object is in the tenured generation as
291 * opposed to being in the nursery.
292 */
293 extern JS_FRIEND_API(void)
294 AssertGCThingMustBeTenured(JSObject* obj);
295 #else
296 inline void
297 AssertGCThingMustBeTenured(JSObject *obj) {}
298 #endif
300 /*
301 * The TenuredHeap<T> class is similar to the Heap<T> class above in that it
302 * encapsulates the GC concerns of an on-heap reference to a JS object. However,
303 * it has two important differences:
304 *
305 * 1) Pointers which are statically known to only reference "tenured" objects
306 * can avoid the extra overhead of SpiderMonkey's write barriers.
307 *
308 * 2) Objects in the "tenured" heap have stronger alignment restrictions than
309 * those in the "nursery", so it is possible to store flags in the lower
310 * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged
311 * pointer with a nice API for accessing the flag bits and adds various
312 * assertions to ensure that it is not mis-used.
313 *
314 * GC things are said to be "tenured" when they are located in the long-lived
315 * heap: e.g. they have gained tenure as an object by surviving past at least
316 * one GC. For performance, SpiderMonkey allocates some things which are known
317 * to normally be long lived directly into the tenured generation; for example,
318 * global objects. Additionally, SpiderMonkey does not visit individual objects
319 * when deleting non-tenured objects, so object with finalizers are also always
320 * tenured; for instance, this includes most DOM objects.
321 *
322 * The considerations to keep in mind when using a TenuredHeap<T> vs a normal
323 * Heap<T> are:
324 *
325 * - It is invalid for a TenuredHeap<T> to refer to a non-tenured thing.
326 * - It is however valid for a Heap<T> to refer to a tenured thing.
327 * - It is not possible to store flag bits in a Heap<T>.
328 */
329 template <typename T>
330 class TenuredHeap : public js::HeapBase<T>
331 {
332 public:
333 TenuredHeap() : bits(0) {
334 static_assert(sizeof(T) == sizeof(TenuredHeap<T>),
335 "TenuredHeap<T> must be binary compatible with T.");
336 }
337 explicit TenuredHeap(T p) : bits(0) { setPtr(p); }
338 explicit TenuredHeap(const TenuredHeap<T> &p) : bits(0) { setPtr(p.getPtr()); }
340 bool operator==(const TenuredHeap<T> &other) { return bits == other.bits; }
341 bool operator!=(const TenuredHeap<T> &other) { return bits != other.bits; }
343 void setPtr(T newPtr) {
344 MOZ_ASSERT((reinterpret_cast<uintptr_t>(newPtr) & flagsMask) == 0);
345 MOZ_ASSERT(!js::GCMethods<T>::poisoned(newPtr));
346 if (newPtr)
347 AssertGCThingMustBeTenured(newPtr);
348 bits = (bits & flagsMask) | reinterpret_cast<uintptr_t>(newPtr);
349 }
351 void setFlags(uintptr_t flagsToSet) {
352 MOZ_ASSERT((flagsToSet & ~flagsMask) == 0);
353 bits |= flagsToSet;
354 }
356 void unsetFlags(uintptr_t flagsToUnset) {
357 MOZ_ASSERT((flagsToUnset & ~flagsMask) == 0);
358 bits &= ~flagsToUnset;
359 }
361 bool hasFlag(uintptr_t flag) const {
362 MOZ_ASSERT((flag & ~flagsMask) == 0);
363 return (bits & flag) != 0;
364 }
366 T getPtr() const { return reinterpret_cast<T>(bits & ~flagsMask); }
367 uintptr_t getFlags() const { return bits & flagsMask; }
369 operator T() const { return getPtr(); }
370 T operator->() const { return getPtr(); }
372 TenuredHeap<T> &operator=(T p) {
373 setPtr(p);
374 return *this;
375 }
377 TenuredHeap<T> &operator=(const TenuredHeap<T>& other) {
378 bits = other.bits;
379 return *this;
380 }
382 private:
383 enum {
384 maskBits = 3,
385 flagsMask = (1 << maskBits) - 1,
386 };
388 uintptr_t bits;
389 };
391 /*
392 * Reference to a T that has been rooted elsewhere. This is most useful
393 * as a parameter type, which guarantees that the T lvalue is properly
394 * rooted. See "Move GC Stack Rooting" above.
395 *
396 * If you want to add additional methods to Handle for a specific
397 * specialization, define a HandleBase<T> specialization containing them.
398 */
399 template <typename T>
400 class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
401 {
402 friend class JS::MutableHandle<T>;
404 public:
405 /* Creates a handle from a handle of a type convertible to T. */
406 template <typename S>
407 Handle(Handle<S> handle,
408 typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
409 {
410 static_assert(sizeof(Handle<T>) == sizeof(T *),
411 "Handle must be binary compatible with T*.");
412 ptr = reinterpret_cast<const T *>(handle.address());
413 }
415 /* Create a handle for a nullptr pointer. */
416 Handle(js::NullPtr) {
417 static_assert(mozilla::IsPointer<T>::value,
418 "js::NullPtr overload not valid for non-pointer types");
419 ptr = reinterpret_cast<const T *>(&js::NullPtr::constNullValue);
420 }
422 /* Create a handle for a nullptr pointer. */
423 Handle(JS::NullPtr) {
424 static_assert(mozilla::IsPointer<T>::value,
425 "JS::NullPtr overload not valid for non-pointer types");
426 ptr = reinterpret_cast<const T *>(&JS::NullPtr::constNullValue);
427 }
429 Handle(MutableHandle<T> handle) {
430 ptr = handle.address();
431 }
433 /*
434 * Take care when calling this method!
435 *
436 * This creates a Handle from the raw location of a T.
437 *
438 * It should be called only if the following conditions hold:
439 *
440 * 1) the location of the T is guaranteed to be marked (for some reason
441 * other than being a Rooted), e.g., if it is guaranteed to be reachable
442 * from an implicit root.
443 *
444 * 2) the contents of the location are immutable, or at least cannot change
445 * for the lifetime of the handle, as its users may not expect its value
446 * to change underneath them.
447 */
448 static MOZ_CONSTEXPR Handle fromMarkedLocation(const T *p) {
449 return Handle(p, DeliberatelyChoosingThisOverload,
450 ImUsingThisOnlyInFromFromMarkedLocation);
451 }
453 /*
454 * Construct a handle from an explicitly rooted location. This is the
455 * normal way to create a handle, and normally happens implicitly.
456 */
457 template <typename S>
458 inline
459 Handle(const Rooted<S> &root,
460 typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
462 template <typename S>
463 inline
464 Handle(const PersistentRooted<S> &root,
465 typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
467 /* Construct a read only handle from a mutable handle. */
468 template <typename S>
469 inline
470 Handle(MutableHandle<S> &root,
471 typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
473 const T *address() const { return ptr; }
474 const T& get() const { return *ptr; }
476 /*
477 * Return a reference so passing a Handle<T> to something that
478 * takes a |const T&| is not a GC hazard.
479 */
480 operator const T&() const { return get(); }
481 T operator->() const { return get(); }
483 bool operator!=(const T &other) const { return *ptr != other; }
484 bool operator==(const T &other) const { return *ptr == other; }
486 /* Change this handle to point to the same rooted location RHS does. */
487 void repoint(const Handle &rhs) { ptr = rhs.address(); }
489 private:
490 Handle() {}
492 enum Disambiguator { DeliberatelyChoosingThisOverload = 42 };
493 enum CallerIdentity { ImUsingThisOnlyInFromFromMarkedLocation = 17 };
494 MOZ_CONSTEXPR Handle(const T *p, Disambiguator, CallerIdentity) : ptr(p) {}
496 const T *ptr;
498 template <typename S> void operator=(S) MOZ_DELETE;
499 void operator=(Handle) MOZ_DELETE;
500 };
502 /*
503 * Similar to a handle, but the underlying storage can be changed. This is
504 * useful for outparams.
505 *
506 * If you want to add additional methods to MutableHandle for a specific
507 * specialization, define a MutableHandleBase<T> specialization containing
508 * them.
509 */
510 template <typename T>
511 class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
512 {
513 public:
514 inline MutableHandle(Rooted<T> *root);
515 inline MutableHandle(PersistentRooted<T> *root);
517 private:
518 // Disallow true nullptr and emulated nullptr (gcc 4.4/4.5, __null, appears
519 // as int/long [32/64-bit]) for overloading purposes.
520 template<typename N>
521 MutableHandle(N,
522 typename mozilla::EnableIf<mozilla::IsNullPointer<N>::value ||
523 mozilla::IsSame<N, int>::value ||
524 mozilla::IsSame<N, long>::value,
525 int>::Type dummy = 0)
526 MOZ_DELETE;
528 public:
529 void set(T v) {
530 MOZ_ASSERT(!js::GCMethods<T>::poisoned(v));
531 *ptr = v;
532 }
534 /*
535 * This may be called only if the location of the T is guaranteed
536 * to be marked (for some reason other than being a Rooted),
537 * e.g., if it is guaranteed to be reachable from an implicit root.
538 *
539 * Create a MutableHandle from a raw location of a T.
540 */
541 static MutableHandle fromMarkedLocation(T *p) {
542 MutableHandle h;
543 h.ptr = p;
544 return h;
545 }
547 T *address() const { return ptr; }
548 const T& get() const { return *ptr; }
550 /*
551 * Return a reference so passing a MutableHandle<T> to something that takes
552 * a |const T&| is not a GC hazard.
553 */
554 operator const T&() const { return get(); }
555 T operator->() const { return get(); }
557 private:
558 MutableHandle() {}
560 T *ptr;
562 template <typename S> void operator=(S v) MOZ_DELETE;
563 void operator=(MutableHandle other) MOZ_DELETE;
564 };
566 #ifdef JSGC_GENERATIONAL
567 JS_FRIEND_API(void) HeapCellPostBarrier(js::gc::Cell **cellp);
568 JS_FRIEND_API(void) HeapCellRelocate(js::gc::Cell **cellp);
569 #endif
571 } /* namespace JS */
573 namespace js {
575 /*
576 * InternalHandle is a handle to an internal pointer into a gcthing. Use
577 * InternalHandle when you have a pointer to a direct field of a gcthing, or
578 * when you need a parameter type for something that *may* be a pointer to a
579 * direct field of a gcthing.
580 */
581 template <typename T>
582 class InternalHandle {};
584 template <typename T>
585 class InternalHandle<T*>
586 {
587 void * const *holder;
588 size_t offset;
590 public:
591 /*
592 * Create an InternalHandle using a Handle to the gcthing containing the
593 * field in question, and a pointer to the field.
594 */
595 template<typename H>
596 InternalHandle(const JS::Handle<H> &handle, T *field)
597 : holder((void**)handle.address()), offset(uintptr_t(field) - uintptr_t(handle.get()))
598 {}
600 /*
601 * Create an InternalHandle to a field within a Rooted<>.
602 */
603 template<typename R>
604 InternalHandle(const JS::Rooted<R> &root, T *field)
605 : holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get()))
606 {}
608 InternalHandle(const InternalHandle<T*>& other)
609 : holder(other.holder), offset(other.offset) {}
611 T *get() const { return reinterpret_cast<T*>(uintptr_t(*holder) + offset); }
613 const T &operator*() const { return *get(); }
614 T *operator->() const { return get(); }
616 static InternalHandle<T*> fromMarkedLocation(T *fieldPtr) {
617 return InternalHandle(fieldPtr);
618 }
620 private:
621 /*
622 * Create an InternalHandle to something that is not a pointer to a
623 * gcthing, and so does not need to be rooted in the first place. Use these
624 * InternalHandles to pass pointers into functions that also need to accept
625 * regular InternalHandles to gcthing fields.
626 *
627 * Make this private to prevent accidental misuse; this is only for
628 * fromMarkedLocation().
629 */
630 InternalHandle(T *field)
631 : holder(reinterpret_cast<void * const *>(&js::NullPtr::constNullValue)),
632 offset(uintptr_t(field))
633 {}
635 void operator=(InternalHandle<T*> other) MOZ_DELETE;
636 };
638 /*
639 * By default, pointers should use the inheritance hierarchy to find their
640 * ThingRootKind. Some pointer types are explicitly set in jspubtd.h so that
641 * Rooted<T> may be used without the class definition being available.
642 */
643 template <typename T>
644 struct RootKind<T *>
645 {
646 static ThingRootKind rootKind() { return T::rootKind(); }
647 };
649 template <typename T>
650 struct GCMethods<T *>
651 {
652 static T *initial() { return nullptr; }
653 static ThingRootKind kind() { return RootKind<T *>::rootKind(); }
654 static bool poisoned(T *v) { return JS::IsPoisonedPtr(v); }
655 static bool needsPostBarrier(T *v) { return false; }
656 #ifdef JSGC_GENERATIONAL
657 static void postBarrier(T **vp) {}
658 static void relocate(T **vp) {}
659 #endif
660 };
662 template <>
663 struct GCMethods<JSObject *>
664 {
665 static JSObject *initial() { return nullptr; }
666 static ThingRootKind kind() { return RootKind<JSObject *>::rootKind(); }
667 static bool poisoned(JSObject *v) { return JS::IsPoisonedPtr(v); }
668 static bool needsPostBarrier(JSObject *v) { return v; }
669 #ifdef JSGC_GENERATIONAL
670 static void postBarrier(JSObject **vp) {
671 JS::HeapCellPostBarrier(reinterpret_cast<js::gc::Cell **>(vp));
672 }
673 static void relocate(JSObject **vp) {
674 JS::HeapCellRelocate(reinterpret_cast<js::gc::Cell **>(vp));
675 }
676 #endif
677 };
679 template <>
680 struct GCMethods<JSFunction *>
681 {
682 static JSFunction *initial() { return nullptr; }
683 static ThingRootKind kind() { return RootKind<JSObject *>::rootKind(); }
684 static bool poisoned(JSFunction *v) { return JS::IsPoisonedPtr(v); }
685 static bool needsPostBarrier(JSFunction *v) { return v; }
686 #ifdef JSGC_GENERATIONAL
687 static void postBarrier(JSFunction **vp) {
688 JS::HeapCellPostBarrier(reinterpret_cast<js::gc::Cell **>(vp));
689 }
690 static void relocate(JSFunction **vp) {
691 JS::HeapCellRelocate(reinterpret_cast<js::gc::Cell **>(vp));
692 }
693 #endif
694 };
696 #ifdef JS_DEBUG
697 /* This helper allows us to assert that Rooted<T> is scoped within a request. */
698 extern JS_PUBLIC_API(bool)
699 IsInRequest(JSContext *cx);
700 #endif
702 } /* namespace js */
704 namespace JS {
706 /*
707 * Local variable of type T whose value is always rooted. This is typically
708 * used for local variables, or for non-rooted values being passed to a
709 * function that requires a handle, e.g. Foo(Root<T>(cx, x)).
710 *
711 * If you want to add additional methods to Rooted for a specific
712 * specialization, define a RootedBase<T> specialization containing them.
713 */
714 template <typename T>
715 class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
716 {
717 /* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */
718 template <typename CX>
719 void init(CX *cx) {
720 #ifdef JSGC_TRACK_EXACT_ROOTS
721 js::ThingRootKind kind = js::GCMethods<T>::kind();
722 this->stack = &cx->thingGCRooters[kind];
723 this->prev = *stack;
724 *stack = reinterpret_cast<Rooted<void*>*>(this);
726 MOZ_ASSERT(!js::GCMethods<T>::poisoned(ptr));
727 #endif
728 }
730 public:
731 Rooted(JSContext *cx
732 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
733 : ptr(js::GCMethods<T>::initial())
734 {
735 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
736 #ifdef JS_DEBUG
737 MOZ_ASSERT(js::IsInRequest(cx));
738 #endif
739 init(js::ContextFriendFields::get(cx));
740 }
742 Rooted(JSContext *cx, T initial
743 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
744 : ptr(initial)
745 {
746 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
747 #ifdef JS_DEBUG
748 MOZ_ASSERT(js::IsInRequest(cx));
749 #endif
750 init(js::ContextFriendFields::get(cx));
751 }
753 Rooted(js::ContextFriendFields *cx
754 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
755 : ptr(js::GCMethods<T>::initial())
756 {
757 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
758 init(cx);
759 }
761 Rooted(js::ContextFriendFields *cx, T initial
762 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
763 : ptr(initial)
764 {
765 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
766 init(cx);
767 }
769 Rooted(js::PerThreadDataFriendFields *pt
770 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
771 : ptr(js::GCMethods<T>::initial())
772 {
773 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
774 init(pt);
775 }
777 Rooted(js::PerThreadDataFriendFields *pt, T initial
778 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
779 : ptr(initial)
780 {
781 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
782 init(pt);
783 }
785 Rooted(JSRuntime *rt
786 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
787 : ptr(js::GCMethods<T>::initial())
788 {
789 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
790 init(js::PerThreadDataFriendFields::getMainThread(rt));
791 }
793 Rooted(JSRuntime *rt, T initial
794 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
795 : ptr(initial)
796 {
797 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
798 init(js::PerThreadDataFriendFields::getMainThread(rt));
799 }
801 // Note that we need to let the compiler generate the default destructor in
802 // non-exact-rooting builds because of a bug in the instrumented PGO builds
803 // using MSVC, see bug 915735 for more details.
804 #ifdef JSGC_TRACK_EXACT_ROOTS
805 ~Rooted() {
806 MOZ_ASSERT(*stack == reinterpret_cast<Rooted<void*>*>(this));
807 *stack = prev;
808 }
809 #endif
811 #ifdef JSGC_TRACK_EXACT_ROOTS
812 Rooted<T> *previous() { return prev; }
813 #endif
815 /*
816 * Important: Return a reference here so passing a Rooted<T> to
817 * something that takes a |const T&| is not a GC hazard.
818 */
819 operator const T&() const { return ptr; }
820 T operator->() const { return ptr; }
821 T *address() { return &ptr; }
822 const T *address() const { return &ptr; }
823 T &get() { return ptr; }
824 const T &get() const { return ptr; }
826 T &operator=(T value) {
827 MOZ_ASSERT(!js::GCMethods<T>::poisoned(value));
828 ptr = value;
829 return ptr;
830 }
832 T &operator=(const Rooted &value) {
833 ptr = value;
834 return ptr;
835 }
837 void set(T value) {
838 MOZ_ASSERT(!js::GCMethods<T>::poisoned(value));
839 ptr = value;
840 }
842 bool operator!=(const T &other) const { return ptr != other; }
843 bool operator==(const T &other) const { return ptr == other; }
845 private:
846 #ifdef JSGC_TRACK_EXACT_ROOTS
847 Rooted<void*> **stack, *prev;
848 #endif
850 /*
851 * |ptr| must be the last field in Rooted because the analysis treats all
852 * Rooted as Rooted<void*> during the analysis. See bug 829372.
853 */
854 T ptr;
856 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
858 Rooted(const Rooted &) MOZ_DELETE;
859 };
861 } /* namespace JS */
863 namespace js {
865 /*
866 * Augment the generic Rooted<T> interface when T = JSObject* with
867 * class-querying and downcasting operations.
868 *
869 * Given a Rooted<JSObject*> obj, one can view
870 * Handle<StringObject*> h = obj.as<StringObject*>();
871 * as an optimization of
872 * Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
873 * Handle<StringObject*> h = rooted;
874 */
875 template <>
876 class RootedBase<JSObject*>
877 {
878 public:
879 template <class U>
880 JS::Handle<U*> as() const;
881 };
884 /*
885 * RootedGeneric<T> allows a class to instantiate its own Rooted type by
886 * including the following two methods:
887 *
888 * static inline js::ThingRootKind rootKind() { return js::THING_ROOT_CUSTOM; }
889 * void trace(JSTracer *trc);
890 *
891 * The trace() method must trace all of the class's fields.
892 *
893 * Implementation:
894 *
895 * RootedGeneric<T> works by placing a pointer to its 'rooter' field into the
896 * usual list of rooters when it is instantiated. When marking, it backs up
897 * from this pointer to find a vtable containing a type-appropriate trace()
898 * method.
899 */
900 template <typename GCType>
901 class JS_PUBLIC_API(RootedGeneric)
902 {
903 public:
904 JS::Rooted<GCType> rooter;
906 RootedGeneric(js::ContextFriendFields *cx)
907 : rooter(cx)
908 {
909 }
911 RootedGeneric(js::ContextFriendFields *cx, const GCType &initial)
912 : rooter(cx, initial)
913 {
914 }
916 virtual inline void trace(JSTracer *trc);
918 operator const GCType&() const { return rooter.get(); }
919 GCType operator->() const { return rooter.get(); }
920 };
922 template <typename GCType>
923 inline void RootedGeneric<GCType>::trace(JSTracer *trc)
924 {
925 rooter->trace(trc);
926 }
928 // We will instantiate RootedGeneric<void*> in RootMarking.cpp, and MSVC will
929 // notice that void*s have no trace() method defined on them and complain (even
930 // though it's never called.) MSVC's complaint is not unreasonable, so
931 // specialize for void*.
932 template <>
933 inline void RootedGeneric<void*>::trace(JSTracer *trc)
934 {
935 MOZ_ASSUME_UNREACHABLE("RootedGeneric<void*>::trace()");
936 }
938 /* Interface substitute for Rooted<T> which does not root the variable's memory. */
939 template <typename T>
940 class FakeRooted : public RootedBase<T>
941 {
942 public:
943 template <typename CX>
944 FakeRooted(CX *cx
945 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
946 : ptr(GCMethods<T>::initial())
947 {
948 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
949 }
951 template <typename CX>
952 FakeRooted(CX *cx, T initial
953 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
954 : ptr(initial)
955 {
956 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
957 }
959 operator T() const { return ptr; }
960 T operator->() const { return ptr; }
961 T *address() { return &ptr; }
962 const T *address() const { return &ptr; }
963 T &get() { return ptr; }
964 const T &get() const { return ptr; }
966 FakeRooted<T> &operator=(T value) {
967 MOZ_ASSERT(!GCMethods<T>::poisoned(value));
968 ptr = value;
969 return *this;
970 }
972 FakeRooted<T> &operator=(const FakeRooted<T> &other) {
973 MOZ_ASSERT(!GCMethods<T>::poisoned(other.ptr));
974 ptr = other.ptr;
975 return *this;
976 }
978 bool operator!=(const T &other) const { return ptr != other; }
979 bool operator==(const T &other) const { return ptr == other; }
981 private:
982 T ptr;
984 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
986 FakeRooted(const FakeRooted &) MOZ_DELETE;
987 };
989 /* Interface substitute for MutableHandle<T> which is not required to point to rooted memory. */
990 template <typename T>
991 class FakeMutableHandle : public js::MutableHandleBase<T>
992 {
993 public:
994 FakeMutableHandle(T *t) {
995 ptr = t;
996 }
998 FakeMutableHandle(FakeRooted<T> *root) {
999 ptr = root->address();
1000 }
1002 void set(T v) {
1003 MOZ_ASSERT(!js::GCMethods<T>::poisoned(v));
1004 *ptr = v;
1005 }
1007 T *address() const { return ptr; }
1008 T get() const { return *ptr; }
1010 operator T() const { return get(); }
1011 T operator->() const { return get(); }
1013 private:
1014 FakeMutableHandle() {}
1016 T *ptr;
1018 template <typename S>
1019 void operator=(S v) MOZ_DELETE;
1021 void operator=(const FakeMutableHandle<T>& other) MOZ_DELETE;
1022 };
1024 /*
1025 * Types for a variable that either should or shouldn't be rooted, depending on
1026 * the template parameter allowGC. Used for implementing functions that can
1027 * operate on either rooted or unrooted data.
1028 *
1029 * The toHandle() and toMutableHandle() functions are for calling functions
1030 * which require handle types and are only called in the CanGC case. These
1031 * allow the calling code to type check.
1032 */
1033 enum AllowGC {
1034 NoGC = 0,
1035 CanGC = 1
1036 };
1037 template <typename T, AllowGC allowGC>
1038 class MaybeRooted
1039 {
1040 };
1042 template <typename T> class MaybeRooted<T, CanGC>
1043 {
1044 public:
1045 typedef JS::Handle<T> HandleType;
1046 typedef JS::Rooted<T> RootType;
1047 typedef JS::MutableHandle<T> MutableHandleType;
1049 static inline JS::Handle<T> toHandle(HandleType v) {
1050 return v;
1051 }
1053 static inline JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
1054 return v;
1055 }
1056 };
1058 template <typename T> class MaybeRooted<T, NoGC>
1059 {
1060 public:
1061 typedef T HandleType;
1062 typedef FakeRooted<T> RootType;
1063 typedef FakeMutableHandle<T> MutableHandleType;
1065 static inline JS::Handle<T> toHandle(HandleType v) {
1066 MOZ_ASSUME_UNREACHABLE("Bad conversion");
1067 }
1069 static inline JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
1070 MOZ_ASSUME_UNREACHABLE("Bad conversion");
1071 }
1072 };
1074 } /* namespace js */
1076 namespace JS {
1078 template <typename T> template <typename S>
1079 inline
1080 Handle<T>::Handle(const Rooted<S> &root,
1081 typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
1082 {
1083 ptr = reinterpret_cast<const T *>(root.address());
1084 }
1086 template <typename T> template <typename S>
1087 inline
1088 Handle<T>::Handle(const PersistentRooted<S> &root,
1089 typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
1090 {
1091 ptr = reinterpret_cast<const T *>(root.address());
1092 }
1094 template <typename T> template <typename S>
1095 inline
1096 Handle<T>::Handle(MutableHandle<S> &root,
1097 typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
1098 {
1099 ptr = reinterpret_cast<const T *>(root.address());
1100 }
1102 template <typename T>
1103 inline
1104 MutableHandle<T>::MutableHandle(Rooted<T> *root)
1105 {
1106 static_assert(sizeof(MutableHandle<T>) == sizeof(T *),
1107 "MutableHandle must be binary compatible with T*.");
1108 ptr = root->address();
1109 }
1111 template <typename T>
1112 inline
1113 MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
1114 {
1115 static_assert(sizeof(MutableHandle<T>) == sizeof(T *),
1116 "MutableHandle must be binary compatible with T*.");
1117 ptr = root->address();
1118 }
1120 /*
1121 * A copyable, assignable global GC root type with arbitrary lifetime, an
1122 * infallible constructor, and automatic unrooting on destruction.
1123 *
1124 * These roots can be used in heap-allocated data structures, so they are not
1125 * associated with any particular JSContext or stack. They are registered with
1126 * the JSRuntime itself, without locking, so they require a full JSContext to be
1127 * constructed, not one of its more restricted superclasses.
1128 *
1129 * Note that you must not use an PersistentRooted in an object owned by a JS
1130 * object:
1131 *
1132 * Whenever one object whose lifetime is decided by the GC refers to another
1133 * such object, that edge must be traced only if the owning JS object is traced.
1134 * This applies not only to JS objects (which obviously are managed by the GC)
1135 * but also to C++ objects owned by JS objects.
1136 *
1137 * If you put a PersistentRooted in such a C++ object, that is almost certainly
1138 * a leak. When a GC begins, the referent of the PersistentRooted is treated as
1139 * live, unconditionally (because a PersistentRooted is a *root*), even if the
1140 * JS object that owns it is unreachable. If there is any path from that
1141 * referent back to the JS object, then the C++ object containing the
1142 * PersistentRooted will not be destructed, and the whole blob of objects will
1143 * not be freed, even if there are no references to them from the outside.
1144 *
1145 * In the context of Firefox, this is a severe restriction: almost everything in
1146 * Firefox is owned by some JS object or another, so using PersistentRooted in
1147 * such objects would introduce leaks. For these kinds of edges, Heap<T> or
1148 * TenuredHeap<T> would be better types. It's up to the implementor of the type
1149 * containing Heap<T> or TenuredHeap<T> members to make sure their referents get
1150 * marked when the object itself is marked.
1151 */
1152 template<typename T>
1153 class PersistentRooted : private mozilla::LinkedListElement<PersistentRooted<T> > {
1154 friend class mozilla::LinkedList<PersistentRooted>;
1155 friend class mozilla::LinkedListElement<PersistentRooted>;
1157 friend class js::gc::PersistentRootedMarker<T>;
1159 void registerWithRuntime(JSRuntime *rt) {
1160 JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(rt);
1161 srt->getPersistentRootedList<T>().insertBack(this);
1162 }
1164 public:
1165 PersistentRooted(JSContext *cx) : ptr(js::GCMethods<T>::initial())
1166 {
1167 registerWithRuntime(js::GetRuntime(cx));
1168 }
1170 PersistentRooted(JSContext *cx, T initial) : ptr(initial)
1171 {
1172 registerWithRuntime(js::GetRuntime(cx));
1173 }
1175 PersistentRooted(JSRuntime *rt) : ptr(js::GCMethods<T>::initial())
1176 {
1177 registerWithRuntime(rt);
1178 }
1180 PersistentRooted(JSRuntime *rt, T initial) : ptr(initial)
1181 {
1182 registerWithRuntime(rt);
1183 }
1185 PersistentRooted(PersistentRooted &rhs) : ptr(rhs.ptr)
1186 {
1187 /*
1188 * Copy construction takes advantage of the fact that the original
1189 * is already inserted, and simply adds itself to whatever list the
1190 * original was on - no JSRuntime pointer needed.
1191 */
1192 rhs.setNext(this);
1193 }
1195 /*
1196 * Important: Return a reference here so passing a Rooted<T> to
1197 * something that takes a |const T&| is not a GC hazard.
1198 */
1199 operator const T&() const { return ptr; }
1200 T operator->() const { return ptr; }
1201 T *address() { return &ptr; }
1202 const T *address() const { return &ptr; }
1203 T &get() { return ptr; }
1204 const T &get() const { return ptr; }
1206 T &operator=(T value) {
1207 MOZ_ASSERT(!js::GCMethods<T>::poisoned(value));
1208 ptr = value;
1209 return ptr;
1210 }
1212 T &operator=(const PersistentRooted &value) {
1213 ptr = value;
1214 return ptr;
1215 }
1217 void set(T value) {
1218 MOZ_ASSERT(!js::GCMethods<T>::poisoned(value));
1219 ptr = value;
1220 }
1222 bool operator!=(const T &other) const { return ptr != other; }
1223 bool operator==(const T &other) const { return ptr == other; }
1225 private:
1226 T ptr;
1227 };
1229 } /* namespace JS */
1231 namespace js {
1233 /* Base class for automatic read-only object rooting during compilation. */
1234 class CompilerRootNode
1235 {
1236 protected:
1237 CompilerRootNode(js::gc::Cell *ptr) : next(nullptr), ptr_(ptr) {}
1239 public:
1240 void **address() { return (void **)&ptr_; }
1242 public:
1243 CompilerRootNode *next;
1245 protected:
1246 js::gc::Cell *ptr_;
1247 };
1249 } /* namespace js */
1251 #endif /* js_RootingAPI_h */