diff options
author | Moonchild <moonchild@palemoon.org> | 2022-05-24 06:51:11 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2022-05-24 06:51:46 +0000 |
commit | dc5a60fb62a0f43fe77517bd0e46fe40358b44b0 (patch) | |
tree | cb5dcd22fb22fc292adaff89626c35e18e09a6be /js/src | |
parent | 1588077e629baa1c27e03149e39f06c265419e0b (diff) | |
download | uxp-dc5a60fb62a0f43fe77517bd0e46fe40358b44b0.tar.gz |
Issue #1742 - Part 1: Refactor rooting base class templates
Based on Bug 1325406
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/builtin/MapObject.h | 20 | ||||
-rw-r--r-- | js/src/ds/TraceableFifo.h | 54 | ||||
-rw-r--r-- | js/src/gc/Barrier.h | 25 | ||||
-rw-r--r-- | js/src/jsapi-tests/testGCExactRooting.cpp | 17 | ||||
-rw-r--r-- | js/src/jsapi.h | 44 | ||||
-rw-r--r-- | js/src/jscompartment.cpp | 5 | ||||
-rw-r--r-- | js/src/jsobj.h | 14 | ||||
-rw-r--r-- | js/src/vm/ArrayBufferObject.cpp | 4 | ||||
-rw-r--r-- | js/src/vm/ArrayBufferObject.h | 17 | ||||
-rw-r--r-- | js/src/vm/Interpreter.cpp | 14 | ||||
-rw-r--r-- | js/src/vm/JSONParser.h | 9 | ||||
-rw-r--r-- | js/src/vm/SavedStacks.h | 51 | ||||
-rw-r--r-- | js/src/vm/Scope.h | 96 | ||||
-rw-r--r-- | js/src/vm/Shape.h | 33 | ||||
-rw-r--r-- | js/src/vm/TaggedProto.h | 18 |
15 files changed, 144 insertions, 277 deletions
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<HashableValue> { +template <typename Wrapper> +class WrappedPtrOperations<HashableValue, Wrapper> +{ public: - MOZ_MUST_USE bool setValue(JSContext* cx, HandleValue v) { - return static_cast<JS::Rooted<HashableValue>*>(this)->get().setValue(cx, v); - } Value value() const { - return static_cast<const JS::Rooted<HashableValue>*>(this)->get().get(); + return static_cast<const Wrapper*>(this)->get().get(); + } +}; + +template <typename Wrapper> +class MutableWrappedPtrOperations<HashableValue, Wrapper> + : public WrappedPtrOperations<HashableValue, Wrapper> +{ + public: + MOZ_MUST_USE bool setValue(JSContext* cx, HandleValue v) { + return static_cast<Wrapper*>(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<T, MinInlineCapacity, AllocPolicy> } }; -template <typename Outer, typename T, size_t Capacity, typename AllocPolicy> -class TraceableFifoOperations +template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy> +class WrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, Wrapper> { using TF = TraceableFifo<T, Capacity, AllocPolicy>; - const TF& fifo() const { return static_cast<const Outer*>(this)->extract(); } + const TF& fifo() const { return static_cast<const Wrapper*>(this)->get(); } public: size_t length() const { return fifo().length(); } @@ -63,12 +63,12 @@ class TraceableFifoOperations const T& front() const { return fifo().front(); } }; -template <typename Outer, typename T, size_t Capacity, typename AllocPolicy> -class MutableTraceableFifoOperations - : public TraceableFifoOperations<Outer, T, Capacity, AllocPolicy> +template <typename Wrapper, typename T, size_t Capacity, typename AllocPolicy> +class MutableWrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, Wrapper> + : public WrappedPtrOperations<TraceableFifo<T, Capacity, AllocPolicy>, Wrapper> { using TF = TraceableFifo<T, Capacity, AllocPolicy>; - TF& fifo() { return static_cast<Outer*>(this)->extract(); } + TF& fifo() { return static_cast<Wrapper*>(this)->get(); } public: T& front() { return fifo().front(); } @@ -82,46 +82,6 @@ class MutableTraceableFifoOperations void clear() { fifo().clear(); } }; -template <typename A, size_t B, typename C> -class RootedBase<TraceableFifo<A,B,C>> - : public MutableTraceableFifoOperations<JS::Rooted<TraceableFifo<A,B,C>>, A,B,C> -{ - using TF = TraceableFifo<A,B,C>; - - friend class TraceableFifoOperations<JS::Rooted<TF>, A,B,C>; - const TF& extract() const { return *static_cast<const JS::Rooted<TF>*>(this)->address(); } - - friend class MutableTraceableFifoOperations<JS::Rooted<TF>, A,B,C>; - TF& extract() { return *static_cast<JS::Rooted<TF>*>(this)->address(); } -}; - -template <typename A, size_t B, typename C> -class MutableHandleBase<TraceableFifo<A,B,C>> - : public MutableTraceableFifoOperations<JS::MutableHandle<TraceableFifo<A,B,C>>, A,B,C> -{ - using TF = TraceableFifo<A,B,C>; - - friend class TraceableFifoOperations<JS::MutableHandle<TF>, A,B,C>; - const TF& extract() const { - return *static_cast<const JS::MutableHandle<TF>*>(this)->address(); - } - - friend class MutableTraceableFifoOperations<JS::MutableHandle<TF>, A,B,C>; - TF& extract() { return *static_cast<JS::MutableHandle<TF>*>(this)->address(); } -}; - -template <typename A, size_t B, typename C> -class HandleBase<TraceableFifo<A,B,C>> - : public TraceableFifoOperations<JS::Handle<TraceableFifo<A,B,C>>, A,B,C> -{ - using TF = TraceableFifo<A,B,C>; - - friend class TraceableFifoOperations<JS::Handle<TF>, A,B,C>; - const TF& extract() const { - return *static_cast<const JS::Handle<TF>*>(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<jsid> 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 <typename T> -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 <typename T> -class MOZ_NON_MEMMOVABLE BarrieredBase : public BarrieredBaseMixins<T> +class MOZ_NON_MEMMOVABLE BarrieredBase { protected: // BarrieredBase is not directly instantiable. @@ -356,9 +350,12 @@ class MOZ_NON_MEMMOVABLE BarrieredBase : public BarrieredBaseMixins<T> // Base class for barriered pointer types that intercept only writes. template <class T> -class WriteBarrieredBase : public BarrieredBase<T> +class WriteBarrieredBase : public BarrieredBase<T>, + public WrappedPtrOperations<T, WriteBarrieredBase<T>> { protected: + using BarrieredBase<T>::value; + // WriteBarrieredBase is not directly instantiable. explicit WriteBarrieredBase(const T& v) : BarrieredBase<T>(v) {} @@ -580,8 +577,12 @@ class ReadBarrieredBase : public BarrieredBase<T> // insert manual post-barriers on the table for rekeying if the key is based in // any way on the address of the object. template <typename T> -class ReadBarriered : public ReadBarrieredBase<T> +class ReadBarriered : public ReadBarrieredBase<T>, + public WrappedPtrOperations<T, ReadBarriered<T>> { + protected: + using ReadBarrieredBase<T>::value; + public: ReadBarriered() : ReadBarrieredBase<T>(JS::GCPolicy<T>::initial()) {} @@ -649,12 +650,6 @@ class ReadBarriered : public ReadBarrieredBase<T> template <typename T> using WeakRef = ReadBarriered<T>; -// 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<JS::Value> : public ValueOperations<WriteBarrieredBase<JS::Value>> -{}; - // 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<MyContainer> { - HeapPtr<JSObject*>& obj() { return static_cast<Rooted<MyContainer>*>(this)->get().obj; } - HeapPtr<JSString*>& str() { return static_cast<Rooted<MyContainer>*>(this)->get().str; } -}; -template <> -struct PersistentRootedBase<MyContainer> { - HeapPtr<JSObject*>& obj() { - return static_cast<PersistentRooted<MyContainer>*>(this)->get().obj; - } - HeapPtr<JSString*>& str() { - return static_cast<PersistentRooted<MyContainer>*>(this)->get().str; - } +template <typename Wrapper> +struct MutableWrappedPtrOperations<MyContainer, Wrapper> { + HeapPtr<JSObject*>& obj() { return static_cast<Wrapper*>(this)->get().obj; } + HeapPtr<JSString*>& str() { return static_cast<Wrapper*>(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 <typename Outer> -class PropertyDescriptorOperations +} // namespace JS + +namespace js { + +template <typename Wrapper> +class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper> { - const PropertyDescriptor& desc() const { return static_cast<const Outer*>(this)->get(); } + const JS::PropertyDescriptor& desc() const { return static_cast<const Wrapper*>(this)->get(); } bool has(unsigned bit) const { MOZ_ASSERT(bit != 0); @@ -2678,10 +2682,11 @@ class PropertyDescriptorOperations } }; -template <typename Outer> -class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer> +template <typename Wrapper> +class MutableWrappedPtrOperations<JS::PropertyDescriptor, Wrapper> + : public js::WrappedPtrOperations<JS::PropertyDescriptor, Wrapper> { - PropertyDescriptor& desc() { return static_cast<Outer*>(this)->get(); } + JS::PropertyDescriptor& desc() { return static_cast<Wrapper*>(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<JS::PropertyDescriptor> - : public JS::MutablePropertyDescriptorOperations<JS::Rooted<JS::PropertyDescriptor>> -{}; - -template <> -class HandleBase<JS::PropertyDescriptor> - : public JS::PropertyDescriptorOperations<JS::Handle<JS::PropertyDescriptor>> -{}; - -template <> -class MutableHandleBase<JS::PropertyDescriptor> - : public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JS::PropertyDescriptor>> -{}; - -} /* 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 <class U> +template <typename Wrapper> +template <typename U> MOZ_ALWAYS_INLINE JS::Handle<U*> -js::RootedBase<JSObject*>::as() const +js::RootedBase<JSObject*, Wrapper>::as() const { - const JS::Rooted<JSObject*>& self = *static_cast<const JS::Rooted<JSObject*>*>(this); - MOZ_ASSERT(self->is<U>()); + const Wrapper& self = *static_cast<const Wrapper*>(this); + MOZ_ASSERT(self->template is<U>()); return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address())); } +template <typename Wrapper> template <class U> MOZ_ALWAYS_INLINE JS::Handle<U*> -js::HandleBase<JSObject*>::as() const +js::HandleBase<JSObject*, Wrapper>::as() const { const JS::Handle<JSObject*>& self = *static_cast<const JS::Handle<JSObject*>*>(this); - MOZ_ASSERT(self->is<U>()); + MOZ_ASSERT(self->template is<U>()); return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(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<ArrayBufferObject*> 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<ArrayBufferViewObject*, 1, SystemAllocPolicy> ViewVector; friend class ArrayBufferObject; - friend class WeakCacheBase<InnerViewTable>; private: struct MapGCPolicy { @@ -602,23 +601,15 @@ class InnerViewTable size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); }; -template <> -class WeakCacheBase<InnerViewTable> +template <typename Wrapper> +class MutableWrappedPtrOperations<InnerViewTable, Wrapper> + : public WrappedPtrOperations<InnerViewTable, Wrapper> { InnerViewTable& table() { - return static_cast<JS::WeakCache<InnerViewTable>*>(this)->get(); - } - const InnerViewTable& table() const { - return static_cast<const JS::WeakCache<InnerViewTable>*>(this)->get(); + return static_cast<Wrapper*>(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<typename T> -class ReservedRootedBase { -}; - -template<typename T> -class ReservedRooted : public ReservedRootedBase<T> +class ReservedRooted : public RootedBase<T, ReservedRooted<T>> { Rooted<T>* savedRoot; @@ -1645,14 +1641,6 @@ class ReservedRooted : public ReservedRootedBase<T> DECLARE_POINTER_ASSIGN_OPS(ReservedRooted, T) }; -template <> -class ReservedRootedBase<Value> : public ValueOperations<ReservedRooted<Value>> -{}; - -template <> -class ReservedRootedBase<Scope*> : public ScopeCastOperation<ReservedRooted<Scope*>> -{}; - 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 <typename CharT> -struct RootedBase<JSONParser<CharT>> { +template <typename CharT, typename Wrapper> +class MutableWrappedPtrOperations<JSONParser<CharT>, Wrapper> + : public WrappedPtrOperations<JSONParser<CharT>, Wrapper> +{ + public: bool parse(MutableHandleValue vp) { - return static_cast<Rooted<JSONParser<CharT>>*>(this)->get().parse(vp); + return static_cast<Wrapper*>(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 <typename Outer> - 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<const Outer*>(this)->get(); } - }; - - template <typename Outer> - struct MutableLocationValueOperations : public LocationValueOperations<Outer> { - 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<Outer*>(this)->get(); } - }; - private: struct PCLocationHasher : public DefaultHasher<PCKey> { using ScriptPtrHasher = DefaultHasher<JSScript*>; @@ -313,15 +295,32 @@ class SavedStacks { MutableHandle<LocationValue> locationp); }; -template <> -class RootedBase<SavedStacks::LocationValue> - : public SavedStacks::MutableLocationValueOperations<JS::Rooted<SavedStacks::LocationValue>> -{}; +template <typename Wrapper> +struct WrappedPtrOperations<SavedStacks::LocationValue, Wrapper> +{ + 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<const Wrapper*>(this)->get(); + } +}; + +template <typename Wrapper> +struct MutableWrappedPtrOperations<SavedStacks::LocationValue, Wrapper> + : public WrappedPtrOperations<SavedStacks::LocationValue, Wrapper> +{ + 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<SavedStacks::LocationValue> - : public SavedStacks::MutableLocationValueOperations<JS::MutableHandle<SavedStacks::LocationValue>> -{}; + private: + SavedStacks::LocationValue& loc() { + return static_cast<Wrapper*>(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 { @@ -224,6 +225,21 @@ class BindingLocation }; // +// Allow using is<T> and as<T> on Rooted<Scope*> and Handle<Scope*>. +// +template <typename Wrapper> +class WrappedPtrOperations<Scope*, Wrapper> +{ + public: + template <class U> + JS::Handle<U*> as() const { + const Wrapper& self = *static_cast<const Wrapper*>(this); + MOZ_ASSERT_IF(self, self->template is<U>()); + return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address())); + } +}; + +// // The base class of all Scopes. // class Scope : public js::gc::TenuredCell @@ -1338,10 +1354,10 @@ class MOZ_STACK_CLASS ScopeIter // Specializations of Rooted containers for the iterators. // -template <typename Outer> -class BindingIterOperations +template <typename Wrapper> +class WrappedPtrOperations<BindingIter, Wrapper> { - const BindingIter& iter() const { return static_cast<const Outer*>(this)->get(); } + const BindingIter& iter() const { return static_cast<const Wrapper*>(this)->get(); } public: bool done() const { return iter().done(); } @@ -1361,19 +1377,20 @@ class BindingIterOperations uint32_t nextEnvironmentSlot() const { return iter().nextEnvironmentSlot(); } }; -template <typename Outer> -class MutableBindingIterOperations : public BindingIterOperations<Outer> +template <typename Wrapper> +class MutableWrappedPtrOperations<BindingIter, Wrapper> + : public WrappedPtrOperations<BindingIter, Wrapper> { - BindingIter& iter() { return static_cast<Outer*>(this)->get(); } + BindingIter& iter() { return static_cast<Wrapper*>(this)->get(); } public: void operator++(int) { iter().operator++(1); } }; -template <typename Outer> -class ScopeIterOperations +template <typename Wrapper> +class WrappedPtrOperations<ScopeIter, Wrapper> { - const ScopeIter& iter() const { return static_cast<const Outer*>(this)->get(); } + const ScopeIter& iter() const { return static_cast<const Wrapper*>(this)->get(); } public: bool done() const { return iter().done(); } @@ -1384,69 +1401,16 @@ class ScopeIterOperations bool hasSyntacticEnvironment() const { return iter().hasSyntacticEnvironment(); } }; -template <typename Outer> -class MutableScopeIterOperations : public ScopeIterOperations<Outer> +template <typename Wrapper> +class MutableWrappedPtrOperations<ScopeIter, Wrapper> + : public WrappedPtrOperations<ScopeIter, Wrapper> { - ScopeIter& iter() { return static_cast<Outer*>(this)->get(); } + ScopeIter& iter() { return static_cast<Wrapper*>(this)->get(); } public: void operator++(int) { iter().operator++(1); } }; -#define SPECIALIZE_ROOTING_CONTAINERS(Iter, BaseIter) \ - template <> \ - class RootedBase<Iter> \ - : public Mutable##BaseIter##Operations<JS::Rooted<Iter>> \ - { }; \ - \ - template <> \ - class MutableHandleBase<Iter> \ - : public Mutable##BaseIter##Operations<JS::MutableHandle<Iter>> \ - { }; \ - \ - template <> \ - class HandleBase<Iter> \ - : public BaseIter##Operations<JS::Handle<Iter>> \ - { }; \ - \ - template <> \ - class PersistentRootedBase<Iter> \ - : public Mutable##BaseIter##Operations<JS::PersistentRooted<Iter>> \ - { } - -SPECIALIZE_ROOTING_CONTAINERS(BindingIter, BindingIter); -SPECIALIZE_ROOTING_CONTAINERS(PositionalFormalParameterIter, BindingIter); -SPECIALIZE_ROOTING_CONTAINERS(ScopeIter, ScopeIter); - -#undef SPECIALIZE_ROOTING_CONTAINERS - -// -// Allow using is<T> and as<T> on Rooted<Scope*> and Handle<Scope*>. -// - -template <typename Outer> -struct ScopeCastOperation -{ - template <class U> - JS::Handle<U*> as() const { - const Outer& self = *static_cast<const Outer*>(this); - MOZ_ASSERT_IF(self, self->template is<U>()); - return Handle<U*>::fromMarkedLocation(reinterpret_cast<U* const*>(self.address())); - } -}; - -template <> -class RootedBase<Scope*> : public ScopeCastOperation<JS::Rooted<Scope*>> -{ }; - -template <> -class HandleBase<Scope*> : public ScopeCastOperation<JS::Handle<Scope*>> -{ }; - -template <> -class MutableHandleBase<Scope*> : public ScopeCastOperation<JS::MutableHandle<Scope*>> -{ }; - } // 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 <typename Outer> -class StackShapeOperations { - const StackShape& ss() const { return static_cast<const Outer*>(this)->get(); } +template <typename Wrapper> +class WrappedPtrOperations<StackShape, Wrapper> +{ + const StackShape& ss() const { return static_cast<const Wrapper*>(this)->get(); } public: bool hasSlot() const { return ss().hasSlot(); } @@ -1370,9 +1372,11 @@ class StackShapeOperations { uint8_t attrs() const { return ss().attrs; } }; -template <typename Outer> -class MutableStackShapeOperations : public StackShapeOperations<Outer> { - StackShape& ss() { return static_cast<Outer*>(this)->get(); } +template <typename Wrapper> +class MutableWrappedPtrOperations<StackShape, Wrapper> + : public WrappedPtrOperations<StackShape, Wrapper> +{ + StackShape& ss() { return static_cast<Wrapper*>(this)->get(); } public: void updateGetterSetter(GetterOp rawGetter, SetterOp rawSetter) { @@ -1383,19 +1387,6 @@ class MutableStackShapeOperations : public StackShapeOperations<Outer> { void setAttrs(uint8_t attrs) { ss().attrs = attrs; } }; -template <> -class RootedBase<StackShape> : public MutableStackShapeOperations<JS::Rooted<StackShape>> -{}; - -template <> -class HandleBase<StackShape> : public StackShapeOperations<JS::Handle<StackShape>> -{}; - -template <> -class MutableHandleBase<StackShape> - : public MutableStackShapeOperations<JS::MutableHandle<StackShape>> -{}; - 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<TaggedProto> } }; -template<class Outer> -class TaggedProtoOperations +template <class Wrapper> +class WrappedPtrOperations<TaggedProto, Wrapper> { const TaggedProto& value() const { - return static_cast<const Outer*>(this)->get(); + return static_cast<const Wrapper*>(this)->get(); } public: @@ -95,18 +95,6 @@ class TaggedProtoOperations uint64_t uniqueId() const { return value().uniqueId(); } }; -template <> -class HandleBase<TaggedProto> : public TaggedProtoOperations<Handle<TaggedProto>> -{}; - -template <> -class RootedBase<TaggedProto> : public TaggedProtoOperations<Rooted<TaggedProto>> -{}; - -template <> -class BarrieredBaseMixins<TaggedProto> : public TaggedProtoOperations<GCPtr<TaggedProto>> -{}; - // 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 <typename F, typename... Args> |