diff options
Diffstat (limited to 'js/src/gc/Barrier.h')
-rw-r--r-- | js/src/gc/Barrier.h | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 681ccc9c4c..345131a296 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -261,8 +261,6 @@ struct InternalBarrierMethods<T*> { static bool isMarkable(T* v) { return v != nullptr; } - static bool isMarkableTaggedPointer(T* v) { return !IsNullTaggedPointer(v); } - static void preBarrier(T* v) { T::writeBarrierPre(v); } static void postBarrier(T** vp, T* prev, T* next) { T::writeBarrierPost(vp, prev, next); } @@ -282,7 +280,6 @@ template <> struct InternalBarrierMethods<Value> { static bool isMarkable(const Value& v) { return v.isGCThing(); } - static bool isMarkableTaggedPointer(const Value& v) { return isMarkable(v); } static void preBarrier(const Value& v) { DispatchTyped(PreBarrierFunctor<Value>(), v); @@ -318,24 +315,17 @@ template <> struct InternalBarrierMethods<jsid> { static bool isMarkable(jsid id) { return JSID_IS_GCTHING(id); } - static bool isMarkableTaggedPointer(jsid id) { return isMarkable(id); } static void preBarrier(jsid id) { DispatchTyped(PreBarrierFunctor<jsid>(), id); } 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,14 +346,18 @@ 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) {} public: - DECLARE_POINTER_COMPARISON_OPS(T); + using ElementType = T; + DECLARE_POINTER_CONSTREF_OPS(T); // Use this if the automatic coercion to T isn't working. @@ -460,10 +454,6 @@ class GCPtr : public WriteBarrieredBase<T> DECLARE_POINTER_ASSIGN_OPS(GCPtr, T); - T unbarrieredGet() const { - return this->value; - } - private: void set(const T& v) { this->pre(); @@ -580,8 +570,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()) {} @@ -614,14 +608,13 @@ class ReadBarriered : public ReadBarrieredBase<T> return *this; } - const T get() const { - if (!InternalBarrierMethods<T>::isMarkable(this->value)) - return JS::GCPolicy<T>::initial(); - this->read(); + const T& get() const { + if (InternalBarrierMethods<T>::isMarkable(this->value)) + this->read(); return this->value; } - const T unbarrieredGet() const { + const T& unbarrieredGet() const { return this->value; } @@ -629,9 +622,9 @@ class ReadBarriered : public ReadBarrieredBase<T> return bool(this->value); } - operator const T() const { return get(); } + operator const T&() const { return get(); } - const T operator->() const { return get(); } + const T& operator->() const { return get(); } T* unsafeGet() { return &this->value; } T const* unsafeGet() const { return &this->value; } @@ -649,12 +642,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. @@ -943,6 +930,36 @@ typedef ReadBarriered<WasmTableObject*> ReadBarrieredWasmTableObject; typedef ReadBarriered<Value> ReadBarrieredValue; +namespace detail { + +template <typename T> +struct DefineComparisonOps<PreBarriered<T>> : mozilla::TrueType { + static const T& get(const PreBarriered<T>& v) { return v.get(); } +}; + +template <typename T> +struct DefineComparisonOps<GCPtr<T>> : mozilla::TrueType { + static const T& get(const GCPtr<T>& v) { return v.get(); } +}; + +template <typename T> +struct DefineComparisonOps<HeapPtr<T>> : mozilla::TrueType { + static const T& get(const HeapPtr<T>& v) { return v.get(); } +}; + +template <typename T> +struct DefineComparisonOps<ReadBarriered<T>> : mozilla::TrueType { + static const T& get(const ReadBarriered<T>& v) { return v.unbarrieredGet(); } +}; + +template <> +struct DefineComparisonOps<HeapSlot> : mozilla::TrueType { + static const Value& get(const HeapSlot& v) { return v.get(); } +}; + +} /* namespace detail */ + + } /* namespace js */ #endif /* gc_Barrier_h */ |