diff options
Diffstat (limited to 'js/src/gc')
-rw-r--r-- | js/src/gc/Barrier.h | 79 | ||||
-rw-r--r-- | js/src/gc/Heap.h | 7 | ||||
-rw-r--r-- | js/src/gc/Marking.cpp | 2 | ||||
-rw-r--r-- | js/src/gc/Marking.h | 8 |
4 files changed, 50 insertions, 46 deletions
diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 681ccc9c4..345131a29 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 */ diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 2a1042094..e97aec746 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -315,10 +315,6 @@ class TenuredCell : public Cell MOZ_ALWAYS_INLINE void unmark(uint32_t color) const; MOZ_ALWAYS_INLINE void copyMarkBitsFrom(const TenuredCell* src); - // Note: this is in TenuredCell because JSObject subclasses are sometimes - // used tagged. - static MOZ_ALWAYS_INLINE bool isNullLike(const Cell* thing) { return !thing; } - // Access to the arena. inline Arena* arena() const; inline AllocKind getAllocKind() const; @@ -1300,7 +1296,7 @@ TenuredCell::isInsideZone(JS::Zone* zone) const TenuredCell::readBarrier(TenuredCell* thing) { MOZ_ASSERT(!CurrentThreadIsIonCompiling()); - MOZ_ASSERT(!isNullLike(thing)); + MOZ_ASSERT(thing); // It would be good if barriers were never triggered during collection, but // at the moment this can happen e.g. when rekeying tables containing @@ -1333,7 +1329,6 @@ AssertSafeToSkipBarrier(TenuredCell* thing); TenuredCell::writeBarrierPre(TenuredCell* thing) { MOZ_ASSERT(!CurrentThreadIsIonCompiling()); - MOZ_ASSERT_IF(thing, !isNullLike(thing)); if (!thing) return; diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 241a1df20..da8da5c6b 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -501,7 +501,7 @@ void js::TraceNullableRoot(JSTracer* trc, T* thingp, const char* name) { AssertRootMarkingPhase(trc); - if (InternalBarrierMethods<T>::isMarkableTaggedPointer(*thingp)) + if (InternalBarrierMethods<T>::isMarkable(*thingp)) DispatchToTracer(trc, ConvertToBase(thingp), name); } diff --git a/js/src/gc/Marking.h b/js/src/gc/Marking.h index 2b9e7ace1..40b331b31 100644 --- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -414,14 +414,6 @@ ToMarkable(Cell* cell) return cell; } -// Return true if the pointer is nullptr, or if it is a tagged pointer to -// nullptr. -MOZ_ALWAYS_INLINE bool -IsNullTaggedPointer(void* p) -{ - return uintptr_t(p) <= LargestTaggedNullCellPointer; -} - // Wrap a GC thing pointer into a new Value or jsid. The type system enforces // that the thing pointer is a wrappable type. template <typename S, typename T> |