TraceableFifo.h (3363B)
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 js_TraceableFifo_h 8 #define js_TraceableFifo_h 9 10 #include "ds/Fifo.h" 11 #include "js/GCVector.h" 12 #include "js/RootingAPI.h" 13 #include "js/TracingAPI.h" 14 15 namespace js { 16 17 // A TraceableFifo is a Fifo with an additional trace method that knows how to 18 // visit all of the items stored in the Fifo. For Fifos that contain GC things, 19 // this is usually more convenient than manually iterating and marking the 20 // contents. 21 // 22 // Most types of GC pointers as keys and values can be traced with no extra 23 // infrastructure. For structs and non-gc-pointer members, ensure that there is 24 // a specialization of GCPolicy<T> with an appropriate trace method available 25 // to handle the custom type. Generic helpers can be found in 26 // js/public/TracingAPI.h. Generic helpers can be found in 27 // js/public/TracingAPI.h. 28 // 29 // Note that although this Fifo's trace will deal correctly with moved items, it 30 // does not itself know when to barrier or trace items. To function properly it 31 // must either be used with Rooted, or barriered and traced manually. 32 template <typename T, size_t MinInlineCapacity = 0, 33 typename AllocPolicy = TempAllocPolicy> 34 class TraceableFifo 35 : public js::Fifo<T, MinInlineCapacity, AllocPolicy, JS::GCVector> { 36 using Base = js::Fifo<T, MinInlineCapacity, AllocPolicy, JS::GCVector>; 37 38 public: 39 explicit TraceableFifo(AllocPolicy alloc = AllocPolicy()) 40 : Base(std::move(alloc)) {} 41 42 TraceableFifo(TraceableFifo&& rhs) : Base(std::move(rhs)) {} 43 TraceableFifo& operator=(TraceableFifo&& rhs) = default; 44 45 TraceableFifo(const TraceableFifo&) = delete; 46 TraceableFifo& operator=(const TraceableFifo&) = delete; 47 48 void trace(JSTracer* trc) { 49 this->front_.trace(trc); 50 this->rear_.trace(trc); 51 } 52 }; 53 54 template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy> 55 class WrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, Wrapper> { 56 using TF = TraceableFifo<T, Capacity, AllocPolicy>; 57 const TF& fifo() const { return static_cast<const Wrapper*>(this)->get(); } 58 59 public: 60 size_t length() const { return fifo().length(); } 61 bool empty() const { return fifo().empty(); } 62 const T& front() const { return fifo().front(); } 63 }; 64 65 template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy> 66 class MutableWrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, 67 Wrapper> 68 : public WrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, 69 Wrapper> { 70 using TF = TraceableFifo<T, Capacity, AllocPolicy>; 71 TF& fifo() { return static_cast<Wrapper*>(this)->get(); } 72 73 public: 74 T& front() { return fifo().front(); } 75 76 template <typename U> 77 bool pushBack(U&& u) { 78 return fifo().pushBack(std::forward<U>(u)); 79 } 80 template <typename... Args> 81 bool emplaceBack(Args&&... args) { 82 return fifo().emplaceBack(std::forward<Args...>(args...)); 83 } 84 85 void popFront() { fifo().popFront(); } 86 void clear() { fifo().clear(); } 87 }; 88 89 } // namespace js 90 91 #endif // js_TraceableFifo_h