1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 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 mozilla_HoldDropJSObjects_h 8 #define mozilla_HoldDropJSObjects_h 9 10 #include <type_traits> 11 #include "nsCycleCollectionNoteChild.h" 12 13 class nsISupports; 14 class nsScriptObjectTracer; 15 class nsCycleCollectionParticipant; 16 17 namespace JS { 18 class Zone; 19 } 20 21 // Only HoldJSObjects and DropJSObjects should be called directly. 22 23 namespace mozilla { 24 namespace cyclecollector { 25 26 void HoldJSObjectsImpl(void* aHolder, nsScriptObjectTracer* aTracer, 27 JS::Zone* aZone = nullptr); 28 void HoldJSObjectsImpl(nsISupports* aHolder); 29 void DropJSObjectsImpl(void* aHolder); 30 void DropJSObjectsImpl(nsISupports* aHolder); 31 32 } // namespace cyclecollector 33 34 template <class T, bool isISupports = std::is_base_of<nsISupports, T>::value, 35 typename P = typename T::NS_CYCLE_COLLECTION_INNERCLASS> 36 struct HoldDropJSObjectsHelper { HoldHoldDropJSObjectsHelper37 static void Hold(T* aHolder) { 38 cyclecollector::HoldJSObjectsImpl(aHolder, 39 NS_CYCLE_COLLECTION_PARTICIPANT(T)); 40 } DropHoldDropJSObjectsHelper41 static void Drop(T* aHolder) { cyclecollector::DropJSObjectsImpl(aHolder); } 42 }; 43 44 template <class T> 45 struct HoldDropJSObjectsHelper<T, true> { 46 static void Hold(T* aHolder) { 47 cyclecollector::HoldJSObjectsImpl(ToSupports(aHolder)); 48 } 49 static void Drop(T* aHolder) { 50 cyclecollector::DropJSObjectsImpl(ToSupports(aHolder)); 51 } 52 }; 53 54 /** 55 Classes that hold strong references to JS GC things such as `JSObjects` and 56 `JS::Values` (e.g. `JS::Heap<JSObject*> mFoo;`) must use these, generally by 57 calling `HoldJSObjects(this)` and `DropJSObjects(this)` in the ctor and dtor 58 respectively. 59 60 For classes that are wrapper cached and hold no other strong references to JS 61 GC things, there's no need to call these; it will be taken care of 62 automatically by nsWrapperCache. 63 **/ 64 template <class T> 65 void HoldJSObjects(T* aHolder) { 66 static_assert(!std::is_base_of<nsCycleCollectionParticipant, T>::value, 67 "Don't call this on the CC participant but on the object that " 68 "it's for (in an Unlink implementation it's usually stored in " 69 "a variable named 'tmp')."); 70 HoldDropJSObjectsHelper<T>::Hold(aHolder); 71 } 72 73 template <class T> 74 void DropJSObjects(T* aHolder) { 75 static_assert(!std::is_base_of<nsCycleCollectionParticipant, T>::value, 76 "Don't call this on the CC participant but on the object that " 77 "it's for (in an Unlink implementation it's usually stored in " 78 "a variable named 'tmp')."); 79 HoldDropJSObjectsHelper<T>::Drop(aHolder); 80 } 81 82 } // namespace mozilla 83 84 #endif // mozilla_HoldDropJSObjects_h 85