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/. */
6 
7 #ifndef js_RootingAPI_h
8 #define js_RootingAPI_h
9 
10 #include "mozilla/Attributes.h"
11 #include "mozilla/DebugOnly.h"
12 #include "mozilla/GuardObjects.h"
13 #include "mozilla/LinkedList.h"
14 #include "mozilla/Move.h"
15 #include "mozilla/TypeTraits.h"
16 
17 #include <type_traits>
18 
19 #include "jspubtd.h"
20 
21 #include "js/GCAnnotations.h"
22 #include "js/GCPolicyAPI.h"
23 #include "js/HeapAPI.h"
24 #include "js/ProfilingStack.h"
25 #include "js/TypeDecls.h"
26 #include "js/UniquePtr.h"
27 #include "js/Utility.h"
28 
29 /*
30  * Moving GC Stack Rooting
31  *
32  * A moving GC may change the physical location of GC allocated things, even
33  * when they are rooted, updating all pointers to the thing to refer to its new
34  * location. The GC must therefore know about all live pointers to a thing,
35  * not just one of them, in order to behave correctly.
36  *
37  * The |Rooted| and |Handle| classes below are used to root stack locations
38  * whose value may be held live across a call that can trigger GC. For a
39  * code fragment such as:
40  *
41  * JSObject* obj = NewObject(cx);
42  * DoSomething(cx);
43  * ... = obj->lastProperty();
44  *
45  * If |DoSomething()| can trigger a GC, the stack location of |obj| must be
46  * rooted to ensure that the GC does not move the JSObject referred to by
47  * |obj| without updating |obj|'s location itself. This rooting must happen
48  * regardless of whether there are other roots which ensure that the object
49  * itself will not be collected.
50  *
51  * If |DoSomething()| cannot trigger a GC, and the same holds for all other
52  * calls made between |obj|'s definitions and its last uses, then no rooting
53  * is required.
54  *
55  * SpiderMonkey can trigger a GC at almost any time and in ways that are not
56  * always clear. For example, the following innocuous-looking actions can
57  * cause a GC: allocation of any new GC thing; JSObject::hasProperty;
58  * JS_ReportError and friends; and ToNumber, among many others. The following
59  * dangerous-looking actions cannot trigger a GC: js_malloc, cx->malloc_,
60  * rt->malloc_, and friends and JS_ReportOutOfMemory.
61  *
62  * The following family of three classes will exactly root a stack location.
63  * Incorrect usage of these classes will result in a compile error in almost
64  * all cases. Therefore, it is very hard to be incorrectly rooted if you use
65  * these classes exclusively. These classes are all templated on the type T of
66  * the value being rooted.
67  *
68  * - Rooted<T> declares a variable of type T, whose value is always rooted.
69  *   Rooted<T> may be automatically coerced to a Handle<T>, below. Rooted<T>
70  *   should be used whenever a local variable's value may be held live across a
71  *   call which can trigger a GC.
72  *
73  * - Handle<T> is a const reference to a Rooted<T>. Functions which take GC
74  *   things or values as arguments and need to root those arguments should
75  *   generally use handles for those arguments and avoid any explicit rooting.
76  *   This has two benefits. First, when several such functions call each other
77  *   then redundant rooting of multiple copies of the GC thing can be avoided.
78  *   Second, if the caller does not pass a rooted value a compile error will be
79  *   generated, which is quicker and easier to fix than when relying on a
80  *   separate rooting analysis.
81  *
82  * - MutableHandle<T> is a non-const reference to Rooted<T>. It is used in the
83  *   same way as Handle<T> and includes a |set(const T& v)| method to allow
84  *   updating the value of the referenced Rooted<T>. A MutableHandle<T> can be
85  *   created with an implicit cast from a Rooted<T>*.
86  *
87  * In some cases the small performance overhead of exact rooting (measured to
88  * be a few nanoseconds on desktop) is too much. In these cases, try the
89  * following:
90  *
91  * - Move all Rooted<T> above inner loops: this allows you to re-use the root
92  *   on each iteration of the loop.
93  *
94  * - Pass Handle<T> through your hot call stack to avoid re-rooting costs at
95  *   every invocation.
96  *
97  * The following diagram explains the list of supported, implicit type
98  * conversions between classes of this family:
99  *
100  *  Rooted<T> ----> Handle<T>
101  *     |               ^
102  *     |               |
103  *     |               |
104  *     +---> MutableHandle<T>
105  *     (via &)
106  *
107  * All of these types have an implicit conversion to raw pointers.
108  */
109 
110 namespace js {
111 
112 template <typename T>
113 struct BarrierMethods {};
114 
115 template <typename Element, typename Wrapper>
116 class WrappedPtrOperations {};
117 
118 template <typename Element, typename Wrapper>
119 class MutableWrappedPtrOperations
120     : public WrappedPtrOperations<Element, Wrapper> {};
121 
122 template <typename T, typename Wrapper>
123 class RootedBase : public MutableWrappedPtrOperations<T, Wrapper> {};
124 
125 template <typename T, typename Wrapper>
126 class HandleBase : public WrappedPtrOperations<T, Wrapper> {};
127 
128 template <typename T, typename Wrapper>
129 class MutableHandleBase : public MutableWrappedPtrOperations<T, Wrapper> {};
130 
131 template <typename T, typename Wrapper>
132 class HeapBase : public MutableWrappedPtrOperations<T, Wrapper> {};
133 
134 // Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many
135 // macros into scope
136 template <typename T>
137 struct IsHeapConstructibleType {
138   static constexpr bool value = false;
139 };
140 #define DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE(T) \
141   template <>                                 \
142   struct IsHeapConstructibleType<T> {         \
143     static constexpr bool value = true;       \
144   };
145 FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)146 FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
147 #undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE
148 
149 template <typename T, typename Wrapper>
150 class PersistentRootedBase : public MutableWrappedPtrOperations<T, Wrapper> {};
151 
152 template <typename T>
153 class FakeRooted;
154 
155 template <typename T>
156 class FakeMutableHandle;
157 
158 namespace gc {
159 struct Cell;
160 template <typename T>
161 struct PersistentRootedMarker;
162 } /* namespace gc */
163 
164 // Important: Return a reference so passing a Rooted<T>, etc. to
165 // something that takes a |const T&| is not a GC hazard.
166 #define DECLARE_POINTER_CONSTREF_OPS(T)       \
167   operator const T&() const { return get(); } \
168   const T& operator->() const { return get(); }
169 
170 // Assignment operators on a base class are hidden by the implicitly defined
171 // operator= on the derived class. Thus, define the operator= directly on the
172 // class as we would need to manually pass it through anyway.
173 #define DECLARE_POINTER_ASSIGN_OPS(Wrapper, T)     \
174   Wrapper<T>& operator=(const T& p) {              \
175     set(p);                                        \
176     return *this;                                  \
177   }                                                \
178   Wrapper<T>& operator=(T&& p) {                   \
179     set(mozilla::Move(p));                         \
180     return *this;                                  \
181   }                                                \
182   Wrapper<T>& operator=(const Wrapper<T>& other) { \
183     set(other.get());                              \
184     return *this;                                  \
185   }
186 
187 #define DELETE_ASSIGNMENT_OPS(Wrapper, T) \
188   template <typename S>                   \
189   Wrapper<T>& operator=(S) = delete;      \
190   Wrapper<T>& operator=(const Wrapper<T>&) = delete;
191 
192 #define DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr) \
193   const T* address() const { return &(ptr); }    \
194   const T& get() const { return (ptr); }
195 
196 #define DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr) \
197   T* address() { return &(ptr); }                        \
198   T& get() { return (ptr); }
199 
200 } /* namespace js */
201 
202 namespace JS {
203 
204 template <typename T>
205 class Rooted;
206 template <typename T>
207 class PersistentRooted;
208 
209 /* This is exposing internal state of the GC for inlining purposes. */
210 JS_FRIEND_API bool isGCEnabled();
211 
212 JS_FRIEND_API void HeapObjectPostBarrier(JSObject** objp, JSObject* prev,
213                                          JSObject* next);
214 JS_FRIEND_API void HeapStringPostBarrier(JSString** objp, JSString* prev,
215                                          JSString* next);
216 
217 #ifdef JS_DEBUG
218 /**
219  * For generational GC, assert that an object is in the tenured generation as
220  * opposed to being in the nursery.
221  */
222 extern JS_FRIEND_API void AssertGCThingMustBeTenured(JSObject* obj);
223 extern JS_FRIEND_API void AssertGCThingIsNotNurseryAllocable(
224     js::gc::Cell* cell);
225 #else
AssertGCThingMustBeTenured(JSObject * obj)226 inline void AssertGCThingMustBeTenured(JSObject* obj) {}
AssertGCThingIsNotNurseryAllocable(js::gc::Cell * cell)227 inline void AssertGCThingIsNotNurseryAllocable(js::gc::Cell* cell) {}
228 #endif
229 
230 /**
231  * The Heap<T> class is a heap-stored reference to a JS GC thing. All members of
232  * heap classes that refer to GC things should use Heap<T> (or possibly
233  * TenuredHeap<T>, described below).
234  *
235  * Heap<T> is an abstraction that hides some of the complexity required to
236  * maintain GC invariants for the contained reference. It uses operator
237  * overloading to provide a normal pointer interface, but notifies the GC every
238  * time the value it contains is updated. This is necessary for generational GC,
239  * which keeps track of all pointers into the nursery.
240  *
241  * Heap<T> instances must be traced when their containing object is traced to
242  * keep the pointed-to GC thing alive.
243  *
244  * Heap<T> objects should only be used on the heap. GC references stored on the
245  * C/C++ stack must use Rooted/Handle/MutableHandle instead.
246  *
247  * Type T must be a public GC pointer type.
248  */
249 template <typename T>
250 class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase<T, Heap<T>> {
251   // Please note: this can actually also be used by nsXBLMaybeCompiled<T>, for
252   // legacy reasons.
253   static_assert(js::IsHeapConstructibleType<T>::value,
254                 "Type T must be a public GC pointer type");
255 
256  public:
257   using ElementType = T;
258 
Heap()259   Heap() {
260     static_assert(sizeof(T) == sizeof(Heap<T>),
261                   "Heap<T> must be binary compatible with T.");
262     init(GCPolicy<T>::initial());
263   }
Heap(const T & p)264   explicit Heap(const T& p) { init(p); }
265 
266   /*
267    * For Heap, move semantics are equivalent to copy semantics. In C++, a
268    * copy constructor taking const-ref is the way to get a single function
269    * that will be used for both lvalue and rvalue copies, so we can simply
270    * omit the rvalue variant.
271    */
Heap(const Heap<T> & p)272   explicit Heap(const Heap<T>& p) { init(p.ptr); }
273 
~Heap()274   ~Heap() { post(ptr, GCPolicy<T>::initial()); }
275 
276   DECLARE_POINTER_CONSTREF_OPS(T);
277   DECLARE_POINTER_ASSIGN_OPS(Heap, T);
278 
address()279   const T* address() const { return &ptr; }
280 
exposeToActiveJS()281   void exposeToActiveJS() const { js::BarrierMethods<T>::exposeToJS(ptr); }
get()282   const T& get() const {
283     exposeToActiveJS();
284     return ptr;
285   }
unbarrieredGet()286   const T& unbarrieredGet() const { return ptr; }
287 
unsafeGet()288   T* unsafeGet() { return &ptr; }
289 
290   explicit operator bool() const {
291     return bool(js::BarrierMethods<T>::asGCThingOrNull(ptr));
292   }
293   explicit operator bool() {
294     return bool(js::BarrierMethods<T>::asGCThingOrNull(ptr));
295   }
296 
297  private:
init(const T & newPtr)298   void init(const T& newPtr) {
299     ptr = newPtr;
300     post(GCPolicy<T>::initial(), ptr);
301   }
302 
set(const T & newPtr)303   void set(const T& newPtr) {
304     T tmp = ptr;
305     ptr = newPtr;
306     post(tmp, ptr);
307   }
308 
post(const T & prev,const T & next)309   void post(const T& prev, const T& next) {
310     js::BarrierMethods<T>::postBarrier(&ptr, prev, next);
311   }
312 
313   T ptr;
314 };
315 
ObjectIsTenured(JSObject * obj)316 static MOZ_ALWAYS_INLINE bool ObjectIsTenured(JSObject* obj) {
317   return !js::gc::IsInsideNursery(reinterpret_cast<js::gc::Cell*>(obj));
318 }
319 
ObjectIsTenured(const Heap<JSObject * > & obj)320 static MOZ_ALWAYS_INLINE bool ObjectIsTenured(const Heap<JSObject*>& obj) {
321   return ObjectIsTenured(obj.unbarrieredGet());
322 }
323 
ObjectIsMarkedGray(JSObject * obj)324 static MOZ_ALWAYS_INLINE bool ObjectIsMarkedGray(JSObject* obj) {
325   auto cell = reinterpret_cast<js::gc::Cell*>(obj);
326   return js::gc::detail::CellIsMarkedGrayIfKnown(cell);
327 }
328 
ObjectIsMarkedGray(const JS::Heap<JSObject * > & obj)329 static MOZ_ALWAYS_INLINE bool ObjectIsMarkedGray(
330     const JS::Heap<JSObject*>& obj) {
331   return ObjectIsMarkedGray(obj.unbarrieredGet());
332 }
333 
334 // The following *IsNotGray functions are for use in assertions and take account
335 // of the eventual gray marking state at the end of any ongoing incremental GC.
336 #ifdef DEBUG
CellIsNotGray(js::gc::Cell * maybeCell)337 inline bool CellIsNotGray(js::gc::Cell* maybeCell) {
338   if (!maybeCell) return true;
339 
340   return js::gc::detail::CellIsNotGray(maybeCell);
341 }
342 
ObjectIsNotGray(JSObject * maybeObj)343 inline bool ObjectIsNotGray(JSObject* maybeObj) {
344   return CellIsNotGray(reinterpret_cast<js::gc::Cell*>(maybeObj));
345 }
346 
ObjectIsNotGray(const JS::Heap<JSObject * > & obj)347 inline bool ObjectIsNotGray(const JS::Heap<JSObject*>& obj) {
348   return ObjectIsNotGray(obj.unbarrieredGet());
349 }
350 #endif
351 
352 /**
353  * The TenuredHeap<T> class is similar to the Heap<T> class above in that it
354  * encapsulates the GC concerns of an on-heap reference to a JS object. However,
355  * it has two important differences:
356  *
357  *  1) Pointers which are statically known to only reference "tenured" objects
358  *     can avoid the extra overhead of SpiderMonkey's write barriers.
359  *
360  *  2) Objects in the "tenured" heap have stronger alignment restrictions than
361  *     those in the "nursery", so it is possible to store flags in the lower
362  *     bits of pointers known to be tenured. TenuredHeap wraps a normal tagged
363  *     pointer with a nice API for accessing the flag bits and adds various
364  *     assertions to ensure that it is not mis-used.
365  *
366  * GC things are said to be "tenured" when they are located in the long-lived
367  * heap: e.g. they have gained tenure as an object by surviving past at least
368  * one GC. For performance, SpiderMonkey allocates some things which are known
369  * to normally be long lived directly into the tenured generation; for example,
370  * global objects. Additionally, SpiderMonkey does not visit individual objects
371  * when deleting non-tenured objects, so object with finalizers are also always
372  * tenured; for instance, this includes most DOM objects.
373  *
374  * The considerations to keep in mind when using a TenuredHeap<T> vs a normal
375  * Heap<T> are:
376  *
377  *  - It is invalid for a TenuredHeap<T> to refer to a non-tenured thing.
378  *  - It is however valid for a Heap<T> to refer to a tenured thing.
379  *  - It is not possible to store flag bits in a Heap<T>.
380  */
381 template <typename T>
382 class TenuredHeap : public js::HeapBase<T, TenuredHeap<T>> {
383  public:
384   using ElementType = T;
385 
TenuredHeap()386   TenuredHeap() : bits(0) {
387     static_assert(sizeof(T) == sizeof(TenuredHeap<T>),
388                   "TenuredHeap<T> must be binary compatible with T.");
389   }
TenuredHeap(T p)390   explicit TenuredHeap(T p) : bits(0) { setPtr(p); }
TenuredHeap(const TenuredHeap<T> & p)391   explicit TenuredHeap(const TenuredHeap<T>& p) : bits(0) {
392     setPtr(p.getPtr());
393   }
394 
setPtr(T newPtr)395   void setPtr(T newPtr) {
396     MOZ_ASSERT((reinterpret_cast<uintptr_t>(newPtr) & flagsMask) == 0);
397     MOZ_ASSERT(js::gc::IsCellPointerValidOrNull(newPtr));
398     if (newPtr) AssertGCThingMustBeTenured(newPtr);
399     bits = (bits & flagsMask) | reinterpret_cast<uintptr_t>(newPtr);
400   }
401 
setFlags(uintptr_t flagsToSet)402   void setFlags(uintptr_t flagsToSet) {
403     MOZ_ASSERT((flagsToSet & ~flagsMask) == 0);
404     bits |= flagsToSet;
405   }
406 
unsetFlags(uintptr_t flagsToUnset)407   void unsetFlags(uintptr_t flagsToUnset) {
408     MOZ_ASSERT((flagsToUnset & ~flagsMask) == 0);
409     bits &= ~flagsToUnset;
410   }
411 
hasFlag(uintptr_t flag)412   bool hasFlag(uintptr_t flag) const {
413     MOZ_ASSERT((flag & ~flagsMask) == 0);
414     return (bits & flag) != 0;
415   }
416 
unbarrieredGetPtr()417   T unbarrieredGetPtr() const { return reinterpret_cast<T>(bits & ~flagsMask); }
getFlags()418   uintptr_t getFlags() const { return bits & flagsMask; }
419 
exposeToActiveJS()420   void exposeToActiveJS() const {
421     js::BarrierMethods<T>::exposeToJS(unbarrieredGetPtr());
422   }
getPtr()423   T getPtr() const {
424     exposeToActiveJS();
425     return unbarrieredGetPtr();
426   }
427 
T()428   operator T() const { return getPtr(); }
429   T operator->() const { return getPtr(); }
430 
431   explicit operator bool() const {
432     return bool(js::BarrierMethods<T>::asGCThingOrNull(unbarrieredGetPtr()));
433   }
434   explicit operator bool() {
435     return bool(js::BarrierMethods<T>::asGCThingOrNull(unbarrieredGetPtr()));
436   }
437 
438   TenuredHeap<T>& operator=(T p) {
439     setPtr(p);
440     return *this;
441   }
442 
443   TenuredHeap<T>& operator=(const TenuredHeap<T>& other) {
444     bits = other.bits;
445     return *this;
446   }
447 
448  private:
449   enum {
450     maskBits = 3,
451     flagsMask = (1 << maskBits) - 1,
452   };
453 
454   uintptr_t bits;
455 };
456 
457 /**
458  * Reference to a T that has been rooted elsewhere. This is most useful
459  * as a parameter type, which guarantees that the T lvalue is properly
460  * rooted. See "Move GC Stack Rooting" above.
461  *
462  * If you want to add additional methods to Handle for a specific
463  * specialization, define a HandleBase<T> specialization containing them.
464  */
465 template <typename T>
466 class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T, Handle<T>> {
467   friend class JS::MutableHandle<T>;
468 
469  public:
470   using ElementType = T;
471 
472   /* Creates a handle from a handle of a type convertible to T. */
473   template <typename S>
474   MOZ_IMPLICIT Handle(
475       Handle<S> handle,
476       typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type
477           dummy = 0) {
478     static_assert(sizeof(Handle<T>) == sizeof(T*),
479                   "Handle must be binary compatible with T*.");
480     ptr = reinterpret_cast<const T*>(handle.address());
481   }
482 
Handle(decltype (nullptr))483   MOZ_IMPLICIT Handle(decltype(nullptr)) {
484     static_assert(mozilla::IsPointer<T>::value,
485                   "nullptr_t overload not valid for non-pointer types");
486     static void* const ConstNullValue = nullptr;
487     ptr = reinterpret_cast<const T*>(&ConstNullValue);
488   }
489 
Handle(MutableHandle<T> handle)490   MOZ_IMPLICIT Handle(MutableHandle<T> handle) { ptr = handle.address(); }
491 
492   /*
493    * Take care when calling this method!
494    *
495    * This creates a Handle from the raw location of a T.
496    *
497    * It should be called only if the following conditions hold:
498    *
499    *  1) the location of the T is guaranteed to be marked (for some reason
500    *     other than being a Rooted), e.g., if it is guaranteed to be reachable
501    *     from an implicit root.
502    *
503    *  2) the contents of the location are immutable, or at least cannot change
504    *     for the lifetime of the handle, as its users may not expect its value
505    *     to change underneath them.
506    */
fromMarkedLocation(const T * p)507   static constexpr Handle fromMarkedLocation(const T* p) {
508     return Handle(p, DeliberatelyChoosingThisOverload,
509                   ImUsingThisOnlyInFromFromMarkedLocation);
510   }
511 
512   /*
513    * Construct a handle from an explicitly rooted location. This is the
514    * normal way to create a handle, and normally happens implicitly.
515    */
516   template <typename S>
517   inline MOZ_IMPLICIT Handle(
518       const Rooted<S>& root,
519       typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type
520           dummy = 0);
521 
522   template <typename S>
523   inline MOZ_IMPLICIT Handle(
524       const PersistentRooted<S>& root,
525       typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type
526           dummy = 0);
527 
528   /* Construct a read only handle from a mutable handle. */
529   template <typename S>
530   inline MOZ_IMPLICIT Handle(
531       MutableHandle<S>& root,
532       typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type
533           dummy = 0);
534 
535   DECLARE_POINTER_CONSTREF_OPS(T);
536   DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr);
537 
538  private:
Handle()539   Handle() {}
540   DELETE_ASSIGNMENT_OPS(Handle, T);
541 
542   enum Disambiguator { DeliberatelyChoosingThisOverload = 42 };
543   enum CallerIdentity { ImUsingThisOnlyInFromFromMarkedLocation = 17 };
Handle(const T * p,Disambiguator,CallerIdentity)544   constexpr Handle(const T* p, Disambiguator, CallerIdentity) : ptr(p) {}
545 
546   const T* ptr;
547 };
548 
549 /**
550  * Similar to a handle, but the underlying storage can be changed. This is
551  * useful for outparams.
552  *
553  * If you want to add additional methods to MutableHandle for a specific
554  * specialization, define a MutableHandleBase<T> specialization containing
555  * them.
556  */
557 template <typename T>
558 class MOZ_STACK_CLASS MutableHandle
559     : public js::MutableHandleBase<T, MutableHandle<T>> {
560  public:
561   using ElementType = T;
562 
563   inline MOZ_IMPLICIT MutableHandle(Rooted<T>* root);
564   inline MOZ_IMPLICIT MutableHandle(PersistentRooted<T>* root);
565 
566  private:
567   // Disallow nullptr for overloading purposes.
568   MutableHandle(decltype(nullptr)) = delete;
569 
570  public:
set(const T & v)571   void set(const T& v) {
572     *ptr = v;
573     MOZ_ASSERT(GCPolicy<T>::isValid(*ptr));
574   }
set(T && v)575   void set(T&& v) {
576     *ptr = mozilla::Move(v);
577     MOZ_ASSERT(GCPolicy<T>::isValid(*ptr));
578   }
579 
580   /*
581    * This may be called only if the location of the T is guaranteed
582    * to be marked (for some reason other than being a Rooted),
583    * e.g., if it is guaranteed to be reachable from an implicit root.
584    *
585    * Create a MutableHandle from a raw location of a T.
586    */
fromMarkedLocation(T * p)587   static MutableHandle fromMarkedLocation(T* p) {
588     MutableHandle h;
589     h.ptr = p;
590     return h;
591   }
592 
593   DECLARE_POINTER_CONSTREF_OPS(T);
594   DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr);
595   DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr);
596 
597  private:
MutableHandle()598   MutableHandle() {}
599   DELETE_ASSIGNMENT_OPS(MutableHandle, T);
600 
601   T* ptr;
602 };
603 
604 } /* namespace JS */
605 
606 namespace js {
607 
608 template <typename T>
609 struct BarrierMethods<T*> {
610   static T* initial() { return nullptr; }
611   static gc::Cell* asGCThingOrNull(T* v) {
612     if (!v) return nullptr;
613     MOZ_ASSERT(uintptr_t(v) > 32);
614     return reinterpret_cast<gc::Cell*>(v);
615   }
616   static void postBarrier(T** vp, T* prev, T* next) {
617     if (next)
618       JS::AssertGCThingIsNotNurseryAllocable(
619           reinterpret_cast<js::gc::Cell*>(next));
620   }
621   static void exposeToJS(T* t) {
622     if (t) js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(t));
623   }
624 };
625 
626 template <>
627 struct BarrierMethods<JSObject*> {
628   static JSObject* initial() { return nullptr; }
629   static gc::Cell* asGCThingOrNull(JSObject* v) {
630     if (!v) return nullptr;
631     MOZ_ASSERT(uintptr_t(v) > 32);
632     return reinterpret_cast<gc::Cell*>(v);
633   }
634   static void postBarrier(JSObject** vp, JSObject* prev, JSObject* next) {
635     JS::HeapObjectPostBarrier(vp, prev, next);
636   }
637   static void exposeToJS(JSObject* obj) {
638     if (obj) JS::ExposeObjectToActiveJS(obj);
639   }
640 };
641 
642 template <>
643 struct BarrierMethods<JSFunction*> {
644   static JSFunction* initial() { return nullptr; }
645   static gc::Cell* asGCThingOrNull(JSFunction* v) {
646     if (!v) return nullptr;
647     MOZ_ASSERT(uintptr_t(v) > 32);
648     return reinterpret_cast<gc::Cell*>(v);
649   }
650   static void postBarrier(JSFunction** vp, JSFunction* prev, JSFunction* next) {
651     JS::HeapObjectPostBarrier(reinterpret_cast<JSObject**>(vp),
652                               reinterpret_cast<JSObject*>(prev),
653                               reinterpret_cast<JSObject*>(next));
654   }
655   static void exposeToJS(JSFunction* fun) {
656     if (fun) JS::ExposeObjectToActiveJS(reinterpret_cast<JSObject*>(fun));
657   }
658 };
659 
660 template <>
661 struct BarrierMethods<JSString*> {
662   static JSString* initial() { return nullptr; }
663   static gc::Cell* asGCThingOrNull(JSString* v) {
664     if (!v) return nullptr;
665     MOZ_ASSERT(uintptr_t(v) > 32);
666     return reinterpret_cast<gc::Cell*>(v);
667   }
668   static void postBarrier(JSString** vp, JSString* prev, JSString* next) {
669     JS::HeapStringPostBarrier(vp, prev, next);
670   }
671   static void exposeToJS(JSString* v) {
672     if (v) js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(v));
673   }
674 };
675 
676 // Provide hash codes for Cell kinds that may be relocated and, thus, not have
677 // a stable address to use as the base for a hash code. Instead of the address,
678 // this hasher uses Cell::getUniqueId to provide exact matches and as a base
679 // for generating hash codes.
680 //
681 // Note: this hasher, like PointerHasher can "hash" a nullptr. While a nullptr
682 // would not likely be a useful key, there are some cases where being able to
683 // hash a nullptr is useful, either on purpose or because of bugs:
684 // (1) existence checks where the key may happen to be null and (2) some
685 // aggregate Lookup kinds embed a JSObject* that is frequently null and do not
686 // null test before dispatching to the hasher.
687 template <typename T>
688 struct JS_PUBLIC_API MovableCellHasher {
689   using Key = T;
690   using Lookup = T;
691 
692   static bool hasHash(const Lookup& l);
693   static bool ensureHash(const Lookup& l);
694   static HashNumber hash(const Lookup& l);
695   static bool match(const Key& k, const Lookup& l);
696   static void rekey(Key& k, const Key& newKey) { k = newKey; }
697 };
698 
699 template <typename T>
700 struct JS_PUBLIC_API MovableCellHasher<JS::Heap<T>> {
701   using Key = JS::Heap<T>;
702   using Lookup = T;
703 
704   static bool hasHash(const Lookup& l) {
705     return MovableCellHasher<T>::hasHash(l);
706   }
707   static bool ensureHash(const Lookup& l) {
708     return MovableCellHasher<T>::ensureHash(l);
709   }
710   static HashNumber hash(const Lookup& l) {
711     return MovableCellHasher<T>::hash(l);
712   }
713   static bool match(const Key& k, const Lookup& l) {
714     return MovableCellHasher<T>::match(k.unbarrieredGet(), l);
715   }
716   static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); }
717 };
718 
719 template <typename T>
720 struct FallibleHashMethods<MovableCellHasher<T>> {
721   template <typename Lookup>
722   static bool hasHash(Lookup&& l) {
723     return MovableCellHasher<T>::hasHash(mozilla::Forward<Lookup>(l));
724   }
725   template <typename Lookup>
726   static bool ensureHash(Lookup&& l) {
727     return MovableCellHasher<T>::ensureHash(mozilla::Forward<Lookup>(l));
728   }
729 };
730 
731 } /* namespace js */
732 
733 namespace js {
734 
735 // The alignment must be set because the Rooted and PersistentRooted ptr fields
736 // may be accessed through reinterpret_cast<Rooted<ConcreteTraceable>*>, and
737 // the compiler may choose a different alignment for the ptr field when it
738 // knows the actual type stored in DispatchWrapper<T>.
739 //
740 // It would make more sense to align only those specific fields of type
741 // DispatchWrapper, rather than DispatchWrapper itself, but that causes MSVC to
742 // fail when Rooted is used in an IsConvertible test.
743 template <typename T>
744 class alignas(8) DispatchWrapper {
745   static_assert(JS::MapTypeToRootKind<T>::kind == JS::RootKind::Traceable,
746                 "DispatchWrapper is intended only for usage with a Traceable");
747 
748   using TraceFn = void (*)(JSTracer*, T*, const char*);
749   TraceFn tracer;
750   alignas(gc::CellAlignBytes) T storage;
751 
752  public:
753   template <typename U>
754   MOZ_IMPLICIT DispatchWrapper(U&& initial)
755       : tracer(&JS::GCPolicy<T>::trace),
756         storage(mozilla::Forward<U>(initial)) {}
757 
758   // Mimic a pointer type, so that we can drop into Rooted.
759   T* operator&() { return &storage; }
760   const T* operator&() const { return &storage; }
761   operator T&() { return storage; }
762   operator const T&() const { return storage; }
763 
764   // Trace the contained storage (of unknown type) using the trace function
765   // we set aside when we did know the type.
766   static void TraceWrapped(JSTracer* trc, T* thingp, const char* name) {
767     auto wrapper = reinterpret_cast<DispatchWrapper*>(
768         uintptr_t(thingp) - offsetof(DispatchWrapper, storage));
769     wrapper->tracer(trc, &wrapper->storage, name);
770   }
771 };
772 
773 } /* namespace js */
774 
775 namespace JS {
776 
777 class JS_PUBLIC_API AutoGCRooter;
778 
779 // Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
780 // instantiation of MapTypeToRootKind.
781 template <>
782 struct MapTypeToRootKind<void*> {
783   static const RootKind kind = RootKind::Traceable;
784 };
785 
786 using RootedListHeads =
787     mozilla::EnumeratedArray<RootKind, RootKind::Limit, Rooted<void*>*>;
788 
789 // Superclass of JSContext which can be used for rooting data in use by the
790 // current thread but that does not provide all the functions of a JSContext.
791 class RootingContext {
792   // Stack GC roots for Rooted GC heap pointers.
793   RootedListHeads stackRoots_;
794   template <typename T>
795   friend class JS::Rooted;
796 
797   // Stack GC roots for AutoFooRooter classes.
798   JS::AutoGCRooter* autoGCRooters_;
799   friend class JS::AutoGCRooter;
800 
801   // Gecko profiling metadata.
802   // This isn't really rooting related. It's only here because we want
803   // GetContextProfilingStack to be inlineable into non-JS code, and we
804   // didn't want to add another superclass of JSContext just for this.
805   js::GeckoProfilerThread geckoProfiler_;
806 
807  public:
808   RootingContext();
809 
810   void traceStackRoots(JSTracer* trc);
811   void checkNoGCRooters();
812 
813   js::GeckoProfilerThread& geckoProfiler() { return geckoProfiler_; }
814 
815  protected:
816   // The remaining members in this class should only be accessed through
817   // JSContext pointers. They are unrelated to rooting and are in place so
818   // that inlined API functions can directly access the data.
819 
820   /* The current compartment. */
821   JSCompartment* compartment_;
822 
823   /* The current zone. */
824   JS::Zone* zone_;
825 
826  public:
827   /* Limit pointer for checking native stack consumption. */
828   uintptr_t nativeStackLimit[StackKindCount];
829 
830   static const RootingContext* get(const JSContext* cx) {
831     return reinterpret_cast<const RootingContext*>(cx);
832   }
833 
834   static RootingContext* get(JSContext* cx) {
835     return reinterpret_cast<RootingContext*>(cx);
836   }
837 
838   friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
839   friend JS::Zone* js::GetContextZone(const JSContext* cx);
840 };
841 
842 class JS_PUBLIC_API AutoGCRooter {
843  public:
844   AutoGCRooter(JSContext* cx, ptrdiff_t tag)
845       : AutoGCRooter(JS::RootingContext::get(cx), tag) {}
846   AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag)
847       : down(cx->autoGCRooters_), tag_(tag), stackTop(&cx->autoGCRooters_) {
848     MOZ_ASSERT(this != *stackTop);
849     *stackTop = this;
850   }
851 
852   ~AutoGCRooter() {
853     MOZ_ASSERT(this == *stackTop);
854     *stackTop = down;
855   }
856 
857   /* Implemented in gc/RootMarking.cpp. */
858   inline void trace(JSTracer* trc);
859   static void traceAll(const js::CooperatingContext& target, JSTracer* trc);
860   static void traceAllWrappers(const js::CooperatingContext& target,
861                                JSTracer* trc);
862 
863  protected:
864   AutoGCRooter* const down;
865 
866   /*
867    * Discriminates actual subclass of this being used.  If non-negative, the
868    * subclass roots an array of values of the length stored in this field.
869    * If negative, meaning is indicated by the corresponding value in the enum
870    * below.  Any other negative value indicates some deeper problem such as
871    * memory corruption.
872    */
873   ptrdiff_t tag_;
874 
875   enum {
876     VALARRAY = -2, /* js::AutoValueArray */
877     PARSER = -3,   /* js::frontend::Parser */
878 #if defined(JS_BUILD_BINAST)
879     BINPARSER = -4,   /* js::frontend::BinSource */
880 #endif                // defined(JS_BUILD_BINAST)
881     IONMASM = -19,    /* js::jit::MacroAssembler */
882     WRAPVECTOR = -20, /* js::AutoWrapperVector */
883     WRAPPER = -21,    /* js::AutoWrapperRooter */
884     CUSTOM = -26      /* js::CustomAutoRooter */
885   };
886 
887  private:
888   AutoGCRooter** const stackTop;
889 
890   /* No copy or assignment semantics. */
891   AutoGCRooter(AutoGCRooter& ida) = delete;
892   void operator=(AutoGCRooter& ida) = delete;
893 };
894 
895 namespace detail {
896 
897 /*
898  * For pointer types, the TraceKind for tracing is based on the list it is
899  * in (selected via MapTypeToRootKind), so no additional storage is
900  * required here. Non-pointer types, however, share the same list, so the
901  * function to call for tracing is stored adjacent to the struct. Since C++
902  * cannot templatize on storage class, this is implemented via the wrapper
903  * class DispatchWrapper.
904  */
905 template <typename T>
906 using MaybeWrapped =
907     typename mozilla::Conditional<MapTypeToRootKind<T>::kind ==
908                                       JS::RootKind::Traceable,
909                                   js::DispatchWrapper<T>, T>::Type;
910 
911 } /* namespace detail */
912 
913 /**
914  * Local variable of type T whose value is always rooted. This is typically
915  * used for local variables, or for non-rooted values being passed to a
916  * function that requires a handle, e.g. Foo(Root<T>(cx, x)).
917  *
918  * If you want to add additional methods to Rooted for a specific
919  * specialization, define a RootedBase<T> specialization containing them.
920  */
921 template <typename T>
922 class MOZ_RAII Rooted : public js::RootedBase<T, Rooted<T>> {
923   inline void registerWithRootLists(RootedListHeads& roots) {
924     this->stack = &roots[JS::MapTypeToRootKind<T>::kind];
925     this->prev = *stack;
926     *stack = reinterpret_cast<Rooted<void*>*>(this);
927   }
928 
929   inline RootedListHeads& rootLists(RootingContext* cx) {
930     return cx->stackRoots_;
931   }
932   inline RootedListHeads& rootLists(JSContext* cx) {
933     return rootLists(RootingContext::get(cx));
934   }
935 
936  public:
937   using ElementType = T;
938 
939   template <typename RootingContext>
940   explicit Rooted(const RootingContext& cx) : ptr(GCPolicy<T>::initial()) {
941     registerWithRootLists(rootLists(cx));
942   }
943 
944   template <typename RootingContext, typename S>
945   Rooted(const RootingContext& cx, S&& initial)
946       : ptr(mozilla::Forward<S>(initial)) {
947     MOZ_ASSERT(GCPolicy<T>::isValid(ptr));
948     registerWithRootLists(rootLists(cx));
949   }
950 
951   ~Rooted() {
952     MOZ_ASSERT(*stack == reinterpret_cast<Rooted<void*>*>(this));
953     *stack = prev;
954   }
955 
956   Rooted<T>* previous() { return reinterpret_cast<Rooted<T>*>(prev); }
957 
958   /*
959    * This method is public for Rooted so that Codegen.py can use a Rooted
960    * interchangeably with a MutableHandleValue.
961    */
962   void set(const T& value) {
963     ptr = value;
964     MOZ_ASSERT(GCPolicy<T>::isValid(ptr));
965   }
966   void set(T&& value) {
967     ptr = mozilla::Move(value);
968     MOZ_ASSERT(GCPolicy<T>::isValid(ptr));
969   }
970 
971   DECLARE_POINTER_CONSTREF_OPS(T);
972   DECLARE_POINTER_ASSIGN_OPS(Rooted, T);
973   DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
974   DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr);
975 
976  private:
977   /*
978    * These need to be templated on void* to avoid aliasing issues between, for
979    * example, Rooted<JSObject> and Rooted<JSFunction>, which use the same
980    * stack head pointer for different classes.
981    */
982   Rooted<void*>** stack;
983   Rooted<void*>* prev;
984 
985   detail::MaybeWrapped<T> ptr;
986 
987   Rooted(const Rooted&) = delete;
988 } JS_HAZ_ROOTED;
989 
990 } /* namespace JS */
991 
992 namespace js {
993 
994 /*
995  * Inlinable accessors for JSContext.
996  *
997  * - These must not be available on the more restricted superclasses of
998  *   JSContext, so we can't simply define them on RootingContext.
999  *
1000  * - They're perfectly ordinary JSContext functionality, so ought to be
1001  *   usable without resorting to jsfriendapi.h, and when JSContext is an
1002  *   incomplete type.
1003  */
1004 inline JSCompartment* GetContextCompartment(const JSContext* cx) {
1005   return JS::RootingContext::get(cx)->compartment_;
1006 }
1007 
1008 inline JS::Zone* GetContextZone(const JSContext* cx) {
1009   return JS::RootingContext::get(cx)->zone_;
1010 }
1011 
1012 inline PseudoStack* GetContextProfilingStack(JSContext* cx) {
1013   return JS::RootingContext::get(cx)->geckoProfiler().getPseudoStack();
1014 }
1015 
1016 /**
1017  * Augment the generic Rooted<T> interface when T = JSObject* with
1018  * class-querying and downcasting operations.
1019  *
1020  * Given a Rooted<JSObject*> obj, one can view
1021  *   Handle<StringObject*> h = obj.as<StringObject*>();
1022  * as an optimization of
1023  *   Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
1024  *   Handle<StringObject*> h = rooted;
1025  */
1026 template <typename Container>
1027 class RootedBase<JSObject*, Container>
1028     : public MutableWrappedPtrOperations<JSObject*, Container> {
1029  public:
1030   template <class U>
1031   JS::Handle<U*> as() const;
1032 };
1033 
1034 /**
1035  * Augment the generic Handle<T> interface when T = JSObject* with
1036  * downcasting operations.
1037  *
1038  * Given a Handle<JSObject*> obj, one can view
1039  *   Handle<StringObject*> h = obj.as<StringObject*>();
1040  * as an optimization of
1041  *   Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
1042  *   Handle<StringObject*> h = rooted;
1043  */
1044 template <typename Container>
1045 class HandleBase<JSObject*, Container>
1046     : public WrappedPtrOperations<JSObject*, Container> {
1047  public:
1048   template <class U>
1049   JS::Handle<U*> as() const;
1050 };
1051 
1052 /**
1053  * Types for a variable that either should or shouldn't be rooted, depending on
1054  * the template parameter allowGC. Used for implementing functions that can
1055  * operate on either rooted or unrooted data.
1056  *
1057  * The toHandle() and toMutableHandle() functions are for calling functions
1058  * which require handle types and are only called in the CanGC case. These
1059  * allow the calling code to type check.
1060  */
1061 enum AllowGC { NoGC = 0, CanGC = 1 };
1062 template <typename T, AllowGC allowGC>
1063 class MaybeRooted {};
1064 
1065 template <typename T>
1066 class MaybeRooted<T, CanGC> {
1067  public:
1068   typedef JS::Handle<T> HandleType;
1069   typedef JS::Rooted<T> RootType;
1070   typedef JS::MutableHandle<T> MutableHandleType;
1071 
1072   static inline JS::Handle<T> toHandle(HandleType v) { return v; }
1073 
1074   static inline JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
1075     return v;
1076   }
1077 
1078   template <typename T2>
1079   static inline JS::Handle<T2*> downcastHandle(HandleType v) {
1080     return v.template as<T2>();
1081   }
1082 };
1083 
1084 } /* namespace js */
1085 
1086 namespace JS {
1087 
1088 template <typename T>
1089 template <typename S>
1090 inline Handle<T>::Handle(
1091     const Rooted<S>& root,
1092     typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type
1093         dummy) {
1094   ptr = reinterpret_cast<const T*>(root.address());
1095 }
1096 
1097 template <typename T>
1098 template <typename S>
1099 inline Handle<T>::Handle(
1100     const PersistentRooted<S>& root,
1101     typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type
1102         dummy) {
1103   ptr = reinterpret_cast<const T*>(root.address());
1104 }
1105 
1106 template <typename T>
1107 template <typename S>
1108 inline Handle<T>::Handle(
1109     MutableHandle<S>& root,
1110     typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type
1111         dummy) {
1112   ptr = reinterpret_cast<const T*>(root.address());
1113 }
1114 
1115 template <typename T>
1116 inline MutableHandle<T>::MutableHandle(Rooted<T>* root) {
1117   static_assert(sizeof(MutableHandle<T>) == sizeof(T*),
1118                 "MutableHandle must be binary compatible with T*.");
1119   ptr = root->address();
1120 }
1121 
1122 template <typename T>
1123 inline MutableHandle<T>::MutableHandle(PersistentRooted<T>* root) {
1124   static_assert(sizeof(MutableHandle<T>) == sizeof(T*),
1125                 "MutableHandle must be binary compatible with T*.");
1126   ptr = root->address();
1127 }
1128 
1129 JS_PUBLIC_API void AddPersistentRoot(RootingContext* cx, RootKind kind,
1130                                      PersistentRooted<void*>* root);
1131 
1132 JS_PUBLIC_API void AddPersistentRoot(JSRuntime* rt, RootKind kind,
1133                                      PersistentRooted<void*>* root);
1134 
1135 /**
1136  * A copyable, assignable global GC root type with arbitrary lifetime, an
1137  * infallible constructor, and automatic unrooting on destruction.
1138  *
1139  * These roots can be used in heap-allocated data structures, so they are not
1140  * associated with any particular JSContext or stack. They are registered with
1141  * the JSRuntime itself, without locking, so they require a full JSContext to be
1142  * initialized, not one of its more restricted superclasses. Initialization may
1143  * take place on construction, or in two phases if the no-argument constructor
1144  * is called followed by init().
1145  *
1146  * Note that you must not use an PersistentRooted in an object owned by a JS
1147  * object:
1148  *
1149  * Whenever one object whose lifetime is decided by the GC refers to another
1150  * such object, that edge must be traced only if the owning JS object is traced.
1151  * This applies not only to JS objects (which obviously are managed by the GC)
1152  * but also to C++ objects owned by JS objects.
1153  *
1154  * If you put a PersistentRooted in such a C++ object, that is almost certainly
1155  * a leak. When a GC begins, the referent of the PersistentRooted is treated as
1156  * live, unconditionally (because a PersistentRooted is a *root*), even if the
1157  * JS object that owns it is unreachable. If there is any path from that
1158  * referent back to the JS object, then the C++ object containing the
1159  * PersistentRooted will not be destructed, and the whole blob of objects will
1160  * not be freed, even if there are no references to them from the outside.
1161  *
1162  * In the context of Firefox, this is a severe restriction: almost everything in
1163  * Firefox is owned by some JS object or another, so using PersistentRooted in
1164  * such objects would introduce leaks. For these kinds of edges, Heap<T> or
1165  * TenuredHeap<T> would be better types. It's up to the implementor of the type
1166  * containing Heap<T> or TenuredHeap<T> members to make sure their referents get
1167  * marked when the object itself is marked.
1168  */
1169 template <typename T>
1170 class PersistentRooted
1171     : public js::RootedBase<T, PersistentRooted<T>>,
1172       private mozilla::LinkedListElement<PersistentRooted<T>> {
1173   using ListBase = mozilla::LinkedListElement<PersistentRooted<T>>;
1174 
1175   friend class mozilla::LinkedList<PersistentRooted>;
1176   friend class mozilla::LinkedListElement<PersistentRooted>;
1177 
1178   void registerWithRootLists(RootingContext* cx) {
1179     MOZ_ASSERT(!initialized());
1180     JS::RootKind kind = JS::MapTypeToRootKind<T>::kind;
1181     AddPersistentRoot(cx, kind,
1182                       reinterpret_cast<JS::PersistentRooted<void*>*>(this));
1183   }
1184 
1185   void registerWithRootLists(JSRuntime* rt) {
1186     MOZ_ASSERT(!initialized());
1187     JS::RootKind kind = JS::MapTypeToRootKind<T>::kind;
1188     AddPersistentRoot(rt, kind,
1189                       reinterpret_cast<JS::PersistentRooted<void*>*>(this));
1190   }
1191 
1192  public:
1193   using ElementType = T;
1194 
1195   PersistentRooted() : ptr(GCPolicy<T>::initial()) {}
1196 
1197   explicit PersistentRooted(RootingContext* cx) : ptr(GCPolicy<T>::initial()) {
1198     registerWithRootLists(cx);
1199   }
1200 
1201   explicit PersistentRooted(JSContext* cx) : ptr(GCPolicy<T>::initial()) {
1202     registerWithRootLists(RootingContext::get(cx));
1203   }
1204 
1205   template <typename U>
1206   PersistentRooted(RootingContext* cx, U&& initial)
1207       : ptr(mozilla::Forward<U>(initial)) {
1208     registerWithRootLists(cx);
1209   }
1210 
1211   template <typename U>
1212   PersistentRooted(JSContext* cx, U&& initial)
1213       : ptr(mozilla::Forward<U>(initial)) {
1214     registerWithRootLists(RootingContext::get(cx));
1215   }
1216 
1217   explicit PersistentRooted(JSRuntime* rt) : ptr(GCPolicy<T>::initial()) {
1218     registerWithRootLists(rt);
1219   }
1220 
1221   template <typename U>
1222   PersistentRooted(JSRuntime* rt, U&& initial)
1223       : ptr(mozilla::Forward<U>(initial)) {
1224     registerWithRootLists(rt);
1225   }
1226 
1227   PersistentRooted(const PersistentRooted& rhs)
1228       : mozilla::LinkedListElement<PersistentRooted<T>>(), ptr(rhs.ptr) {
1229     /*
1230      * Copy construction takes advantage of the fact that the original
1231      * is already inserted, and simply adds itself to whatever list the
1232      * original was on - no JSRuntime pointer needed.
1233      *
1234      * This requires mutating rhs's links, but those should be 'mutable'
1235      * anyway. C++ doesn't let us declare mutable base classes.
1236      */
1237     const_cast<PersistentRooted&>(rhs).setNext(this);
1238   }
1239 
1240   bool initialized() { return ListBase::isInList(); }
1241 
1242   void init(JSContext* cx) { init(cx, GCPolicy<T>::initial()); }
1243 
1244   template <typename U>
1245   void init(JSContext* cx, U&& initial) {
1246     ptr = mozilla::Forward<U>(initial);
1247     registerWithRootLists(RootingContext::get(cx));
1248   }
1249 
1250   void reset() {
1251     if (initialized()) {
1252       set(GCPolicy<T>::initial());
1253       ListBase::remove();
1254     }
1255   }
1256 
1257   DECLARE_POINTER_CONSTREF_OPS(T);
1258   DECLARE_POINTER_ASSIGN_OPS(PersistentRooted, T);
1259   DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
1260 
1261   // These are the same as DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS, except
1262   // they check that |this| is initialized in case the caller later stores
1263   // something in |ptr|.
1264   T* address() {
1265     MOZ_ASSERT(initialized());
1266     return &ptr;
1267   }
1268   T& get() {
1269     MOZ_ASSERT(initialized());
1270     return ptr;
1271   }
1272 
1273  private:
1274   template <typename U>
1275   void set(U&& value) {
1276     MOZ_ASSERT(initialized());
1277     ptr = mozilla::Forward<U>(value);
1278   }
1279 
1280   detail::MaybeWrapped<T> ptr;
1281 } JS_HAZ_ROOTED;
1282 
1283 class JS_PUBLIC_API ObjectPtr {
1284   Heap<JSObject*> value;
1285 
1286  public:
1287   using ElementType = JSObject*;
1288 
1289   ObjectPtr() : value(nullptr) {}
1290 
1291   explicit ObjectPtr(JSObject* obj) : value(obj) {}
1292 
1293   ObjectPtr(const ObjectPtr& other) : value(other.value) {}
1294 
1295   ObjectPtr(ObjectPtr&& other) : value(other.value) { other.value = nullptr; }
1296 
1297   /* Always call finalize before the destructor. */
1298   ~ObjectPtr() { MOZ_ASSERT(!value); }
1299 
1300   void finalize(JSRuntime* rt);
1301   void finalize(JSContext* cx);
1302 
1303   void init(JSObject* obj) { value = obj; }
1304 
1305   JSObject* get() const { return value; }
1306   JSObject* unbarrieredGet() const { return value.unbarrieredGet(); }
1307 
1308   void writeBarrierPre(JSContext* cx) { IncrementalPreWriteBarrier(value); }
1309 
1310   void updateWeakPointerAfterGC();
1311 
1312   ObjectPtr& operator=(JSObject* obj) {
1313     IncrementalPreWriteBarrier(value);
1314     value = obj;
1315     return *this;
1316   }
1317 
1318   void trace(JSTracer* trc, const char* name);
1319 
1320   JSObject& operator*() const { return *value; }
1321   JSObject* operator->() const { return value; }
1322   operator JSObject*() const { return value; }
1323 
1324   explicit operator bool() const { return value.unbarrieredGet(); }
1325   explicit operator bool() { return value.unbarrieredGet(); }
1326 };
1327 
1328 } /* namespace JS */
1329 
1330 namespace js {
1331 
1332 template <typename T, typename D, typename Container>
1333 class WrappedPtrOperations<UniquePtr<T, D>, Container> {
1334   const UniquePtr<T, D>& uniquePtr() const {
1335     return static_cast<const Container*>(this)->get();
1336   }
1337 
1338  public:
1339   explicit operator bool() const { return !!uniquePtr(); }
1340   T* get() const { return uniquePtr().get(); }
1341   T* operator->() const { return get(); }
1342   T& operator*() const { return *uniquePtr(); }
1343 };
1344 
1345 template <typename T, typename D, typename Container>
1346 class MutableWrappedPtrOperations<UniquePtr<T, D>, Container>
1347     : public WrappedPtrOperations<UniquePtr<T, D>, Container> {
1348   UniquePtr<T, D>& uniquePtr() { return static_cast<Container*>(this)->get(); }
1349 
1350  public:
1351   MOZ_MUST_USE typename UniquePtr<T, D>::Pointer release() {
1352     return uniquePtr().release();
1353   }
1354   void reset(T* ptr = T()) { uniquePtr().reset(ptr); }
1355 };
1356 
1357 namespace gc {
1358 
1359 template <typename T, typename TraceCallbacks>
1360 void CallTraceCallbackOnNonHeap(T* v, const TraceCallbacks& aCallbacks,
1361                                 const char* aName, void* aClosure) {
1362   static_assert(sizeof(T) == sizeof(JS::Heap<T>),
1363                 "T and Heap<T> must be compatible.");
1364   MOZ_ASSERT(v);
1365   mozilla::DebugOnly<Cell*> cell = BarrierMethods<T>::asGCThingOrNull(*v);
1366   MOZ_ASSERT(cell);
1367   MOZ_ASSERT(!IsInsideNursery(cell));
1368   JS::Heap<T>* asHeapT = reinterpret_cast<JS::Heap<T>*>(v);
1369   aCallbacks.Trace(asHeapT, aName, aClosure);
1370 }
1371 
1372 } /* namespace gc */
1373 } /* namespace js */
1374 
1375 // mozilla::Swap uses a stack temporary, which prevents classes like Heap<T>
1376 // from being declared MOZ_HEAP_CLASS.
1377 namespace mozilla {
1378 
1379 template <typename T>
1380 inline void Swap(JS::Heap<T>& aX, JS::Heap<T>& aY) {
1381   T tmp = aX;
1382   aX = aY;
1383   aY = tmp;
1384 }
1385 
1386 template <typename T>
1387 inline void Swap(JS::TenuredHeap<T>& aX, JS::TenuredHeap<T>& aY) {
1388   T tmp = aX;
1389   aX = aY;
1390   aY = tmp;
1391 }
1392 
1393 } /* namespace mozilla */
1394 
1395 namespace js {
1396 namespace detail {
1397 
1398 // DefineComparisonOps is a trait which selects which wrapper classes to define
1399 // operator== and operator!= for. It supplies a getter function to extract the
1400 // value to compare. This is used to avoid triggering the automatic read
1401 // barriers where appropriate.
1402 //
1403 // If DefineComparisonOps is not specialized for a particular wrapper you may
1404 // get errors such as 'invalid operands to binary expression' or 'no match for
1405 // operator==' when trying to compare against instances of the wrapper.
1406 
1407 template <typename T>
1408 struct DefineComparisonOps : mozilla::FalseType {};
1409 
1410 template <typename T>
1411 struct DefineComparisonOps<JS::Heap<T>> : mozilla::TrueType {
1412   static const T& get(const JS::Heap<T>& v) { return v.unbarrieredGet(); }
1413 };
1414 
1415 template <typename T>
1416 struct DefineComparisonOps<JS::TenuredHeap<T>> : mozilla::TrueType {
1417   static const T get(const JS::TenuredHeap<T>& v) {
1418     return v.unbarrieredGetPtr();
1419   }
1420 };
1421 
1422 template <>
1423 struct DefineComparisonOps<JS::ObjectPtr> : mozilla::TrueType {
1424   static const JSObject* get(const JS::ObjectPtr& v) {
1425     return v.unbarrieredGet();
1426   }
1427 };
1428 
1429 template <typename T>
1430 struct DefineComparisonOps<JS::Rooted<T>> : mozilla::TrueType {
1431   static const T& get(const JS::Rooted<T>& v) { return v.get(); }
1432 };
1433 
1434 template <typename T>
1435 struct DefineComparisonOps<JS::Handle<T>> : mozilla::TrueType {
1436   static const T& get(const JS::Handle<T>& v) { return v.get(); }
1437 };
1438 
1439 template <typename T>
1440 struct DefineComparisonOps<JS::MutableHandle<T>> : mozilla::TrueType {
1441   static const T& get(const JS::MutableHandle<T>& v) { return v.get(); }
1442 };
1443 
1444 template <typename T>
1445 struct DefineComparisonOps<JS::PersistentRooted<T>> : mozilla::TrueType {
1446   static const T& get(const JS::PersistentRooted<T>& v) { return v.get(); }
1447 };
1448 
1449 template <typename T>
1450 struct DefineComparisonOps<js::FakeRooted<T>> : mozilla::TrueType {
1451   static const T& get(const js::FakeRooted<T>& v) { return v.get(); }
1452 };
1453 
1454 template <typename T>
1455 struct DefineComparisonOps<js::FakeMutableHandle<T>> : mozilla::TrueType {
1456   static const T& get(const js::FakeMutableHandle<T>& v) { return v.get(); }
1457 };
1458 
1459 } /* namespace detail */
1460 } /* namespace js */
1461 
1462 // Overload operator== and operator!= for all types with the DefineComparisonOps
1463 // trait using the supplied getter.
1464 //
1465 // There are four cases:
1466 
1467 // Case 1: comparison between two wrapper objects.
1468 
1469 template <typename T, typename U>
1470 typename mozilla::EnableIf<js::detail::DefineComparisonOps<T>::value &&
1471                                js::detail::DefineComparisonOps<U>::value,
1472                            bool>::Type
1473 operator==(const T& a, const U& b) {
1474   return js::detail::DefineComparisonOps<T>::get(a) ==
1475          js::detail::DefineComparisonOps<U>::get(b);
1476 }
1477 
1478 template <typename T, typename U>
1479 typename mozilla::EnableIf<js::detail::DefineComparisonOps<T>::value &&
1480                                js::detail::DefineComparisonOps<U>::value,
1481                            bool>::Type
1482 operator!=(const T& a, const U& b) {
1483   return !(a == b);
1484 }
1485 
1486 // Case 2: comparison between a wrapper object and its unwrapped element type.
1487 
1488 template <typename T>
1489 typename mozilla::EnableIf<js::detail::DefineComparisonOps<T>::value,
1490                            bool>::Type
1491 operator==(const T& a, const typename T::ElementType& b) {
1492   return js::detail::DefineComparisonOps<T>::get(a) == b;
1493 }
1494 
1495 template <typename T>
1496 typename mozilla::EnableIf<js::detail::DefineComparisonOps<T>::value,
1497                            bool>::Type
1498 operator!=(const T& a, const typename T::ElementType& b) {
1499   return !(a == b);
1500 }
1501 
1502 template <typename T>
1503 typename mozilla::EnableIf<js::detail::DefineComparisonOps<T>::value,
1504                            bool>::Type
1505 operator==(const typename T::ElementType& a, const T& b) {
1506   return a == js::detail::DefineComparisonOps<T>::get(b);
1507 }
1508 
1509 template <typename T>
1510 typename mozilla::EnableIf<js::detail::DefineComparisonOps<T>::value,
1511                            bool>::Type
1512 operator!=(const typename T::ElementType& a, const T& b) {
1513   return !(a == b);
1514 }
1515 
1516 // Case 3: For pointer wrappers, comparison between the wrapper and a const
1517 // element pointer.
1518 
1519 template <typename T>
1520 typename mozilla::EnableIf<
1521     js::detail::DefineComparisonOps<T>::value &&
1522         mozilla::IsPointer<typename T::ElementType>::value,
1523     bool>::Type
1524 operator==(
1525     const typename mozilla::RemovePointer<typename T::ElementType>::Type* a,
1526     const T& b) {
1527   return a == js::detail::DefineComparisonOps<T>::get(b);
1528 }
1529 
1530 template <typename T>
1531 typename mozilla::EnableIf<
1532     js::detail::DefineComparisonOps<T>::value &&
1533         mozilla::IsPointer<typename T::ElementType>::value,
1534     bool>::Type
1535 operator!=(
1536     const typename mozilla::RemovePointer<typename T::ElementType>::Type* a,
1537     const T& b) {
1538   return !(a == b);
1539 }
1540 
1541 template <typename T>
1542 typename mozilla::EnableIf<
1543     js::detail::DefineComparisonOps<T>::value &&
1544         mozilla::IsPointer<typename T::ElementType>::value,
1545     bool>::Type
1546 operator==(
1547     const T& a,
1548     const typename mozilla::RemovePointer<typename T::ElementType>::Type* b) {
1549   return js::detail::DefineComparisonOps<T>::get(a) == b;
1550 }
1551 
1552 template <typename T>
1553 typename mozilla::EnableIf<
1554     js::detail::DefineComparisonOps<T>::value &&
1555         mozilla::IsPointer<typename T::ElementType>::value,
1556     bool>::Type
1557 operator!=(
1558     const T& a,
1559     const typename mozilla::RemovePointer<typename T::ElementType>::Type* b) {
1560   return !(a == b);
1561 }
1562 
1563 // Case 4: For pointer wrappers, comparison between the wrapper and nullptr.
1564 
1565 template <typename T>
1566 typename mozilla::EnableIf<
1567     js::detail::DefineComparisonOps<T>::value &&
1568         mozilla::IsPointer<typename T::ElementType>::value,
1569     bool>::Type
1570 operator==(std::nullptr_t a, const T& b) {
1571   return a == js::detail::DefineComparisonOps<T>::get(b);
1572 }
1573 
1574 template <typename T>
1575 typename mozilla::EnableIf<
1576     js::detail::DefineComparisonOps<T>::value &&
1577         mozilla::IsPointer<typename T::ElementType>::value,
1578     bool>::Type
1579 operator!=(std::nullptr_t a, const T& b) {
1580   return !(a == b);
1581 }
1582 
1583 template <typename T>
1584 typename mozilla::EnableIf<
1585     js::detail::DefineComparisonOps<T>::value &&
1586         mozilla::IsPointer<typename T::ElementType>::value,
1587     bool>::Type
1588 operator==(const T& a, std::nullptr_t b) {
1589   return js::detail::DefineComparisonOps<T>::get(a) == b;
1590 }
1591 
1592 template <typename T>
1593 typename mozilla::EnableIf<
1594     js::detail::DefineComparisonOps<T>::value &&
1595         mozilla::IsPointer<typename T::ElementType>::value,
1596     bool>::Type
1597 operator!=(const T& a, std::nullptr_t b) {
1598   return !(a == b);
1599 }
1600 
1601 #endif /* js_RootingAPI_h */
1602