Bug 744192 - Assert that Vectors do not contain implicitly postbarriered types; r=luke
Since vectors move their memory around outside the control of the GC, it is not
valid to store an implicitly post-barriered item in a Vector.
--- a/js/public/TemplateLib.h
+++ b/js/public/TemplateLib.h
@@ -169,12 +169,17 @@ template <> struct IsPodType<bool>
template <> struct IsPodType<float> { static const bool result = true; };
template <> struct IsPodType<double> { static const bool result = true; };
template <> struct IsPodType<wchar_t> { static const bool result = true; };
template <typename T> struct IsPodType<T *> { static const bool result = true; };
template <bool cond, typename T, T v1, T v2> struct If { static const T result = v1; };
template <typename T, T v1, T v2> struct If<false, T, v1, v2> { static const T result = v2; };
+/*
+ * Traits class for identifying types that are implicitly barriered.
+ */
+template <class T> struct IsPostBarrieredType { static const bool result = false; };
+
} /* namespace tl */
} /* namespace js */
#endif /* js_template_lib_h__ */
--- a/js/public/Vector.h
+++ b/js/public/Vector.h
@@ -208,16 +208,18 @@ struct VectorImpl<T, N, AP, true>
* - see "Allocation policies" in jsalloc.h (default js::TempAllocPolicy)
*
* N.B: Vector is not reentrant: T member functions called during Vector member
* functions must not call back into the same object.
*/
template <class T, size_t N, class AllocPolicy>
class Vector : private AllocPolicy
{
+ typedef typename tl::StaticAssert<!tl::IsPostBarrieredType<T>::result>::result _;
+
/* utilities */
static const bool sElemIsPod = tl::IsPodType<T>::result;
typedef VectorImpl<T, N, AllocPolicy, sElemIsPod> Impl;
friend struct VectorImpl<T, N, AllocPolicy, sElemIsPod>;
bool calculateNewCapacity(size_t curLength, size_t lengthInc, size_t &newCap);
bool growStorageBy(size_t lengthInc);
@@ -500,17 +502,17 @@ class Vector : private AllocPolicy
*/
void erase(T *t);
/*
* Measure the size of the Vector's heap-allocated storage.
*/
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const;
- /*
+ /*
* Like sizeOfExcludingThis, but also measures the size of the Vector
* object (which must be heap-allocated) itself.
*/
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const;
};
/* This does the re-entrancy check plus several other sanity checks. */
#define REENTRANCY_GUARD_ET_AL \
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -504,11 +504,20 @@ class ReadBarrieredValue
ReadBarrieredValue(const Value &value) : value(value) {}
inline const Value &get() const;
inline operator const Value &() const;
inline JSObject &toObject() const;
};
-}
+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; };
+
+} /* namespace tl */
+} /* namespace js */
#endif /* jsgc_barrier_h___ */