Bug 1297244 - Assert on the type given as a parameter to Heap. r=terrence
authorLeo Gaspard <leo@gaspard.io>
Wed, 24 Aug 2016 14:21:42 -0700
changeset 311258 96281cc98bc619164580b33340e116318c94de2a
parent 311257 7785b40af14f91910ad30c731212e5bdbb50bb09
child 311259 60c2eb2aaf6d3d7b0b1e40613a6db7dfa203dfe6
push id81080
push userryanvm@gmail.com
push dateFri, 26 Aug 2016 01:42:06 +0000
treeherdermozilla-inbound@e59fbcb1da07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1297244
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1297244 - Assert on the type given as a parameter to Heap. r=terrence
dom/xbl/nsXBLMaybeCompiled.h
js/public/GCPolicyAPI.h
js/public/RootingAPI.h
js/src/gc/Marking.cpp
js/src/gc/Policy.h
--- a/dom/xbl/nsXBLMaybeCompiled.h
+++ b/dom/xbl/nsXBLMaybeCompiled.h
@@ -111,16 +111,22 @@ struct BarrierMethods<nsXBLMaybeCompiled
     } else if (prev.IsCompiled()) {
       Base::postBarrier(&prev.UnsafeGetJSFunction(),
                         prev.UnsafeGetJSFunction(),
                         nullptr);
     }
   }
 };
 
+template <class T>
+struct IsHeapConstructibleType<nsXBLMaybeCompiled<T>>
+{ // Yes, this is the exception to the rule. Sorry.
+  static constexpr bool value = true;
+};
+
 template <class UncompiledT>
 class HeapBase<nsXBLMaybeCompiled<UncompiledT>>
 {
   const JS::Heap<nsXBLMaybeCompiled<UncompiledT>>& wrapper() const {
     return *static_cast<const JS::Heap<nsXBLMaybeCompiled<UncompiledT>>*>(this);
   }
 
   JS::Heap<nsXBLMaybeCompiled<UncompiledT>>& wrapper() {
--- a/js/public/GCPolicyAPI.h
+++ b/js/public/GCPolicyAPI.h
@@ -40,16 +40,33 @@
 #ifndef GCPolicyAPI_h
 #define GCPolicyAPI_h
 
 #include "mozilla/UniquePtr.h"
 
 #include "js/TraceKind.h"
 #include "js/TracingAPI.h"
 
+// Expand the given macro D for each public GC pointer.
+#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
+    D(JS::Symbol*) \
+    D(JSAtom*) \
+    D(JSFunction*) \
+    D(JSObject*) \
+    D(JSScript*) \
+    D(JSString*)
+
+// Expand the given macro D for each public tagged GC pointer type.
+#define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \
+    D(JS::Value) \
+    D(jsid)
+
+#define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \
+    D(JSPropertyDescriptor)
+
 class JSAtom;
 class JSFunction;
 class JSObject;
 class JSScript;
 class JSString;
 namespace JS {
 class Symbol;
 }
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -9,16 +9,18 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/Move.h"
 #include "mozilla/TypeTraits.h"
 
+#include <type_traits>
+
 #include "jspubtd.h"
 
 #include "js/GCAnnotations.h"
 #include "js/GCAPI.h"
 #include "js/GCPolicyAPI.h"
 #include "js/HeapAPI.h"
 #include "js/TypeDecls.h"
 #include "js/UniquePtr.h"
@@ -118,16 +120,24 @@ template <typename T>
 class HandleBase {};
 
 template <typename T>
 class MutableHandleBase {};
 
 template <typename T>
 class HeapBase {};
 
+// Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope
+template <typename T> struct IsHeapConstructibleType    { static constexpr bool value = false; };
+#define DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE(T) \
+    template <> struct IsHeapConstructibleType<T> { static constexpr bool value = true; };
+FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
+FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE)
+#undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE
+
 template <typename T>
 class PersistentRootedBase {};
 
 static void* const ConstNullValue = nullptr;
 
 namespace gc {
 struct Cell;
 template<typename T>
@@ -209,21 +219,24 @@ AssertGCThingIsNotAnObjectSubclass(js::g
  * which keeps track of all pointers into the nursery.
  *
  * Heap<T> instances must be traced when their containing object is traced to
  * keep the pointed-to GC thing alive.
  *
  * Heap<T> objects should only be used on the heap. GC references stored on the
  * C/C++ stack must use Rooted/Handle/MutableHandle instead.
  *
- * Type T must be one of: JS::Value, jsid, JSObject*, JSString*, JSScript*
+ * Type T must be a public GC pointer type.
  */
 template <typename T>
 class Heap : public js::HeapBase<T>
 {
+    // Please note: this can actually also be used by nsXBLMaybeCompiled<T>, for legacy reasons.
+    static_assert(js::IsHeapConstructibleType<T>::value,
+                  "Type T must be a public GC pointer type");
   public:
     Heap() {
         static_assert(sizeof(T) == sizeof(Heap<T>),
                       "Heap<T> must be binary compatible with T.");
         init(GCPolicy<T>::initial());
     }
     explicit Heap(T p) { init(p); }
 
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -2786,19 +2786,22 @@ EdgeNeedsSweep(JS::Heap<T>* thingp)
 }
 
 // Instantiate a copy of the Tracing templates for each derived type.
 #define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(type) \
     template bool IsMarkedUnbarriered<type>(type*); \
     template bool IsMarked<type>(WriteBarrieredBase<type>*); \
     template bool IsAboutToBeFinalizedUnbarriered<type>(type*); \
     template bool IsAboutToBeFinalized<type>(WriteBarrieredBase<type>*); \
-    template bool IsAboutToBeFinalized<type>(ReadBarrieredBase<type>*); \
+    template bool IsAboutToBeFinalized<type>(ReadBarrieredBase<type>*);
+#define INSTANTIATE_ALL_VALID_HEAP_TRACE_FUNCTIONS(type) \
     template JS_PUBLIC_API(bool) EdgeNeedsSweep<type>(JS::Heap<type>*);
 FOR_EACH_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS)
+FOR_EACH_PUBLIC_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_HEAP_TRACE_FUNCTIONS)
+FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_HEAP_TRACE_FUNCTIONS)
 #undef INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS
 
 } /* namespace gc */
 } /* namespace js */
 
 
 /*** Type Marking *********************************************************************************/
 
--- a/js/src/gc/Policy.h
+++ b/js/src/gc/Policy.h
@@ -53,33 +53,16 @@ class SharedArrayBufferObject;
 class StructTypeDescr;
 class UnownedBaseShape;
 class WasmMemoryObject;
 namespace jit {
 class JitCode;
 } // namespace jit
 } // namespace js
 
-// Expand the given macro D for each public GC pointer.
-#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
-    D(JS::Symbol*) \
-    D(JSAtom*) \
-    D(JSFunction*) \
-    D(JSObject*) \
-    D(JSScript*) \
-    D(JSString*)
-
-// Expand the given macro D for each public tagged GC pointer type.
-#define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \
-    D(JS::Value) \
-    D(jsid)
-
-#define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \
-    D(JSPropertyDescriptor)
-
 // Expand the given macro D for each valid GC reference type.
 #define FOR_EACH_INTERNAL_GC_POINTER_TYPE(D) \
     D(JSFlatString*) \
     D(JSLinearString*) \
     D(js::AccessorShape*) \
     D(js::ArgumentsObject*) \
     D(js::ArrayBufferObject*) \
     D(js::ArrayBufferObjectMaybeShared*) \