From dc5a60fb62a0f43fe77517bd0e46fe40358b44b0 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Tue, 24 May 2022 06:51:11 +0000 Subject: Issue #1742 - Part 1: Refactor rooting base class templates Based on Bug 1325406 --- js/public/GCHashTable.h | 76 ++++++------------------ js/public/GCVariant.h | 36 +++--------- js/public/GCVector.h | 36 +++--------- js/public/RootingAPI.h | 83 +++++++++++--------------- js/public/SweepingAPI.h | 7 +-- js/public/Value.h | 52 +++++------------ js/src/builtin/MapObject.h | 20 +++++-- js/src/ds/TraceableFifo.h | 54 +++-------------- js/src/gc/Barrier.h | 25 ++++---- js/src/jsapi-tests/testGCExactRooting.cpp | 17 ++---- js/src/jsapi.h | 44 +++++--------- js/src/jscompartment.cpp | 5 +- js/src/jsobj.h | 14 +++-- js/src/vm/ArrayBufferObject.cpp | 4 +- js/src/vm/ArrayBufferObject.h | 17 ++---- js/src/vm/Interpreter.cpp | 14 +---- js/src/vm/JSONParser.h | 9 ++- js/src/vm/SavedStacks.h | 51 ++++++++-------- js/src/vm/Scope.h | 96 ++++++++++--------------------- js/src/vm/Shape.h | 33 ++++------- js/src/vm/TaggedProto.h | 18 +----- 21 files changed, 227 insertions(+), 484 deletions(-) (limited to 'js') diff --git a/js/public/GCHashTable.h b/js/public/GCHashTable.h index 4de1c39a81..3e647ed100 100644 --- a/js/public/GCHashTable.h +++ b/js/public/GCHashTable.h @@ -133,13 +133,13 @@ class GCRekeyableHashMap : public JS::GCHashMap -class GCHashMapOperations +template +class WrappedPtrOperations, Wrapper> { using Map = JS::GCHashMap; using Lookup = typename Map::Lookup; - const Map& map() const { return static_cast(this)->get(); } + const Map& map() const { return static_cast(this)->get(); } public: using AddPtr = typename Map::AddPtr; @@ -162,18 +162,18 @@ class GCHashMapOperations } }; -template -class MutableGCHashMapOperations - : public GCHashMapOperations +template +class MutableWrappedPtrOperations, Wrapper> + : public WrappedPtrOperations, Wrapper> { using Map = JS::GCHashMap; using Lookup = typename Map::Lookup; - Map& map() { return static_cast(this)->get(); } + Map& map() { return static_cast(this)->get(); } public: using AddPtr = typename Map::AddPtr; - struct Enum : public Map::Enum { explicit Enum(Outer& o) : Map::Enum(o.map()) {} }; + struct Enum : public Map::Enum { explicit Enum(Wrapper& o) : Map::Enum(o.map()) {} }; using Ptr = typename Map::Ptr; using Range = typename Map::Range; @@ -210,26 +210,6 @@ class MutableGCHashMapOperations } }; -template -class RootedBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class MutableHandleBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class HandleBase> - : public GCHashMapOperations>, A,B,C,D,E> -{}; - -template -class WeakCacheBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - } // namespace js namespace JS { @@ -291,13 +271,13 @@ class GCHashSet : public js::HashSet namespace js { -template -class GCHashSetOperations +template +class WrappedPtrOperations, Wrapper> { using Set = JS::GCHashSet; using Lookup = typename Set::Lookup; - const Set& set() const { return static_cast(this)->get(); } + const Set& set() const { return static_cast(this)->get(); } public: using AddPtr = typename Set::AddPtr; @@ -321,19 +301,19 @@ class GCHashSetOperations } }; -template -class MutableGCHashSetOperations - : public GCHashSetOperations +template +class MutableWrappedPtrOperations, Wrapper> + : public WrappedPtrOperations, Wrapper> { using Set = JS::GCHashSet; using Lookup = typename Set::Lookup; - Set& set() { return static_cast(this)->get(); } + Set& set() { return static_cast(this)->get(); } public: using AddPtr = typename Set::AddPtr; using Entry = typename Set::Entry; - struct Enum : public Set::Enum { explicit Enum(Outer& o) : Set::Enum(o.set()) {} }; + struct Enum : public Set::Enum { explicit Enum(Wrapper& o) : Set::Enum(o.set()) {} }; using Ptr = typename Set::Ptr; using Range = typename Set::Range; @@ -369,30 +349,6 @@ class MutableGCHashSetOperations } }; -template -class RootedBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class MutableHandleBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class HandleBase> - : public GCHashSetOperations>, T, HP, AP> -{ -}; - -template -class WeakCacheBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - } /* namespace js */ #endif /* GCHashTable_h */ diff --git a/js/public/GCVariant.h b/js/public/GCVariant.h index 43f2957fee..3ec40df5ca 100644 --- a/js/public/GCVariant.h +++ b/js/public/GCVariant.h @@ -123,13 +123,13 @@ struct GCPolicy> namespace js { -template -class GCVariantOperations +template +class WrappedPtrOperations, Wrapper> { using Impl = JS::detail::GCVariantImplementation; using Variant = mozilla::Variant; - const Variant& variant() const { return static_cast(this)->get(); } + const Variant& variant() const { return static_cast(this)->get(); } public: template @@ -149,15 +149,15 @@ class GCVariantOperations } }; -template -class MutableGCVariantOperations - : public GCVariantOperations +template +class MutableWrappedPtrOperations, Wrapper> + : public WrappedPtrOperations, Wrapper> { using Impl = JS::detail::GCVariantImplementation; using Variant = mozilla::Variant; - const Variant& variant() const { return static_cast(this)->get(); } - Variant& variant() { return static_cast(this)->get(); } + const Variant& variant() const { return static_cast(this)->get(); } + Variant& variant() { return static_cast(this)->get(); } public: template @@ -172,26 +172,6 @@ class MutableGCVariantOperations } }; -template -class RootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class MutableHandleBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class HandleBase> - : public GCVariantOperations>, Ts...> -{ }; - -template -class PersistentRootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - } // namespace js #endif // js_GCVariant_h diff --git a/js/public/GCVector.h b/js/public/GCVector.h index 1c99252617..4acf0d1fc5 100644 --- a/js/public/GCVector.h +++ b/js/public/GCVector.h @@ -134,11 +134,11 @@ class GCVector namespace js { -template -class GCVectorOperations +template +class WrappedPtrOperations, Wrapper> { using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } + const Vec& vec() const { return static_cast(this)->get(); } public: const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } @@ -154,13 +154,13 @@ class GCVectorOperations } }; -template -class MutableGCVectorOperations - : public GCVectorOperations +template +class MutableWrappedPtrOperations, Wrapper> + : public WrappedPtrOperations, Wrapper> { using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - Vec& vec() { return static_cast(this)->get(); } + const Vec& vec() const { return static_cast(this)->get(); } + Vec& vec() { return static_cast(this)->get(); } public: const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } @@ -223,26 +223,6 @@ class MutableGCVectorOperations void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); } }; -template -class RootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class MutableHandleBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class HandleBase> - : public GCVectorOperations>, T,N,AP> -{}; - -template -class PersistentRootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - } // namespace js #endif // js_GCVector_h diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index 5f0740d53a..120e1fcde0 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -112,17 +112,23 @@ template struct BarrierMethods { }; -template -class RootedBase {}; +template +class WrappedPtrOperations {}; -template -class HandleBase {}; +template +class MutableWrappedPtrOperations : public WrappedPtrOperations {}; -template -class MutableHandleBase {}; +template +class RootedBase : public MutableWrappedPtrOperations {}; -template -class HeapBase {}; +template +class HandleBase : public WrappedPtrOperations {}; + +template +class MutableHandleBase : public MutableWrappedPtrOperations {}; + +template +class HeapBase : public MutableWrappedPtrOperations {}; // Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope template struct IsHeapConstructibleType { static constexpr bool value = false; }; @@ -132,8 +138,8 @@ FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) #undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE -template -class PersistentRootedBase {}; +template +class PersistentRootedBase : public MutableWrappedPtrOperations {}; static void* const ConstNullValue = nullptr; @@ -230,7 +236,7 @@ AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell) {} * Type T must be a public GC pointer type. */ template -class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase +class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase> { // Please note: this can actually also be used by nsXBLMaybeCompiled, for legacy reasons. static_assert(js::IsHeapConstructibleType::value, @@ -367,7 +373,7 @@ ScriptIsMarkedGray(const Heap& script) * - It is not possible to store flag bits in a Heap. */ template -class TenuredHeap : public js::HeapBase +class TenuredHeap : public js::HeapBase> { public: TenuredHeap() : bits(0) { @@ -451,7 +457,7 @@ class TenuredHeap : public js::HeapBase * specialization, define a HandleBase specialization containing them. */ template -class MOZ_NONHEAP_CLASS Handle : public js::HandleBase +class MOZ_NONHEAP_CLASS Handle : public js::HandleBase> { friend class JS::MutableHandle; @@ -540,7 +546,7 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase * them. */ template -class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase +class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase> { public: inline MOZ_IMPLICIT MutableHandle(Rooted* root); @@ -753,7 +759,7 @@ namespace JS { * specialization, define a RootedBase specialization containing them. */ template -class MOZ_RAII Rooted : public js::RootedBase +class MOZ_RAII Rooted : public js::RootedBase> { inline void registerWithRootLists(js::RootedListHeads& roots) { this->stack = &roots[JS::MapTypeToRootKind::kind]; @@ -853,8 +859,8 @@ namespace js { * Rooted rooted(cx, &obj->as()); * Handle h = rooted; */ -template <> -class RootedBase +template +class RootedBase : public MutableWrappedPtrOperations { public: template @@ -871,8 +877,8 @@ class RootedBase * Rooted rooted(cx, &obj->as()); * Handle h = rooted; */ -template <> -class HandleBase +template +class HandleBase : public WrappedPtrOperations { public: template @@ -881,7 +887,7 @@ class HandleBase /** Interface substitute for Rooted which does not root the variable's memory. */ template -class MOZ_RAII FakeRooted : public RootedBase +class MOZ_RAII FakeRooted : public RootedBase> { public: template @@ -908,7 +914,7 @@ class MOZ_RAII FakeRooted : public RootedBase /** Interface substitute for MutableHandle which is not required to point to rooted memory. */ template -class FakeMutableHandle : public js::MutableHandleBase +class FakeMutableHandle : public js::MutableHandleBase> { public: MOZ_IMPLICIT FakeMutableHandle(T* t) { @@ -1075,7 +1081,7 @@ MutableHandle::MutableHandle(PersistentRooted* root) * marked when the object itself is marked. */ template -class PersistentRooted : public js::PersistentRootedBase, +class PersistentRooted : public js::RootedBase>, private mozilla::LinkedListElement> { using ListBase = mozilla::LinkedListElement>; @@ -1240,10 +1246,10 @@ class JS_PUBLIC_API(ObjectPtr) namespace js { -template -class UniquePtrOperations +template +class WrappedPtrOperations, Container> { - const UniquePtr& uniquePtr() const { return static_cast(this)->get(); } + const UniquePtr& uniquePtr() const { return static_cast(this)->get(); } public: explicit operator bool() const { return !!uniquePtr(); } @@ -1252,36 +1258,17 @@ class UniquePtrOperations T& operator*() const { return *uniquePtr(); } }; -template -class MutableUniquePtrOperations : public UniquePtrOperations +template +class MutableWrappedPtrOperations, Container> + : public WrappedPtrOperations, Container> { - UniquePtr& uniquePtr() { return static_cast(this)->get(); } + UniquePtr& uniquePtr() { return static_cast(this)->get(); } public: MOZ_MUST_USE typename UniquePtr::Pointer release() { return uniquePtr().release(); } void reset(T* ptr = T()) { uniquePtr().reset(ptr); } }; -template -class RootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class MutableHandleBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class HandleBase> - : public UniquePtrOperations>, T, D> -{ }; - -template -class PersistentRootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - namespace gc { template diff --git a/js/public/SweepingAPI.h b/js/public/SweepingAPI.h index 39abb0fc0e..bbc1ec279b 100644 --- a/js/public/SweepingAPI.h +++ b/js/public/SweepingAPI.h @@ -8,11 +8,6 @@ #include "js/HeapAPI.h" -namespace js { -template -class WeakCacheBase {}; -} // namespace js - namespace JS { template class WeakCache; @@ -24,7 +19,7 @@ RegisterWeakCache(JS::Zone* zone, JS::WeakCache* cachep); // A WeakCache stores the given Sweepable container and links itself into a // list of such caches that are swept during each GC. template -class WeakCache : public js::WeakCacheBase, +class WeakCache : public js::MutableWrappedPtrOperations>, private mozilla::LinkedListElement> { friend class mozilla::LinkedListElement>; diff --git a/js/public/Value.h b/js/public/Value.h index 087d178efd..c645f07733 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -1340,20 +1340,18 @@ struct BarrierMethods } }; -template class MutableValueOperations; +template class MutableValueOperations; /** * A class designed for CRTP use in implementing the non-mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * ValueOperations with a visible get() method returning a const - * reference to the Value abstracted by Outer. + * Value interface in Value-like classes. Wrapper must be a class inheriting + * ValueOperations with a visible get() method returning a const + * reference to the Value abstracted by Wrapper. */ -template -class ValueOperations +template +class WrappedPtrOperations { - friend class MutableValueOperations; - - const JS::Value& value() const { return static_cast(this)->get(); } + const JS::Value& value() const { return static_cast(this)->get(); } public: bool isUndefined() const { return value().isUndefined(); } @@ -1398,17 +1396,17 @@ class ValueOperations /** * A class designed for CRTP use in implementing all the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible get() methods returning const and - * non-const references to the Value abstracted by Outer. + * Value interface in Value-like classes. Wrapper must be a class inheriting + * MutableWrappedPtrOperations with visible get() methods returning const and + * non-const references to the Value abstracted by Wrapper. */ -template -class MutableValueOperations : public ValueOperations +template +class MutableWrappedPtrOperations : public WrappedPtrOperations { protected: void set(const JS::Value& v) { // Call Outer::set to trigger any barriers. - static_cast(this)->set(v); + static_cast(this)->set(v); } public: @@ -1434,13 +1432,9 @@ class MutableValueOperations : public ValueOperations * Augment the generic Heap interface when T = Value with * type-querying, value-extracting, and mutating operations. */ -template <> -class HeapBase : public MutableValueOperations > +template +class HeapBase : public MutableWrappedPtrOperations { - typedef JS::Heap Outer; - - friend class ValueOperations; - public: void setNumber(uint32_t ui) { if (ui > JSVAL_INT_MAX) { @@ -1460,22 +1454,6 @@ class HeapBase : public MutableValueOperations > } }; -template <> -class HandleBase : public ValueOperations > -{}; - -template <> -class MutableHandleBase : public MutableValueOperations > -{}; - -template <> -class RootedBase : public MutableValueOperations > -{}; - -template <> -class PersistentRootedBase : public MutableValueOperations> -{}; - /* * If the Value is a GC pointer type, convert to that type and call |f| with * the pointer. If the Value is not a GC type, calls F::defaultValue. diff --git a/js/src/builtin/MapObject.h b/js/src/builtin/MapObject.h index 5382adfd25..a9f685ea00 100644 --- a/js/src/builtin/MapObject.h +++ b/js/src/builtin/MapObject.h @@ -52,14 +52,22 @@ class HashableValue } }; -template <> -class RootedBase { +template +class WrappedPtrOperations +{ public: - MOZ_MUST_USE bool setValue(JSContext* cx, HandleValue v) { - return static_cast*>(this)->get().setValue(cx, v); - } Value value() const { - return static_cast*>(this)->get().get(); + return static_cast(this)->get().get(); + } +}; + +template +class MutableWrappedPtrOperations + : public WrappedPtrOperations +{ + public: + MOZ_MUST_USE bool setValue(JSContext* cx, HandleValue v) { + return static_cast(this)->get().setValue(cx, v); } }; diff --git a/js/src/ds/TraceableFifo.h b/js/src/ds/TraceableFifo.h index 04f67da151..0f94b93cbd 100644 --- a/js/src/ds/TraceableFifo.h +++ b/js/src/ds/TraceableFifo.h @@ -51,11 +51,11 @@ class TraceableFifo : public js::Fifo } }; -template -class TraceableFifoOperations +template +class WrappedPtrOperations, Wrapper> { using TF = TraceableFifo; - const TF& fifo() const { return static_cast(this)->extract(); } + const TF& fifo() const { return static_cast(this)->get(); } public: size_t length() const { return fifo().length(); } @@ -63,12 +63,12 @@ class TraceableFifoOperations const T& front() const { return fifo().front(); } }; -template -class MutableTraceableFifoOperations - : public TraceableFifoOperations +template +class MutableWrappedPtrOperations, Wrapper> + : public WrappedPtrOperations, Wrapper> { using TF = TraceableFifo; - TF& fifo() { return static_cast(this)->extract(); } + TF& fifo() { return static_cast(this)->get(); } public: T& front() { return fifo().front(); } @@ -82,46 +82,6 @@ class MutableTraceableFifoOperations void clear() { fifo().clear(); } }; -template -class RootedBase> - : public MutableTraceableFifoOperations>, A,B,C> -{ - using TF = TraceableFifo; - - friend class TraceableFifoOperations, A,B,C>; - const TF& extract() const { return *static_cast*>(this)->address(); } - - friend class MutableTraceableFifoOperations, A,B,C>; - TF& extract() { return *static_cast*>(this)->address(); } -}; - -template -class MutableHandleBase> - : public MutableTraceableFifoOperations>, A,B,C> -{ - using TF = TraceableFifo; - - friend class TraceableFifoOperations, A,B,C>; - const TF& extract() const { - return *static_cast*>(this)->address(); - } - - friend class MutableTraceableFifoOperations, A,B,C>; - TF& extract() { return *static_cast*>(this)->address(); } -}; - -template -class HandleBase> - : public TraceableFifoOperations>, A,B,C> -{ - using TF = TraceableFifo; - - friend class TraceableFifoOperations, A,B,C>; - const TF& extract() const { - return *static_cast*>(this)->address(); - } -}; - } // namespace js #endif // js_TraceableFifo_h diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 681ccc9c4c..d10fb4321c 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -324,18 +324,12 @@ struct InternalBarrierMethods static void postBarrier(jsid* idp, jsid prev, jsid next) {} }; -// Barrier classes can use Mixins to add methods to a set of barrier -// instantiations, to make the barriered thing look and feel more like the -// thing itself. -template -class BarrieredBaseMixins {}; - // Base class of all barrier types. // // This is marked non-memmovable since post barriers added by derived classes // can add pointers to class instances to the store buffer. template -class MOZ_NON_MEMMOVABLE BarrieredBase : public BarrieredBaseMixins +class MOZ_NON_MEMMOVABLE BarrieredBase { protected: // BarrieredBase is not directly instantiable. @@ -356,9 +350,12 @@ class MOZ_NON_MEMMOVABLE BarrieredBase : public BarrieredBaseMixins // Base class for barriered pointer types that intercept only writes. template -class WriteBarrieredBase : public BarrieredBase +class WriteBarrieredBase : public BarrieredBase, + public WrappedPtrOperations> { protected: + using BarrieredBase::value; + // WriteBarrieredBase is not directly instantiable. explicit WriteBarrieredBase(const T& v) : BarrieredBase(v) {} @@ -580,8 +577,12 @@ class ReadBarrieredBase : public BarrieredBase // insert manual post-barriers on the table for rekeying if the key is based in // any way on the address of the object. template -class ReadBarriered : public ReadBarrieredBase +class ReadBarriered : public ReadBarrieredBase, + public WrappedPtrOperations> { + protected: + using ReadBarrieredBase::value; + public: ReadBarriered() : ReadBarrieredBase(JS::GCPolicy::initial()) {} @@ -649,12 +650,6 @@ class ReadBarriered : public ReadBarrieredBase template using WeakRef = ReadBarriered; -// Add Value operations to all Barrier types. Note, this must be defined before -// HeapSlot for HeapSlot's base to get these operations. -template <> -class BarrieredBaseMixins : public ValueOperations> -{}; - // A pre- and post-barriered Value that is specialized to be aware that it // resides in a slots or elements vector. This allows it to be relocated in // memory, but with substantially less overhead than a HeapPtr. diff --git a/js/src/jsapi-tests/testGCExactRooting.cpp b/js/src/jsapi-tests/testGCExactRooting.cpp index aff65014a9..6d41d374b5 100644 --- a/js/src/jsapi-tests/testGCExactRooting.cpp +++ b/js/src/jsapi-tests/testGCExactRooting.cpp @@ -56,19 +56,10 @@ struct MyContainer }; namespace js { -template <> -struct RootedBase { - HeapPtr& obj() { return static_cast*>(this)->get().obj; } - HeapPtr& str() { return static_cast*>(this)->get().str; } -}; -template <> -struct PersistentRootedBase { - HeapPtr& obj() { - return static_cast*>(this)->get().obj; - } - HeapPtr& str() { - return static_cast*>(this)->get().str; - } +template +struct MutableWrappedPtrOperations { + HeapPtr& obj() { return static_cast(this)->get().obj; } + HeapPtr& str() { return static_cast(this)->get().str; } }; } // namespace js diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 1eecdbf749..8e70cc152b 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2546,10 +2546,14 @@ struct JS_PUBLIC_API(PropertyDescriptor) { void trace(JSTracer* trc); }; -template -class PropertyDescriptorOperations +} // namespace JS + +namespace js { + +template +class WrappedPtrOperations { - const PropertyDescriptor& desc() const { return static_cast(this)->get(); } + const JS::PropertyDescriptor& desc() const { return static_cast(this)->get(); } bool has(unsigned bit) const { MOZ_ASSERT(bit != 0); @@ -2678,10 +2682,11 @@ class PropertyDescriptorOperations } }; -template -class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations +template +class MutableWrappedPtrOperations + : public js::WrappedPtrOperations { - PropertyDescriptor& desc() { return static_cast(this)->get(); } + JS::PropertyDescriptor& desc() { return static_cast(this)->get(); } public: void clear() { @@ -2692,7 +2697,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations< value().setUndefined(); } - void initFields(HandleObject obj, HandleValue v, unsigned attrs, + void initFields(JS::HandleObject obj, JS::HandleValue v, unsigned attrs, JSGetterOp getterOp, JSSetterOp setterOp) { MOZ_ASSERT(getterOp != JS_PropertyStub); MOZ_ASSERT(setterOp != JS_StrictPropertyStub); @@ -2704,7 +2709,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations< setSetter(setterOp); } - void assign(PropertyDescriptor& other) { + void assign(JS::PropertyDescriptor& other) { object().set(other.obj); setAttributes(other.attrs); setGetter(other.getter); @@ -2712,7 +2717,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations< value().set(other.value); } - void setDataDescriptor(HandleValue v, unsigned attrs) { + void setDataDescriptor(JS::HandleValue v, unsigned attrs) { MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY | @@ -2787,26 +2792,7 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations< } }; -} /* namespace JS */ - -namespace js { - -template <> -class RootedBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -template <> -class HandleBase - : public JS::PropertyDescriptorOperations> -{}; - -template <> -class MutableHandleBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -} /* namespace js */ +} // namespace js namespace JS { diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index ebf2d178fc..5e33f27f7d 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -722,8 +722,9 @@ JSCompartment::sweepAfterMinorGC(JSTracer* trc) { globalWriteBarriered = 0; - if (innerViews.needsSweepAfterMinorGC()) - innerViews.sweepAfterMinorGC(); + InnerViewTable& table = innerViews.get(); + if (table.needsSweepAfterMinorGC()) + table.sweepAfterMinorGC(); crossCompartmentWrappers.sweepAfterMinorGC(trc); } diff --git a/js/src/jsobj.h b/js/src/jsobj.h index ca48f8de7c..52be7e8188 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -587,21 +587,23 @@ class JSObject : public js::gc::Cell void operator=(const JSObject& other) = delete; }; -template +template +template MOZ_ALWAYS_INLINE JS::Handle -js::RootedBase::as() const +js::RootedBase::as() const { - const JS::Rooted& self = *static_cast*>(this); - MOZ_ASSERT(self->is()); + const Wrapper& self = *static_cast(this); + MOZ_ASSERT(self->template is()); return Handle::fromMarkedLocation(reinterpret_cast(self.address())); } +template template MOZ_ALWAYS_INLINE JS::Handle -js::HandleBase::as() const +js::HandleBase::as() const { const JS::Handle& self = *static_cast*>(this); - MOZ_ASSERT(self->is()); + MOZ_ASSERT(self->template is()); return Handle::fromMarkedLocation(reinterpret_cast(self.address())); } diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 1de3d3b1ec..5d355ada9d 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -352,7 +352,7 @@ ArrayBufferObject::detach(JSContext* cx, Handle buffer, // Update all views of the buffer to account for the buffer having been // detached, and clear the buffer's data and list of views. - auto& innerViews = cx->compartment()->innerViews; + auto& innerViews = cx->compartment()->innerViews.get(); if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(buffer)) { for (size_t i = 0; i < views->length(); i++) NoteViewBufferWasDetached((*views)[i], newContents, cx); @@ -427,7 +427,7 @@ ArrayBufferObject::changeContents(JSContext* cx, BufferContents newContents, setNewData(cx->runtime()->defaultFreeOp(), newContents, ownsState); // Update all views. - auto& innerViews = cx->compartment()->innerViews; + auto& innerViews = cx->compartment()->innerViews.get(); if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(this)) { for (size_t i = 0; i < views->length(); i++) changeViewContents(cx, (*views)[i], oldDataPointer, newContents); diff --git a/js/src/vm/ArrayBufferObject.h b/js/src/vm/ArrayBufferObject.h index e6dbd30961..87dce34ba1 100644 --- a/js/src/vm/ArrayBufferObject.h +++ b/js/src/vm/ArrayBufferObject.h @@ -541,7 +541,6 @@ class InnerViewTable typedef Vector ViewVector; friend class ArrayBufferObject; - friend class WeakCacheBase; private: struct MapGCPolicy { @@ -602,23 +601,15 @@ class InnerViewTable size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); }; -template <> -class WeakCacheBase +template +class MutableWrappedPtrOperations + : public WrappedPtrOperations { InnerViewTable& table() { - return static_cast*>(this)->get(); - } - const InnerViewTable& table() const { - return static_cast*>(this)->get(); + return static_cast(this)->get(); } public: - InnerViewTable::ViewVector* maybeViewsUnbarriered(ArrayBufferObject* obj) { - return table().maybeViewsUnbarriered(obj); - } - void removeViews(ArrayBufferObject* obj) { table().removeViews(obj); } - void sweepAfterMinorGC() { table().sweepAfterMinorGC(); } - bool needsSweepAfterMinorGC() const { return table().needsSweepAfterMinorGC(); } size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { return table().sizeOfExcludingThis(mallocSizeOf); } diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 56f715e2be..7e3f2a7f1b 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -1613,11 +1613,7 @@ GetSuperEnvFunction(JSContext* cx, InterpreterRegs& regs) */ template -class ReservedRootedBase { -}; - -template -class ReservedRooted : public ReservedRootedBase +class ReservedRooted : public RootedBase> { Rooted* savedRoot; @@ -1645,14 +1641,6 @@ class ReservedRooted : public ReservedRootedBase DECLARE_POINTER_ASSIGN_OPS(ReservedRooted, T) }; -template <> -class ReservedRootedBase : public ValueOperations> -{}; - -template <> -class ReservedRootedBase : public ScopeCastOperation> -{}; - static MOZ_NEVER_INLINE bool Interpret(JSContext* cx, RunState& state) { diff --git a/js/src/vm/JSONParser.h b/js/src/vm/JSONParser.h index 6f91391db0..70ed86f58e 100644 --- a/js/src/vm/JSONParser.h +++ b/js/src/vm/JSONParser.h @@ -255,10 +255,13 @@ class MOZ_STACK_CLASS JSONParser : public JSONParserBase void operator=(const JSONParser& other) = delete; }; -template -struct RootedBase> { +template +class MutableWrappedPtrOperations, Wrapper> + : public WrappedPtrOperations, Wrapper> +{ + public: bool parse(MutableHandleValue vp) { - return static_cast>*>(this)->get().parse(vp); + return static_cast(this)->get().parse(vp); } }; diff --git a/js/src/vm/SavedStacks.h b/js/src/vm/SavedStacks.h index c6bda2831b..3ea6c40874 100644 --- a/js/src/vm/SavedStacks.h +++ b/js/src/vm/SavedStacks.h @@ -265,24 +265,6 @@ class SavedStacks { uint32_t column; }; - template - struct LocationValueOperations { - JSAtom* source() const { return loc().source; } - size_t line() const { return loc().line; } - uint32_t column() const { return loc().column; } - private: - const LocationValue& loc() const { return static_cast(this)->get(); } - }; - - template - struct MutableLocationValueOperations : public LocationValueOperations { - void setSource(JSAtom* v) { loc().source = v; } - void setLine(size_t v) { loc().line = v; } - void setColumn(uint32_t v) { loc().column = v; } - private: - LocationValue& loc() { return static_cast(this)->get(); } - }; - private: struct PCLocationHasher : public DefaultHasher { using ScriptPtrHasher = DefaultHasher; @@ -313,15 +295,32 @@ class SavedStacks { MutableHandle locationp); }; -template <> -class RootedBase - : public SavedStacks::MutableLocationValueOperations> -{}; +template +struct WrappedPtrOperations +{ + JSAtom* source() const { return loc().source; } + size_t line() const { return loc().line; } + uint32_t column() const { return loc().column; } + + private: + const SavedStacks::LocationValue& loc() const { + return static_cast(this)->get(); + } +}; + +template +struct MutableWrappedPtrOperations + : public WrappedPtrOperations +{ + void setSource(JSAtom* v) { loc().source = v; } + void setLine(size_t v) { loc().line = v; } + void setColumn(uint32_t v) { loc().column = v; } -template <> -class MutableHandleBase - : public SavedStacks::MutableLocationValueOperations> -{}; + private: + SavedStacks::LocationValue& loc() { + return static_cast(this)->get(); + } +}; UTF8CharsZ BuildUTF8StackString(JSContext* cx, HandleObject stack); diff --git a/js/src/vm/Scope.h b/js/src/vm/Scope.h index 4f0edcc133..fc1419bb89 100644 --- a/js/src/vm/Scope.h +++ b/js/src/vm/Scope.h @@ -22,6 +22,7 @@ namespace js { class ModuleObject; +class Scope; enum class BindingKind : uint8_t { @@ -223,6 +224,21 @@ class BindingLocation } }; +// +// Allow using is and as on Rooted and Handle. +// +template +class WrappedPtrOperations +{ + public: + template + JS::Handle as() const { + const Wrapper& self = *static_cast(this); + MOZ_ASSERT_IF(self, self->template is()); + return Handle::fromMarkedLocation(reinterpret_cast(self.address())); + } +}; + // // The base class of all Scopes. // @@ -1338,10 +1354,10 @@ class MOZ_STACK_CLASS ScopeIter // Specializations of Rooted containers for the iterators. // -template -class BindingIterOperations +template +class WrappedPtrOperations { - const BindingIter& iter() const { return static_cast(this)->get(); } + const BindingIter& iter() const { return static_cast(this)->get(); } public: bool done() const { return iter().done(); } @@ -1361,19 +1377,20 @@ class BindingIterOperations uint32_t nextEnvironmentSlot() const { return iter().nextEnvironmentSlot(); } }; -template -class MutableBindingIterOperations : public BindingIterOperations +template +class MutableWrappedPtrOperations + : public WrappedPtrOperations { - BindingIter& iter() { return static_cast(this)->get(); } + BindingIter& iter() { return static_cast(this)->get(); } public: void operator++(int) { iter().operator++(1); } }; -template -class ScopeIterOperations +template +class WrappedPtrOperations { - const ScopeIter& iter() const { return static_cast(this)->get(); } + const ScopeIter& iter() const { return static_cast(this)->get(); } public: bool done() const { return iter().done(); } @@ -1384,69 +1401,16 @@ class ScopeIterOperations bool hasSyntacticEnvironment() const { return iter().hasSyntacticEnvironment(); } }; -template -class MutableScopeIterOperations : public ScopeIterOperations +template +class MutableWrappedPtrOperations + : public WrappedPtrOperations { - ScopeIter& iter() { return static_cast(this)->get(); } + ScopeIter& iter() { return static_cast(this)->get(); } public: void operator++(int) { iter().operator++(1); } }; -#define SPECIALIZE_ROOTING_CONTAINERS(Iter, BaseIter) \ - template <> \ - class RootedBase \ - : public Mutable##BaseIter##Operations> \ - { }; \ - \ - template <> \ - class MutableHandleBase \ - : public Mutable##BaseIter##Operations> \ - { }; \ - \ - template <> \ - class HandleBase \ - : public BaseIter##Operations> \ - { }; \ - \ - template <> \ - class PersistentRootedBase \ - : public Mutable##BaseIter##Operations> \ - { } - -SPECIALIZE_ROOTING_CONTAINERS(BindingIter, BindingIter); -SPECIALIZE_ROOTING_CONTAINERS(PositionalFormalParameterIter, BindingIter); -SPECIALIZE_ROOTING_CONTAINERS(ScopeIter, ScopeIter); - -#undef SPECIALIZE_ROOTING_CONTAINERS - -// -// Allow using is and as on Rooted and Handle. -// - -template -struct ScopeCastOperation -{ - template - JS::Handle as() const { - const Outer& self = *static_cast(this); - MOZ_ASSERT_IF(self, self->template is()); - return Handle::fromMarkedLocation(reinterpret_cast(self.address())); - } -}; - -template <> -class RootedBase : public ScopeCastOperation> -{ }; - -template <> -class HandleBase : public ScopeCastOperation> -{ }; - -template <> -class MutableHandleBase : public ScopeCastOperation> -{ }; - } // namespace js namespace JS { diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index 52b9197da6..b292bd58f2 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -1264,9 +1264,10 @@ struct InitialShapeEntry bool needsSweep() { Shape* ushape = shape.unbarrieredGet(); - JSObject* protoObj = proto.proto().raw(); + TaggedProto uproto = proto.proto().unbarrieredGet(); + JSObject* protoObj = uproto.raw(); return (gc::IsAboutToBeFinalizedUnbarriered(&ushape) || - (proto.proto().isObject() && gc::IsAboutToBeFinalizedUnbarriered(&protoObj))); + (uproto.isObject() && gc::IsAboutToBeFinalizedUnbarriered(&protoObj))); } }; @@ -1356,9 +1357,10 @@ struct StackShape void trace(JSTracer* trc); }; -template -class StackShapeOperations { - const StackShape& ss() const { return static_cast(this)->get(); } +template +class WrappedPtrOperations +{ + const StackShape& ss() const { return static_cast(this)->get(); } public: bool hasSlot() const { return ss().hasSlot(); } @@ -1370,9 +1372,11 @@ class StackShapeOperations { uint8_t attrs() const { return ss().attrs; } }; -template -class MutableStackShapeOperations : public StackShapeOperations { - StackShape& ss() { return static_cast(this)->get(); } +template +class MutableWrappedPtrOperations + : public WrappedPtrOperations +{ + StackShape& ss() { return static_cast(this)->get(); } public: void updateGetterSetter(GetterOp rawGetter, SetterOp rawSetter) { @@ -1383,19 +1387,6 @@ class MutableStackShapeOperations : public StackShapeOperations { void setAttrs(uint8_t attrs) { ss().attrs = attrs; } }; -template <> -class RootedBase : public MutableStackShapeOperations> -{}; - -template <> -class HandleBase : public StackShapeOperations> -{}; - -template <> -class MutableHandleBase - : public MutableStackShapeOperations> -{}; - inline Shape::Shape(const StackShape& other, uint32_t nfixed) : base_(other.base), diff --git a/js/src/vm/TaggedProto.h b/js/src/vm/TaggedProto.h index de3e86a7f5..5b9fe5c7e8 100644 --- a/js/src/vm/TaggedProto.h +++ b/js/src/vm/TaggedProto.h @@ -77,11 +77,11 @@ struct InternalBarrierMethods } }; -template -class TaggedProtoOperations +template +class WrappedPtrOperations { const TaggedProto& value() const { - return static_cast(this)->get(); + return static_cast(this)->get(); } public: @@ -95,18 +95,6 @@ class TaggedProtoOperations uint64_t uniqueId() const { return value().uniqueId(); } }; -template <> -class HandleBase : public TaggedProtoOperations> -{}; - -template <> -class RootedBase : public TaggedProtoOperations> -{}; - -template <> -class BarrieredBaseMixins : public TaggedProtoOperations> -{}; - // If the TaggedProto is a JSObject pointer, convert to that type and call |f| // with the pointer. If the TaggedProto is lazy, calls F::defaultValue. template -- cgit v1.2.3