RootingAPI.h 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  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. #ifndef js_RootingAPI_h
  7. #define js_RootingAPI_h
  8. #include "mozilla/Attributes.h"
  9. #include "mozilla/DebugOnly.h"
  10. #include "mozilla/GuardObjects.h"
  11. #include "mozilla/LinkedList.h"
  12. #include "mozilla/Move.h"
  13. #include "mozilla/TypeTraits.h"
  14. #include <type_traits>
  15. #include "jspubtd.h"
  16. #include "js/GCAnnotations.h"
  17. #include "js/GCAPI.h"
  18. #include "js/GCPolicyAPI.h"
  19. #include "js/HeapAPI.h"
  20. #include "js/TypeDecls.h"
  21. #include "js/UniquePtr.h"
  22. #include "js/Utility.h"
  23. /*
  24. * Moving GC Stack Rooting
  25. *
  26. * A moving GC may change the physical location of GC allocated things, even
  27. * when they are rooted, updating all pointers to the thing to refer to its new
  28. * location. The GC must therefore know about all live pointers to a thing,
  29. * not just one of them, in order to behave correctly.
  30. *
  31. * The |Rooted| and |Handle| classes below are used to root stack locations
  32. * whose value may be held live across a call that can trigger GC. For a
  33. * code fragment such as:
  34. *
  35. * JSObject* obj = NewObject(cx);
  36. * DoSomething(cx);
  37. * ... = obj->lastProperty();
  38. *
  39. * If |DoSomething()| can trigger a GC, the stack location of |obj| must be
  40. * rooted to ensure that the GC does not move the JSObject referred to by
  41. * |obj| without updating |obj|'s location itself. This rooting must happen
  42. * regardless of whether there are other roots which ensure that the object
  43. * itself will not be collected.
  44. *
  45. * If |DoSomething()| cannot trigger a GC, and the same holds for all other
  46. * calls made between |obj|'s definitions and its last uses, then no rooting
  47. * is required.
  48. *
  49. * SpiderMonkey can trigger a GC at almost any time and in ways that are not
  50. * always clear. For example, the following innocuous-looking actions can
  51. * cause a GC: allocation of any new GC thing; JSObject::hasProperty;
  52. * JS_ReportError and friends; and ToNumber, among many others. The following
  53. * dangerous-looking actions cannot trigger a GC: js_malloc, cx->malloc_,
  54. * rt->malloc_, and friends and JS_ReportOutOfMemory.
  55. *
  56. * The following family of three classes will exactly root a stack location.
  57. * Incorrect usage of these classes will result in a compile error in almost
  58. * all cases. Therefore, it is very hard to be incorrectly rooted if you use
  59. * these classes exclusively. These classes are all templated on the type T of
  60. * the value being rooted.
  61. *
  62. * - Rooted<T> declares a variable of type T, whose value is always rooted.
  63. * Rooted<T> may be automatically coerced to a Handle<T>, below. Rooted<T>
  64. * should be used whenever a local variable's value may be held live across a
  65. * call which can trigger a GC.
  66. *
  67. * - Handle<T> is a const reference to a Rooted<T>. Functions which take GC
  68. * things or values as arguments and need to root those arguments should
  69. * generally use handles for those arguments and avoid any explicit rooting.
  70. * This has two benefits. First, when several such functions call each other
  71. * then redundant rooting of multiple copies of the GC thing can be avoided.
  72. * Second, if the caller does not pass a rooted value a compile error will be
  73. * generated, which is quicker and easier to fix than when relying on a
  74. * separate rooting analysis.
  75. *
  76. * - MutableHandle<T> is a non-const reference to Rooted<T>. It is used in the
  77. * same way as Handle<T> and includes a |set(const T& v)| method to allow
  78. * updating the value of the referenced Rooted<T>. A MutableHandle<T> can be
  79. * created with an implicit cast from a Rooted<T>*.
  80. *
  81. * In some cases the small performance overhead of exact rooting (measured to
  82. * be a few nanoseconds on desktop) is too much. In these cases, try the
  83. * following:
  84. *
  85. * - Move all Rooted<T> above inner loops: this allows you to re-use the root
  86. * on each iteration of the loop.
  87. *
  88. * - Pass Handle<T> through your hot call stack to avoid re-rooting costs at
  89. * every invocation.
  90. *
  91. * The following diagram explains the list of supported, implicit type
  92. * conversions between classes of this family:
  93. *
  94. * Rooted<T> ----> Handle<T>
  95. * | ^
  96. * | |
  97. * | |
  98. * +---> MutableHandle<T>
  99. * (via &)
  100. *
  101. * All of these types have an implicit conversion to raw pointers.
  102. */
  103. namespace js {
  104. template <typename T>
  105. struct BarrierMethods {
  106. };
  107. template <typename T>
  108. class RootedBase {};
  109. template <typename T>
  110. class HandleBase {};
  111. template <typename T>
  112. class MutableHandleBase {};
  113. template <typename T>
  114. class HeapBase {};
  115. // Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope
  116. template <typename T> struct IsHeapConstructibleType { static constexpr bool value = false; };
  117. #define DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE(T) \
  118. template <> struct IsHeapConstructibleType<T> { static constexpr bool value = true; };
  119. FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
  120. FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
  121. #undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE
  122. template <typename T>
  123. class PersistentRootedBase {};
  124. static void* const ConstNullValue = nullptr;
  125. namespace gc {
  126. struct Cell;
  127. template<typename T>
  128. struct PersistentRootedMarker;
  129. } /* namespace gc */
  130. #define DECLARE_POINTER_COMPARISON_OPS(T) \
  131. bool operator==(const T& other) const { return get() == other; } \
  132. bool operator!=(const T& other) const { return get() != other; }
  133. // Important: Return a reference so passing a Rooted<T>, etc. to
  134. // something that takes a |const T&| is not a GC hazard.
  135. #define DECLARE_POINTER_CONSTREF_OPS(T) \
  136. operator const T&() const { return get(); } \
  137. const T& operator->() const { return get(); }
  138. // Assignment operators on a base class are hidden by the implicitly defined
  139. // operator= on the derived class. Thus, define the operator= directly on the
  140. // class as we would need to manually pass it through anyway.
  141. #define DECLARE_POINTER_ASSIGN_OPS(Wrapper, T) \
  142. Wrapper<T>& operator=(const T& p) { \
  143. set(p); \
  144. return *this; \
  145. } \
  146. Wrapper<T>& operator=(const Wrapper<T>& other) { \
  147. set(other.get()); \
  148. return *this; \
  149. } \
  150. #define DELETE_ASSIGNMENT_OPS(Wrapper, T) \
  151. template <typename S> Wrapper<T>& operator=(S) = delete; \
  152. Wrapper<T>& operator=(const Wrapper<T>&) = delete;
  153. #define DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr) \
  154. const T* address() const { return &(ptr); } \
  155. const T& get() const { return (ptr); } \
  156. #define DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr) \
  157. T* address() { return &(ptr); } \
  158. T& get() { return (ptr); } \
  159. } /* namespace js */
  160. namespace JS {
  161. template <typename T> class Rooted;
  162. template <typename T> class PersistentRooted;
  163. /* This is exposing internal state of the GC for inlining purposes. */
  164. JS_FRIEND_API(bool) isGCEnabled();
  165. JS_FRIEND_API(void) HeapObjectPostBarrier(JSObject** objp, JSObject* prev, JSObject* next);
  166. #ifdef JS_DEBUG
  167. /**
  168. * For generational GC, assert that an object is in the tenured generation as
  169. * opposed to being in the nursery.
  170. */
  171. extern JS_FRIEND_API(void)
  172. AssertGCThingMustBeTenured(JSObject* obj);
  173. extern JS_FRIEND_API(void)
  174. AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell);
  175. #else
  176. inline void
  177. AssertGCThingMustBeTenured(JSObject* obj) {}
  178. inline void
  179. AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell) {}
  180. #endif
  181. /**
  182. * The Heap<T> class is a heap-stored reference to a JS GC thing. All members of
  183. * heap classes that refer to GC things should use Heap<T> (or possibly
  184. * TenuredHeap<T>, described below).
  185. *
  186. * Heap<T> is an abstraction that hides some of the complexity required to
  187. * maintain GC invariants for the contained reference. It uses operator
  188. * overloading to provide a normal pointer interface, but notifies the GC every
  189. * time the value it contains is updated. This is necessary for generational GC,
  190. * which keeps track of all pointers into the nursery.
  191. *
  192. * Heap<T> instances must be traced when their containing object is traced to
  193. * keep the pointed-to GC thing alive.
  194. *
  195. * Heap<T> objects should only be used on the heap. GC references stored on the
  196. * C/C++ stack must use Rooted/Handle/MutableHandle instead.
  197. *
  198. * Type T must be a public GC pointer type.
  199. */
  200. template <typename T>
  201. class Heap : public js::HeapBase<T>
  202. {
  203. // Please note: this can actually also be used by nsXBLMaybeCompiled<T>, for legacy reasons.
  204. static_assert(js::IsHeapConstructibleType<T>::value,
  205. "Type T must be a public GC pointer type");
  206. public:
  207. Heap() {
  208. static_assert(sizeof(T) == sizeof(Heap<T>),
  209. "Heap<T> must be binary compatible with T.");
  210. init(GCPolicy<T>::initial());
  211. }
  212. explicit Heap(const T& p) { init(p); }
  213. /*
  214. * For Heap, move semantics are equivalent to copy semantics. In C++, a
  215. * copy constructor taking const-ref is the way to get a single function
  216. * that will be used for both lvalue and rvalue copies, so we can simply
  217. * omit the rvalue variant.
  218. */
  219. explicit Heap(const Heap<T>& p) { init(p.ptr); }
  220. ~Heap() {
  221. post(ptr, GCPolicy<T>::initial());
  222. }
  223. DECLARE_POINTER_CONSTREF_OPS(T);
  224. DECLARE_POINTER_ASSIGN_OPS(Heap, T);
  225. const T* address() const { return &ptr; }
  226. void exposeToActiveJS() const {
  227. js::BarrierMethods<T>::exposeToJS(ptr);
  228. }
  229. const T& get() const {
  230. exposeToActiveJS();
  231. return ptr;
  232. }
  233. const T& unbarrieredGet() const {
  234. return ptr;
  235. }
  236. T* unsafeGet() { return &ptr; }
  237. explicit operator bool() const {
  238. return bool(js::BarrierMethods<T>::asGCThingOrNull(ptr));
  239. }
  240. explicit operator bool() {
  241. return bool(js::BarrierMethods<T>::asGCThingOrNull(ptr));
  242. }
  243. private:
  244. void init(const T& newPtr) {
  245. ptr = newPtr;
  246. post(GCPolicy<T>::initial(), ptr);
  247. }
  248. void set(const T& newPtr) {
  249. T tmp = ptr;
  250. ptr = newPtr;
  251. post(tmp, ptr);
  252. }
  253. void post(const T& prev, const T& next) {
  254. js::BarrierMethods<T>::postBarrier(&ptr, prev, next);
  255. }
  256. T ptr;
  257. };
  258. static MOZ_ALWAYS_INLINE bool
  259. ObjectIsTenured(JSObject* obj)
  260. {
  261. return !js::gc::IsInsideNursery(reinterpret_cast<js::gc::Cell*>(obj));
  262. }
  263. static MOZ_ALWAYS_INLINE bool
  264. ObjectIsTenured(const Heap<JSObject*>& obj)
  265. {
  266. return ObjectIsTenured(obj.unbarrieredGet());
  267. }
  268. static MOZ_ALWAYS_INLINE bool
  269. ObjectIsMarkedGray(JSObject* obj)
  270. {
  271. auto cell = reinterpret_cast<js::gc::Cell*>(obj);
  272. return js::gc::detail::CellIsMarkedGrayIfKnown(cell);
  273. }
  274. static MOZ_ALWAYS_INLINE bool
  275. ObjectIsMarkedGray(const JS::Heap<JSObject*>& obj)
  276. {
  277. return ObjectIsMarkedGray(obj.unbarrieredGet());
  278. }
  279. static MOZ_ALWAYS_INLINE bool
  280. ScriptIsMarkedGray(JSScript* script)
  281. {
  282. auto cell = reinterpret_cast<js::gc::Cell*>(script);
  283. return js::gc::detail::CellIsMarkedGrayIfKnown(cell);
  284. }
  285. static MOZ_ALWAYS_INLINE bool
  286. ScriptIsMarkedGray(const Heap<JSScript*>& script)
  287. {
  288. return ScriptIsMarkedGray(script.unbarrieredGet());
  289. }
  290. /**
  291. * The TenuredHeap<T> class is similar to the Heap<T> class above in that it
  292. * encapsulates the GC concerns of an on-heap reference to a JS object. However,
  293. * it has two important differences:
  294. *
  295. * 1) Pointers which are statically known to only reference "tenured" objects
  296. * can avoid the extra overhead of SpiderMonkey's write barriers.
  297. *
  298. * 2) Objects in the "tenured" heap have stronger alignment restrictions than
  299. * those in the "nursery", so it is possible to store flags in the lower
  300. * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged
  301. * pointer with a nice API for accessing the flag bits and adds various
  302. * assertions to ensure that it is not mis-used.
  303. *
  304. * GC things are said to be "tenured" when they are located in the long-lived
  305. * heap: e.g. they have gained tenure as an object by surviving past at least
  306. * one GC. For performance, SpiderMonkey allocates some things which are known
  307. * to normally be long lived directly into the tenured generation; for example,
  308. * global objects. Additionally, SpiderMonkey does not visit individual objects
  309. * when deleting non-tenured objects, so object with finalizers are also always
  310. * tenured; for instance, this includes most DOM objects.
  311. *
  312. * The considerations to keep in mind when using a TenuredHeap<T> vs a normal
  313. * Heap<T> are:
  314. *
  315. * - It is invalid for a TenuredHeap<T> to refer to a non-tenured thing.
  316. * - It is however valid for a Heap<T> to refer to a tenured thing.
  317. * - It is not possible to store flag bits in a Heap<T>.
  318. */
  319. template <typename T>
  320. class TenuredHeap : public js::HeapBase<T>
  321. {
  322. public:
  323. TenuredHeap() : bits(0) {
  324. static_assert(sizeof(T) == sizeof(TenuredHeap<T>),
  325. "TenuredHeap<T> must be binary compatible with T.");
  326. }
  327. explicit TenuredHeap(T p) : bits(0) { setPtr(p); }
  328. explicit TenuredHeap(const TenuredHeap<T>& p) : bits(0) { setPtr(p.getPtr()); }
  329. bool operator==(const TenuredHeap<T>& other) { return bits == other.bits; }
  330. bool operator!=(const TenuredHeap<T>& other) { return bits != other.bits; }
  331. void setPtr(T newPtr) {
  332. MOZ_ASSERT((reinterpret_cast<uintptr_t>(newPtr) & flagsMask) == 0);
  333. if (newPtr)
  334. AssertGCThingMustBeTenured(newPtr);
  335. bits = (bits & flagsMask) | reinterpret_cast<uintptr_t>(newPtr);
  336. }
  337. void setFlags(uintptr_t flagsToSet) {
  338. MOZ_ASSERT((flagsToSet & ~flagsMask) == 0);
  339. bits |= flagsToSet;
  340. }
  341. void unsetFlags(uintptr_t flagsToUnset) {
  342. MOZ_ASSERT((flagsToUnset & ~flagsMask) == 0);
  343. bits &= ~flagsToUnset;
  344. }
  345. bool hasFlag(uintptr_t flag) const {
  346. MOZ_ASSERT((flag & ~flagsMask) == 0);
  347. return (bits & flag) != 0;
  348. }
  349. T unbarrieredGetPtr() const { return reinterpret_cast<T>(bits & ~flagsMask); }
  350. uintptr_t getFlags() const { return bits & flagsMask; }
  351. void exposeToActiveJS() const {
  352. js::BarrierMethods<T>::exposeToJS(unbarrieredGetPtr());
  353. }
  354. T getPtr() const {
  355. exposeToActiveJS();
  356. return unbarrieredGetPtr();
  357. }
  358. operator T() const { return getPtr(); }
  359. T operator->() const { return getPtr(); }
  360. explicit operator bool() const {
  361. return bool(js::BarrierMethods<T>::asGCThingOrNull(unbarrieredGetPtr()));
  362. }
  363. explicit operator bool() {
  364. return bool(js::BarrierMethods<T>::asGCThingOrNull(unbarrieredGetPtr()));
  365. }
  366. TenuredHeap<T>& operator=(T p) {
  367. setPtr(p);
  368. return *this;
  369. }
  370. TenuredHeap<T>& operator=(const TenuredHeap<T>& other) {
  371. bits = other.bits;
  372. return *this;
  373. }
  374. private:
  375. enum {
  376. maskBits = 3,
  377. flagsMask = (1 << maskBits) - 1,
  378. };
  379. uintptr_t bits;
  380. };
  381. /**
  382. * Reference to a T that has been rooted elsewhere. This is most useful
  383. * as a parameter type, which guarantees that the T lvalue is properly
  384. * rooted. See "Move GC Stack Rooting" above.
  385. *
  386. * If you want to add additional methods to Handle for a specific
  387. * specialization, define a HandleBase<T> specialization containing them.
  388. */
  389. template <typename T>
  390. class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
  391. {
  392. friend class JS::MutableHandle<T>;
  393. public:
  394. /* Creates a handle from a handle of a type convertible to T. */
  395. template <typename S>
  396. MOZ_IMPLICIT Handle(Handle<S> handle,
  397. typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
  398. {
  399. static_assert(sizeof(Handle<T>) == sizeof(T*),
  400. "Handle must be binary compatible with T*.");
  401. ptr = reinterpret_cast<const T*>(handle.address());
  402. }
  403. MOZ_IMPLICIT Handle(decltype(nullptr)) {
  404. static_assert(mozilla::IsPointer<T>::value,
  405. "nullptr_t overload not valid for non-pointer types");
  406. ptr = reinterpret_cast<const T*>(&js::ConstNullValue);
  407. }
  408. MOZ_IMPLICIT Handle(MutableHandle<T> handle) {
  409. ptr = handle.address();
  410. }
  411. /*
  412. * Take care when calling this method!
  413. *
  414. * This creates a Handle from the raw location of a T.
  415. *
  416. * It should be called only if the following conditions hold:
  417. *
  418. * 1) the location of the T is guaranteed to be marked (for some reason
  419. * other than being a Rooted), e.g., if it is guaranteed to be reachable
  420. * from an implicit root.
  421. *
  422. * 2) the contents of the location are immutable, or at least cannot change
  423. * for the lifetime of the handle, as its users may not expect its value
  424. * to change underneath them.
  425. */
  426. static constexpr Handle fromMarkedLocation(const T* p) {
  427. return Handle(p, DeliberatelyChoosingThisOverload,
  428. ImUsingThisOnlyInFromFromMarkedLocation);
  429. }
  430. /*
  431. * Construct a handle from an explicitly rooted location. This is the
  432. * normal way to create a handle, and normally happens implicitly.
  433. */
  434. template <typename S>
  435. inline
  436. MOZ_IMPLICIT Handle(const Rooted<S>& root,
  437. typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
  438. template <typename S>
  439. inline
  440. MOZ_IMPLICIT Handle(const PersistentRooted<S>& root,
  441. typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
  442. /* Construct a read only handle from a mutable handle. */
  443. template <typename S>
  444. inline
  445. MOZ_IMPLICIT Handle(MutableHandle<S>& root,
  446. typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
  447. DECLARE_POINTER_COMPARISON_OPS(T);
  448. DECLARE_POINTER_CONSTREF_OPS(T);
  449. DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr);
  450. private:
  451. Handle() {}
  452. DELETE_ASSIGNMENT_OPS(Handle, T);
  453. enum Disambiguator { DeliberatelyChoosingThisOverload = 42 };
  454. enum CallerIdentity { ImUsingThisOnlyInFromFromMarkedLocation = 17 };
  455. constexpr Handle(const T* p, Disambiguator, CallerIdentity) : ptr(p) {}
  456. const T* ptr;
  457. };
  458. /**
  459. * Similar to a handle, but the underlying storage can be changed. This is
  460. * useful for outparams.
  461. *
  462. * If you want to add additional methods to MutableHandle for a specific
  463. * specialization, define a MutableHandleBase<T> specialization containing
  464. * them.
  465. */
  466. template <typename T>
  467. class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
  468. {
  469. public:
  470. inline MOZ_IMPLICIT MutableHandle(Rooted<T>* root);
  471. inline MOZ_IMPLICIT MutableHandle(PersistentRooted<T>* root);
  472. private:
  473. // Disallow nullptr for overloading purposes.
  474. MutableHandle(decltype(nullptr)) = delete;
  475. public:
  476. void set(const T& v) {
  477. *ptr = v;
  478. }
  479. /*
  480. * This may be called only if the location of the T is guaranteed
  481. * to be marked (for some reason other than being a Rooted),
  482. * e.g., if it is guaranteed to be reachable from an implicit root.
  483. *
  484. * Create a MutableHandle from a raw location of a T.
  485. */
  486. static MutableHandle fromMarkedLocation(T* p) {
  487. MutableHandle h;
  488. h.ptr = p;
  489. return h;
  490. }
  491. DECLARE_POINTER_CONSTREF_OPS(T);
  492. DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr);
  493. DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr);
  494. private:
  495. MutableHandle() {}
  496. DELETE_ASSIGNMENT_OPS(MutableHandle, T);
  497. T* ptr;
  498. };
  499. } /* namespace JS */
  500. namespace js {
  501. template <typename T>
  502. struct BarrierMethods<T*>
  503. {
  504. static T* initial() { return nullptr; }
  505. static gc::Cell* asGCThingOrNull(T* v) {
  506. if (!v)
  507. return nullptr;
  508. MOZ_ASSERT(uintptr_t(v) > 32);
  509. return reinterpret_cast<gc::Cell*>(v);
  510. }
  511. static void postBarrier(T** vp, T* prev, T* next) {
  512. if (next)
  513. JS::AssertGCThingIsNotAnObjectSubclass(reinterpret_cast<js::gc::Cell*>(next));
  514. }
  515. static void exposeToJS(T* t) {
  516. if (t)
  517. js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(t));
  518. }
  519. };
  520. template <>
  521. struct BarrierMethods<JSObject*>
  522. {
  523. static JSObject* initial() { return nullptr; }
  524. static gc::Cell* asGCThingOrNull(JSObject* v) {
  525. if (!v)
  526. return nullptr;
  527. MOZ_ASSERT(uintptr_t(v) > 32);
  528. return reinterpret_cast<gc::Cell*>(v);
  529. }
  530. static void postBarrier(JSObject** vp, JSObject* prev, JSObject* next) {
  531. JS::HeapObjectPostBarrier(vp, prev, next);
  532. }
  533. static void exposeToJS(JSObject* obj) {
  534. if (obj)
  535. JS::ExposeObjectToActiveJS(obj);
  536. }
  537. };
  538. template <>
  539. struct BarrierMethods<JSFunction*>
  540. {
  541. static JSFunction* initial() { return nullptr; }
  542. static gc::Cell* asGCThingOrNull(JSFunction* v) {
  543. if (!v)
  544. return nullptr;
  545. MOZ_ASSERT(uintptr_t(v) > 32);
  546. return reinterpret_cast<gc::Cell*>(v);
  547. }
  548. static void postBarrier(JSFunction** vp, JSFunction* prev, JSFunction* next) {
  549. JS::HeapObjectPostBarrier(reinterpret_cast<JSObject**>(vp),
  550. reinterpret_cast<JSObject*>(prev),
  551. reinterpret_cast<JSObject*>(next));
  552. }
  553. static void exposeToJS(JSFunction* fun) {
  554. if (fun)
  555. JS::ExposeObjectToActiveJS(reinterpret_cast<JSObject*>(fun));
  556. }
  557. };
  558. // Provide hash codes for Cell kinds that may be relocated and, thus, not have
  559. // a stable address to use as the base for a hash code. Instead of the address,
  560. // this hasher uses Cell::getUniqueId to provide exact matches and as a base
  561. // for generating hash codes.
  562. //
  563. // Note: this hasher, like PointerHasher can "hash" a nullptr. While a nullptr
  564. // would not likely be a useful key, there are some cases where being able to
  565. // hash a nullptr is useful, either on purpose or because of bugs:
  566. // (1) existence checks where the key may happen to be null and (2) some
  567. // aggregate Lookup kinds embed a JSObject* that is frequently null and do not
  568. // null test before dispatching to the hasher.
  569. template <typename T>
  570. struct JS_PUBLIC_API(MovableCellHasher)
  571. {
  572. using Key = T;
  573. using Lookup = T;
  574. static bool hasHash(const Lookup& l);
  575. static bool ensureHash(const Lookup& l);
  576. static HashNumber hash(const Lookup& l);
  577. static bool match(const Key& k, const Lookup& l);
  578. static void rekey(Key& k, const Key& newKey) { k = newKey; }
  579. };
  580. template <typename T>
  581. struct JS_PUBLIC_API(MovableCellHasher<JS::Heap<T>>)
  582. {
  583. using Key = JS::Heap<T>;
  584. using Lookup = T;
  585. static bool hasHash(const Lookup& l) { return MovableCellHasher<T>::hasHash(l); }
  586. static bool ensureHash(const Lookup& l) { return MovableCellHasher<T>::ensureHash(l); }
  587. static HashNumber hash(const Lookup& l) { return MovableCellHasher<T>::hash(l); }
  588. static bool match(const Key& k, const Lookup& l) {
  589. return MovableCellHasher<T>::match(k.unbarrieredGet(), l);
  590. }
  591. static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); }
  592. };
  593. template <typename T>
  594. struct FallibleHashMethods<MovableCellHasher<T>>
  595. {
  596. template <typename Lookup> static bool hasHash(Lookup&& l) {
  597. return MovableCellHasher<T>::hasHash(mozilla::Forward<Lookup>(l));
  598. }
  599. template <typename Lookup> static bool ensureHash(Lookup&& l) {
  600. return MovableCellHasher<T>::ensureHash(mozilla::Forward<Lookup>(l));
  601. }
  602. };
  603. } /* namespace js */
  604. namespace js {
  605. // The alignment must be set because the Rooted and PersistentRooted ptr fields
  606. // may be accessed through reinterpret_cast<Rooted<ConcreteTraceable>*>, and
  607. // the compiler may choose a different alignment for the ptr field when it
  608. // knows the actual type stored in DispatchWrapper<T>.
  609. //
  610. // It would make more sense to align only those specific fields of type
  611. // DispatchWrapper, rather than DispatchWrapper itself, but that causes MSVC to
  612. // fail when Rooted is used in an IsConvertible test.
  613. template <typename T>
  614. class alignas(8) DispatchWrapper
  615. {
  616. static_assert(JS::MapTypeToRootKind<T>::kind == JS::RootKind::Traceable,
  617. "DispatchWrapper is intended only for usage with a Traceable");
  618. using TraceFn = void (*)(JSTracer*, T*, const char*);
  619. TraceFn tracer;
  620. alignas(gc::CellSize) T storage;
  621. public:
  622. template <typename U>
  623. MOZ_IMPLICIT DispatchWrapper(U&& initial)
  624. : tracer(&JS::GCPolicy<T>::trace),
  625. storage(mozilla::Forward<U>(initial))
  626. { }
  627. // Mimic a pointer type, so that we can drop into Rooted.
  628. T* operator &() { return &storage; }
  629. const T* operator &() const { return &storage; }
  630. operator T&() { return storage; }
  631. operator const T&() const { return storage; }
  632. // Trace the contained storage (of unknown type) using the trace function
  633. // we set aside when we did know the type.
  634. static void TraceWrapped(JSTracer* trc, T* thingp, const char* name) {
  635. auto wrapper = reinterpret_cast<DispatchWrapper*>(
  636. uintptr_t(thingp) - offsetof(DispatchWrapper, storage));
  637. wrapper->tracer(trc, &wrapper->storage, name);
  638. }
  639. };
  640. } /* namespace js */
  641. namespace JS {
  642. /**
  643. * Local variable of type T whose value is always rooted. This is typically
  644. * used for local variables, or for non-rooted values being passed to a
  645. * function that requires a handle, e.g. Foo(Root<T>(cx, x)).
  646. *
  647. * If you want to add additional methods to Rooted for a specific
  648. * specialization, define a RootedBase<T> specialization containing them.
  649. */
  650. template <typename T>
  651. class MOZ_RAII Rooted : public js::RootedBase<T>
  652. {
  653. inline void registerWithRootLists(js::RootedListHeads& roots) {
  654. this->stack = &roots[JS::MapTypeToRootKind<T>::kind];
  655. this->prev = *stack;
  656. *stack = reinterpret_cast<Rooted<void*>*>(this);
  657. }
  658. inline js::RootedListHeads& rootLists(JS::RootingContext* cx) {
  659. return rootLists(static_cast<js::ContextFriendFields*>(cx));
  660. }
  661. inline js::RootedListHeads& rootLists(js::ContextFriendFields* cx) {
  662. if (JS::Zone* zone = cx->zone_)
  663. return JS::shadow::Zone::asShadowZone(zone)->stackRoots_;
  664. MOZ_ASSERT(cx->isJSContext);
  665. return cx->roots.stackRoots_;
  666. }
  667. inline js::RootedListHeads& rootLists(JSContext* cx) {
  668. return rootLists(js::ContextFriendFields::get(cx));
  669. }
  670. public:
  671. template <typename RootingContext>
  672. explicit Rooted(const RootingContext& cx)
  673. : ptr(GCPolicy<T>::initial())
  674. {
  675. registerWithRootLists(rootLists(cx));
  676. }
  677. template <typename RootingContext, typename S>
  678. Rooted(const RootingContext& cx, S&& initial)
  679. : ptr(mozilla::Forward<S>(initial))
  680. {
  681. registerWithRootLists(rootLists(cx));
  682. }
  683. ~Rooted() {
  684. MOZ_ASSERT(*stack == reinterpret_cast<Rooted<void*>*>(this));
  685. *stack = prev;
  686. }
  687. Rooted<T>* previous() { return reinterpret_cast<Rooted<T>*>(prev); }
  688. /*
  689. * This method is public for Rooted so that Codegen.py can use a Rooted
  690. * interchangeably with a MutableHandleValue.
  691. */
  692. void set(const T& value) {
  693. ptr = value;
  694. }
  695. DECLARE_POINTER_COMPARISON_OPS(T);
  696. DECLARE_POINTER_CONSTREF_OPS(T);
  697. DECLARE_POINTER_ASSIGN_OPS(Rooted, T);
  698. DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
  699. DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr);
  700. private:
  701. /*
  702. * These need to be templated on void* to avoid aliasing issues between, for
  703. * example, Rooted<JSObject> and Rooted<JSFunction>, which use the same
  704. * stack head pointer for different classes.
  705. */
  706. Rooted<void*>** stack;
  707. Rooted<void*>* prev;
  708. /*
  709. * For pointer types, the TraceKind for tracing is based on the list it is
  710. * in (selected via MapTypeToRootKind), so no additional storage is
  711. * required here. Non-pointer types, however, share the same list, so the
  712. * function to call for tracing is stored adjacent to the struct. Since C++
  713. * cannot templatize on storage class, this is implemented via the wrapper
  714. * class DispatchWrapper.
  715. */
  716. using MaybeWrapped = typename mozilla::Conditional<
  717. MapTypeToRootKind<T>::kind == JS::RootKind::Traceable,
  718. js::DispatchWrapper<T>,
  719. T>::Type;
  720. MaybeWrapped ptr;
  721. Rooted(const Rooted&) = delete;
  722. } JS_HAZ_ROOTED;
  723. } /* namespace JS */
  724. namespace js {
  725. /**
  726. * Augment the generic Rooted<T> interface when T = JSObject* with
  727. * class-querying and downcasting operations.
  728. *
  729. * Given a Rooted<JSObject*> obj, one can view
  730. * Handle<StringObject*> h = obj.as<StringObject*>();
  731. * as an optimization of
  732. * Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
  733. * Handle<StringObject*> h = rooted;
  734. */
  735. template <>
  736. class RootedBase<JSObject*>
  737. {
  738. public:
  739. template <class U>
  740. JS::Handle<U*> as() const;
  741. };
  742. /**
  743. * Augment the generic Handle<T> interface when T = JSObject* with
  744. * downcasting operations.
  745. *
  746. * Given a Handle<JSObject*> obj, one can view
  747. * Handle<StringObject*> h = obj.as<StringObject*>();
  748. * as an optimization of
  749. * Rooted<StringObject*> rooted(cx, &obj->as<StringObject*>());
  750. * Handle<StringObject*> h = rooted;
  751. */
  752. template <>
  753. class HandleBase<JSObject*>
  754. {
  755. public:
  756. template <class U>
  757. JS::Handle<U*> as() const;
  758. };
  759. /** Interface substitute for Rooted<T> which does not root the variable's memory. */
  760. template <typename T>
  761. class MOZ_RAII FakeRooted : public RootedBase<T>
  762. {
  763. public:
  764. template <typename CX>
  765. explicit FakeRooted(CX* cx) : ptr(JS::GCPolicy<T>::initial()) {}
  766. template <typename CX>
  767. FakeRooted(CX* cx, T initial) : ptr(initial) {}
  768. DECLARE_POINTER_COMPARISON_OPS(T);
  769. DECLARE_POINTER_CONSTREF_OPS(T);
  770. DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T);
  771. DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
  772. DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr);
  773. private:
  774. T ptr;
  775. void set(const T& value) {
  776. ptr = value;
  777. }
  778. FakeRooted(const FakeRooted&) = delete;
  779. };
  780. /** Interface substitute for MutableHandle<T> which is not required to point to rooted memory. */
  781. template <typename T>
  782. class FakeMutableHandle : public js::MutableHandleBase<T>
  783. {
  784. public:
  785. MOZ_IMPLICIT FakeMutableHandle(T* t) {
  786. ptr = t;
  787. }
  788. MOZ_IMPLICIT FakeMutableHandle(FakeRooted<T>* root) {
  789. ptr = root->address();
  790. }
  791. void set(const T& v) {
  792. *ptr = v;
  793. }
  794. DECLARE_POINTER_CONSTREF_OPS(T);
  795. DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr);
  796. DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr);
  797. private:
  798. FakeMutableHandle() {}
  799. DELETE_ASSIGNMENT_OPS(FakeMutableHandle, T);
  800. T* ptr;
  801. };
  802. /**
  803. * Types for a variable that either should or shouldn't be rooted, depending on
  804. * the template parameter allowGC. Used for implementing functions that can
  805. * operate on either rooted or unrooted data.
  806. *
  807. * The toHandle() and toMutableHandle() functions are for calling functions
  808. * which require handle types and are only called in the CanGC case. These
  809. * allow the calling code to type check.
  810. */
  811. enum AllowGC {
  812. NoGC = 0,
  813. CanGC = 1
  814. };
  815. template <typename T, AllowGC allowGC>
  816. class MaybeRooted
  817. {
  818. };
  819. template <typename T> class MaybeRooted<T, CanGC>
  820. {
  821. public:
  822. typedef JS::Handle<T> HandleType;
  823. typedef JS::Rooted<T> RootType;
  824. typedef JS::MutableHandle<T> MutableHandleType;
  825. static inline JS::Handle<T> toHandle(HandleType v) {
  826. return v;
  827. }
  828. static inline JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
  829. return v;
  830. }
  831. template <typename T2>
  832. static inline JS::Handle<T2*> downcastHandle(HandleType v) {
  833. return v.template as<T2>();
  834. }
  835. };
  836. template <typename T> class MaybeRooted<T, NoGC>
  837. {
  838. public:
  839. typedef const T& HandleType;
  840. typedef FakeRooted<T> RootType;
  841. typedef FakeMutableHandle<T> MutableHandleType;
  842. static JS::Handle<T> toHandle(HandleType v) {
  843. MOZ_CRASH("Bad conversion");
  844. }
  845. static JS::MutableHandle<T> toMutableHandle(MutableHandleType v) {
  846. MOZ_CRASH("Bad conversion");
  847. }
  848. template <typename T2>
  849. static inline T2* downcastHandle(HandleType v) {
  850. return &v->template as<T2>();
  851. }
  852. };
  853. } /* namespace js */
  854. namespace JS {
  855. template <typename T> template <typename S>
  856. inline
  857. Handle<T>::Handle(const Rooted<S>& root,
  858. typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
  859. {
  860. ptr = reinterpret_cast<const T*>(root.address());
  861. }
  862. template <typename T> template <typename S>
  863. inline
  864. Handle<T>::Handle(const PersistentRooted<S>& root,
  865. typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
  866. {
  867. ptr = reinterpret_cast<const T*>(root.address());
  868. }
  869. template <typename T> template <typename S>
  870. inline
  871. Handle<T>::Handle(MutableHandle<S>& root,
  872. typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
  873. {
  874. ptr = reinterpret_cast<const T*>(root.address());
  875. }
  876. template <typename T>
  877. inline
  878. MutableHandle<T>::MutableHandle(Rooted<T>* root)
  879. {
  880. static_assert(sizeof(MutableHandle<T>) == sizeof(T*),
  881. "MutableHandle must be binary compatible with T*.");
  882. ptr = root->address();
  883. }
  884. template <typename T>
  885. inline
  886. MutableHandle<T>::MutableHandle(PersistentRooted<T>* root)
  887. {
  888. static_assert(sizeof(MutableHandle<T>) == sizeof(T*),
  889. "MutableHandle must be binary compatible with T*.");
  890. ptr = root->address();
  891. }
  892. /**
  893. * A copyable, assignable global GC root type with arbitrary lifetime, an
  894. * infallible constructor, and automatic unrooting on destruction.
  895. *
  896. * These roots can be used in heap-allocated data structures, so they are not
  897. * associated with any particular JSContext or stack. They are registered with
  898. * the JSRuntime itself, without locking, so they require a full JSContext to be
  899. * initialized, not one of its more restricted superclasses. Initialization may
  900. * take place on construction, or in two phases if the no-argument constructor
  901. * is called followed by init().
  902. *
  903. * Note that you must not use an PersistentRooted in an object owned by a JS
  904. * object:
  905. *
  906. * Whenever one object whose lifetime is decided by the GC refers to another
  907. * such object, that edge must be traced only if the owning JS object is traced.
  908. * This applies not only to JS objects (which obviously are managed by the GC)
  909. * but also to C++ objects owned by JS objects.
  910. *
  911. * If you put a PersistentRooted in such a C++ object, that is almost certainly
  912. * a leak. When a GC begins, the referent of the PersistentRooted is treated as
  913. * live, unconditionally (because a PersistentRooted is a *root*), even if the
  914. * JS object that owns it is unreachable. If there is any path from that
  915. * referent back to the JS object, then the C++ object containing the
  916. * PersistentRooted will not be destructed, and the whole blob of objects will
  917. * not be freed, even if there are no references to them from the outside.
  918. *
  919. * In the context of Firefox, this is a severe restriction: almost everything in
  920. * Firefox is owned by some JS object or another, so using PersistentRooted in
  921. * such objects would introduce leaks. For these kinds of edges, Heap<T> or
  922. * TenuredHeap<T> would be better types. It's up to the implementor of the type
  923. * containing Heap<T> or TenuredHeap<T> members to make sure their referents get
  924. * marked when the object itself is marked.
  925. */
  926. template<typename T>
  927. class PersistentRooted : public js::PersistentRootedBase<T>,
  928. private mozilla::LinkedListElement<PersistentRooted<T>>
  929. {
  930. using ListBase = mozilla::LinkedListElement<PersistentRooted<T>>;
  931. friend class mozilla::LinkedList<PersistentRooted>;
  932. friend class mozilla::LinkedListElement<PersistentRooted>;
  933. void registerWithRootLists(js::RootLists& roots) {
  934. MOZ_ASSERT(!initialized());
  935. JS::RootKind kind = JS::MapTypeToRootKind<T>::kind;
  936. roots.heapRoots_[kind].insertBack(reinterpret_cast<JS::PersistentRooted<void*>*>(this));
  937. }
  938. js::RootLists& rootLists(JSContext* cx) {
  939. return rootLists(JS::RootingContext::get(cx));
  940. }
  941. js::RootLists& rootLists(JS::RootingContext* cx) {
  942. MOZ_ASSERT(cx->isJSContext);
  943. return cx->roots;
  944. }
  945. // Disallow ExclusiveContext*.
  946. js::RootLists& rootLists(js::ContextFriendFields* cx) = delete;
  947. public:
  948. PersistentRooted() : ptr(GCPolicy<T>::initial()) {}
  949. template <typename RootingContext>
  950. explicit PersistentRooted(const RootingContext& cx)
  951. : ptr(GCPolicy<T>::initial())
  952. {
  953. registerWithRootLists(rootLists(cx));
  954. }
  955. template <typename RootingContext, typename U>
  956. PersistentRooted(const RootingContext& cx, U&& initial)
  957. : ptr(mozilla::Forward<U>(initial))
  958. {
  959. registerWithRootLists(rootLists(cx));
  960. }
  961. PersistentRooted(const PersistentRooted& rhs)
  962. : mozilla::LinkedListElement<PersistentRooted<T>>(),
  963. ptr(rhs.ptr)
  964. {
  965. /*
  966. * Copy construction takes advantage of the fact that the original
  967. * is already inserted, and simply adds itself to whatever list the
  968. * original was on - no JSRuntime pointer needed.
  969. *
  970. * This requires mutating rhs's links, but those should be 'mutable'
  971. * anyway. C++ doesn't let us declare mutable base classes.
  972. */
  973. const_cast<PersistentRooted&>(rhs).setNext(this);
  974. }
  975. bool initialized() {
  976. return ListBase::isInList();
  977. }
  978. template <typename RootingContext>
  979. void init(const RootingContext& cx) {
  980. init(cx, GCPolicy<T>::initial());
  981. }
  982. template <typename RootingContext, typename U>
  983. void init(const RootingContext& cx, U&& initial) {
  984. ptr = mozilla::Forward<U>(initial);
  985. registerWithRootLists(rootLists(cx));
  986. }
  987. void reset() {
  988. if (initialized()) {
  989. set(GCPolicy<T>::initial());
  990. ListBase::remove();
  991. }
  992. }
  993. DECLARE_POINTER_COMPARISON_OPS(T);
  994. DECLARE_POINTER_CONSTREF_OPS(T);
  995. DECLARE_POINTER_ASSIGN_OPS(PersistentRooted, T);
  996. DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
  997. // These are the same as DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS, except
  998. // they check that |this| is initialized in case the caller later stores
  999. // something in |ptr|.
  1000. T* address() {
  1001. MOZ_ASSERT(initialized());
  1002. return &ptr;
  1003. }
  1004. T& get() {
  1005. MOZ_ASSERT(initialized());
  1006. return ptr;
  1007. }
  1008. private:
  1009. template <typename U>
  1010. void set(U&& value) {
  1011. MOZ_ASSERT(initialized());
  1012. ptr = mozilla::Forward<U>(value);
  1013. }
  1014. // See the comment above Rooted::ptr.
  1015. using MaybeWrapped = typename mozilla::Conditional<
  1016. MapTypeToRootKind<T>::kind == JS::RootKind::Traceable,
  1017. js::DispatchWrapper<T>,
  1018. T>::Type;
  1019. MaybeWrapped ptr;
  1020. } JS_HAZ_ROOTED;
  1021. class JS_PUBLIC_API(ObjectPtr)
  1022. {
  1023. Heap<JSObject*> value;
  1024. public:
  1025. ObjectPtr() : value(nullptr) {}
  1026. explicit ObjectPtr(JSObject* obj) : value(obj) {}
  1027. /* Always call finalize before the destructor. */
  1028. ~ObjectPtr() { MOZ_ASSERT(!value); }
  1029. void finalize(JSRuntime* rt);
  1030. void finalize(JSContext* cx);
  1031. void init(JSObject* obj) { value = obj; }
  1032. JSObject* get() const { return value; }
  1033. JSObject* unbarrieredGet() const { return value.unbarrieredGet(); }
  1034. void writeBarrierPre(JSContext* cx) {
  1035. IncrementalObjectBarrier(value);
  1036. }
  1037. void updateWeakPointerAfterGC();
  1038. ObjectPtr& operator=(JSObject* obj) {
  1039. IncrementalObjectBarrier(value);
  1040. value = obj;
  1041. return *this;
  1042. }
  1043. void trace(JSTracer* trc, const char* name);
  1044. JSObject& operator*() const { return *value; }
  1045. JSObject* operator->() const { return value; }
  1046. operator JSObject*() const { return value; }
  1047. explicit operator bool() const { return value.unbarrieredGet(); }
  1048. explicit operator bool() { return value.unbarrieredGet(); }
  1049. };
  1050. } /* namespace JS */
  1051. namespace js {
  1052. template <typename Outer, typename T, typename D>
  1053. class UniquePtrOperations
  1054. {
  1055. const UniquePtr<T, D>& uniquePtr() const { return static_cast<const Outer*>(this)->get(); }
  1056. public:
  1057. explicit operator bool() const { return !!uniquePtr(); }
  1058. };
  1059. template <typename Outer, typename T, typename D>
  1060. class MutableUniquePtrOperations : public UniquePtrOperations<Outer, T, D>
  1061. {
  1062. UniquePtr<T, D>& uniquePtr() { return static_cast<Outer*>(this)->get(); }
  1063. public:
  1064. MOZ_MUST_USE typename UniquePtr<T, D>::Pointer release() { return uniquePtr().release(); }
  1065. };
  1066. template <typename T, typename D>
  1067. class RootedBase<UniquePtr<T, D>>
  1068. : public MutableUniquePtrOperations<JS::Rooted<UniquePtr<T, D>>, T, D>
  1069. { };
  1070. template <typename T, typename D>
  1071. class MutableHandleBase<UniquePtr<T, D>>
  1072. : public MutableUniquePtrOperations<JS::MutableHandle<UniquePtr<T, D>>, T, D>
  1073. { };
  1074. template <typename T, typename D>
  1075. class HandleBase<UniquePtr<T, D>>
  1076. : public UniquePtrOperations<JS::Handle<UniquePtr<T, D>>, T, D>
  1077. { };
  1078. template <typename T, typename D>
  1079. class PersistentRootedBase<UniquePtr<T, D>>
  1080. : public MutableUniquePtrOperations<JS::PersistentRooted<UniquePtr<T, D>>, T, D>
  1081. { };
  1082. namespace gc {
  1083. template <typename T, typename TraceCallbacks>
  1084. void
  1085. CallTraceCallbackOnNonHeap(T* v, const TraceCallbacks& aCallbacks, const char* aName, void* aClosure)
  1086. {
  1087. static_assert(sizeof(T) == sizeof(JS::Heap<T>), "T and Heap<T> must be compatible.");
  1088. MOZ_ASSERT(v);
  1089. mozilla::DebugOnly<Cell*> cell = BarrierMethods<T>::asGCThingOrNull(*v);
  1090. MOZ_ASSERT(cell);
  1091. MOZ_ASSERT(!IsInsideNursery(cell));
  1092. JS::Heap<T>* asHeapT = reinterpret_cast<JS::Heap<T>*>(v);
  1093. aCallbacks.Trace(asHeapT, aName, aClosure);
  1094. }
  1095. } /* namespace gc */
  1096. } /* namespace js */
  1097. // mozilla::Swap uses a stack temporary, which prevents classes like Heap<T>
  1098. // from being declared MOZ_HEAP_CLASS.
  1099. namespace mozilla {
  1100. template <typename T>
  1101. inline void
  1102. Swap(JS::Heap<T>& aX, JS::Heap<T>& aY)
  1103. {
  1104. T tmp = aX;
  1105. aX = aY;
  1106. aY = tmp;
  1107. }
  1108. template <typename T>
  1109. inline void
  1110. Swap(JS::TenuredHeap<T>& aX, JS::TenuredHeap<T>& aY)
  1111. {
  1112. T tmp = aX;
  1113. aX = aY;
  1114. aY = tmp;
  1115. }
  1116. } /* namespace mozilla */
  1117. #undef DELETE_ASSIGNMENT_OPS
  1118. #endif /* js_RootingAPI_h */