summaryrefslogtreecommitdiff
path: root/js/src/gc
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/gc')
-rw-r--r--js/src/gc/Barrier.h79
-rw-r--r--js/src/gc/Heap.h7
-rw-r--r--js/src/gc/Marking.cpp2
-rw-r--r--js/src/gc/Marking.h8
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>