diff --git a/js/public/TemplateLib.h b/js/public/TemplateLib.h index 9010b10f72f306a6e8eae1d16b8aaaea288f9573..299547964f882337b64456b4c14cac5e5bed890b 100644 --- a/js/public/TemplateLib.h +++ b/js/public/TemplateLib.h @@ -177,7 +177,7 @@ template <typename T, T v1, T v2> struct If<false, T, v1, v2> { static const T r /* * Traits class for identifying types that are implicitly barriered. */ -template <class T> struct IsPostBarrieredType { static const bool result = false; }; +template <class T> struct IsRelocatableHeapType { static const bool result = true; }; } /* namespace tl */ } /* namespace js */ diff --git a/js/public/Vector.h b/js/public/Vector.h index e2d91349ea276ef3ba4f9e50ca99d37c65c25378..8fe787036efac7b4d69d26ca5a6b6fa79a974a53 100644 --- a/js/public/Vector.h +++ b/js/public/Vector.h @@ -213,7 +213,7 @@ struct VectorImpl<T, N, AP, true> template <class T, size_t N, class AllocPolicy> class Vector : private AllocPolicy { - typedef typename tl::StaticAssert<!tl::IsPostBarrieredType<T>::result>::result _; + typedef typename tl::StaticAssert<tl::IsRelocatableHeapType<T>::result>::result _; /* utilities */ diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 61337e18afd13c078861cf10635bcf62a20154fc..afb85e3d3579c8b86cbf3d0ae1d2500d9beaaf67 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -151,31 +151,39 @@ struct JSXML; namespace js { template<class T, typename Unioned = uintptr_t> -class HeapPtr +class EncapsulatedPtr { + protected: union { T *value; Unioned other; }; public: - HeapPtr() : value(NULL) {} - explicit HeapPtr(T *v) : value(v) { post(); } - explicit HeapPtr(const HeapPtr<T> &v) : value(v.value) { post(); } + EncapsulatedPtr() : value(NULL) {} + explicit EncapsulatedPtr(T *v) : value(v) {} + explicit EncapsulatedPtr(const EncapsulatedPtr<T> &v) : value(v.value) {} - ~HeapPtr() { pre(); } + ~EncapsulatedPtr() { pre(); } - /* Use this to install a ptr into a newly allocated object. */ - void init(T *v) { + /* Use to set the pointer to NULL. */ + void clear() { + pre(); + value = NULL; + } + + EncapsulatedPtr<T, Unioned> &operator=(T *v) { + pre(); JS_ASSERT(!IsPoisonedPtr<T>(v)); value = v; - post(); + return *this; } - /* Use to set the pointer to NULL. */ - void clear() { - pre(); - value = NULL; + EncapsulatedPtr<T, Unioned> &operator=(const EncapsulatedPtr<T> &v) { + pre(); + JS_ASSERT(!IsPoisonedPtr<T>(v.value)); + value = v.value; + return *this; } /* Use this if the automatic coercion to T* isn't working. */ @@ -190,30 +198,48 @@ class HeapPtr Unioned *unsafeGetUnioned() { return &other; } + T &operator*() const { return *value; } + T *operator->() const { return value; } + + operator T*() const { return value; } + + protected: + void pre() { T::writeBarrierPre(value); } +}; + +template <class T, class Unioned = uintptr_t> +class HeapPtr : public EncapsulatedPtr<T, Unioned> +{ + public: + HeapPtr() : EncapsulatedPtr<T>(NULL) {} + explicit HeapPtr(T *v) : EncapsulatedPtr<T>(v) { post(); } + explicit HeapPtr(const HeapPtr<T> &v) + : EncapsulatedPtr<T>(v) { post(); } + + void init(T *v) { + JS_ASSERT(!IsPoisonedPtr<T>(v)); + this->value = v; + post(); + } + HeapPtr<T, Unioned> &operator=(T *v) { - pre(); + this->pre(); JS_ASSERT(!IsPoisonedPtr<T>(v)); - value = v; + this->value = v; post(); return *this; } HeapPtr<T, Unioned> &operator=(const HeapPtr<T> &v) { - pre(); + this->pre(); JS_ASSERT(!IsPoisonedPtr<T>(v.value)); - value = v.value; + this->value = v.value; post(); return *this; } - T &operator*() const { return *value; } - T *operator->() const { return value; } - - operator T*() const { return value; } - - private: - void pre() { T::writeBarrierPre(value); } - void post() { T::writeBarrierPost(value, (void *)&value); } + protected: + void post() { T::writeBarrierPost(this->value, (void *)&this->value); } /* Make this friend so it can access pre() and post(). */ template<class T1, class T2> @@ -223,6 +249,41 @@ class HeapPtr HeapPtr<T2> &v2, T2 *val2); }; +template <class T> +class RelocatablePtr : public EncapsulatedPtr<T> +{ + public: + RelocatablePtr() : EncapsulatedPtr<T>(NULL) {} + explicit RelocatablePtr(T *v) : EncapsulatedPtr<T>(v) { post(); } + explicit RelocatablePtr(const RelocatablePtr<T> &v) + : EncapsulatedPtr<T>(v) { post(); } + + ~RelocatablePtr() { + this->pre(); + relocate(); + } + + RelocatablePtr<T> &operator=(T *v) { + this->pre(); + JS_ASSERT(!IsPoisonedPtr<T>(v)); + this->value = v; + post(); + return *this; + } + + RelocatablePtr<T> &operator=(const RelocatablePtr<T> &v) { + this->pre(); + JS_ASSERT(!IsPoisonedPtr<T>(v.value)); + this->value = v.value; + post(); + return *this; + } + + protected: + void post() { T::writeBarrierRelocPost(this->value, (void *)&this->value); } + void relocate() { T::writeBarrierRelocated(this->value, (void *)&this->value); } +}; + /* * This is a hack for RegExpStatics::updateFromMatch. It allows us to do two * barriers with only one branch to check if we're in an incremental GC. @@ -247,6 +308,9 @@ struct Shape; class BaseShape; namespace types { struct TypeObject; } +typedef RelocatablePtr<JSObject> RelocatablePtrObject; +typedef RelocatablePtr<JSScript> RelocatablePtrScript; + typedef HeapPtr<JSObject> HeapPtrObject; typedef HeapPtr<JSFunction> HeapPtrFunction; typedef HeapPtr<JSString> HeapPtrString; @@ -269,7 +333,7 @@ struct HeapPtrHasher /* Specialized hashing policy for HeapPtrs. */ template <class T> -struct DefaultHasher< HeapPtr<T> >: HeapPtrHasher<T> { }; +struct DefaultHasher< HeapPtr<T> > : HeapPtrHasher<T> { }; class EncapsulatedValue { @@ -376,9 +440,6 @@ class RelocatableValue : public EncapsulatedValue inline RelocatableValue &operator=(const Value &v); inline RelocatableValue &operator=(const RelocatableValue &v); - static inline void writeBarrierPost(const Value &v, Value *addr); - static inline void writeBarrierPost(JSCompartment *comp, const Value &v, Value *addr); - private: inline void post(); inline void post(JSCompartment *comp); @@ -421,7 +482,7 @@ class HeapSlot : public EncapsulatedValue * Run a post write barrier that encompasses multiple contiguous slots in a * single step. */ -static inline void +inline void SlotRangeWriteBarrierPost(JSCompartment *comp, JSObject *obj, uint32_t start, uint32_t count) { } @@ -556,11 +617,11 @@ class ReadBarrieredValue namespace tl { -template <class T> struct IsPostBarrieredType<HeapPtr<T> > { - static const bool result = true; }; -template <> struct IsPostBarrieredType<HeapSlot> { static const bool result = true; }; -template <> struct IsPostBarrieredType<HeapValue> { static const bool result = true; }; -template <> struct IsPostBarrieredType<HeapId> { static const bool result = true; }; +template <class T> struct IsRelocatableHeapType<HeapPtr<T> > + { static const bool result = false; }; +template <> struct IsRelocatableHeapType<HeapSlot> { static const bool result = false; }; +template <> struct IsRelocatableHeapType<HeapValue> { static const bool result = false; }; +template <> struct IsRelocatableHeapType<HeapId> { static const bool result = false; }; } /* namespace tl */ } /* namespace js */