Bug 744192 - Assert that Vectors do not contain implicitly postbarriered types; r=luke
authorTerrence Cole <terrence@mozilla.com>
Wed, 11 Apr 2012 17:14:11 -0700
changeset 94803 380e6f8bd681ee99176bbb08c05f490cbe6593ee
parent 94802 9c0ffa4a064521a799fe1a0beed08bb33ddbbe06
child 94804 bfa27d58769d5c1d83a2b6d3f6e52d2e98443884
push idunknown
push userunknown
push dateunknown
reviewersluke
bugs744192
milestone14.0a1
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.
js/public/TemplateLib.h
js/public/Vector.h
js/src/gc/Barrier.h
--- 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___ */