summaryrefslogtreecommitdiff
path: root/js/src/gc/Barrier.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/gc/Barrier.h')
-rw-r--r--js/src/gc/Barrier.h79
1 files changed, 48 insertions, 31 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 */