Bug 1400003 - Mark Heap<T> and barrier classes as MOZ_NON_MEMMOVABLE r=sfink r=froydnj
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 09 Oct 2017 10:03:20 +0100
changeset 427685 6ad5b916c9659aeb4b901d8f9ec7f121dc2c4418
parent 427669 0b1a22a4c03cf1c66c47e41a0113969b7289d1b3
child 427687 f5dd83abdb399422f09f75576c970c74daeb3798
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewerssfink, froydnj
bugs1400003
milestone58.0a1
Bug 1400003 - Mark Heap<T> and barrier classes as MOZ_NON_MEMMOVABLE r=sfink r=froydnj
js/public/RootingAPI.h
js/src/gc/Barrier.h
xpcom/ds/nsTArray.h
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -232,17 +232,17 @@ AssertGCThingIsNotAnObjectSubclass(js::g
  * 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 a public GC pointer type.
  */
 template <typename T>
-class Heap : public js::HeapBase<T, Heap<T>>
+class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase<T, Heap<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:
     using ElementType = T;
 
     Heap() {
@@ -1168,16 +1168,24 @@ class JS_PUBLIC_API(ObjectPtr)
 
   public:
     using ElementType = JSObject*;
 
     ObjectPtr() : value(nullptr) {}
 
     explicit ObjectPtr(JSObject* obj) : value(obj) {}
 
+    ObjectPtr(const ObjectPtr& other) : value(other.value) {}
+
+    ObjectPtr(ObjectPtr&& other)
+      : value(other.value)
+    {
+        other.value = nullptr;
+    }
+
     /* Always call finalize before the destructor. */
     ~ObjectPtr() { MOZ_ASSERT(!value); }
 
     void finalize(JSRuntime* rt);
     void finalize(JSContext* cx);
 
     void init(JSObject* obj) { value = obj; }
 
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -313,18 +313,21 @@ template <>
 struct InternalBarrierMethods<jsid>
 {
     static bool isMarkable(jsid id) { return JSID_IS_GCTHING(id); }
     static void preBarrier(jsid id) { DispatchTyped(PreBarrierFunctor<jsid>(), id); }
     static void postBarrier(jsid* idp, jsid prev, jsid next) {}
 };
 
 // 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 BarrieredBase
+class MOZ_NON_MEMMOVABLE BarrieredBase
 {
   protected:
     // BarrieredBase is not directly instantiable.
     explicit BarrieredBase(const T& v) : value(v) {}
 
     // BarrieredBase subclasses cannot be copy constructed by default.
     BarrieredBase(const BarrieredBase<T>& other) = default;
 
--- a/xpcom/ds/nsTArray.h
+++ b/xpcom/ds/nsTArray.h
@@ -32,16 +32,17 @@
 #include "nsRegionFwd.h"
 #include <functional>
 #include <initializer_list>
 #include <new>
 
 namespace JS {
 template<class T>
 class Heap;
+class ObjectPtr;
 } /* namespace JS */
 
 class nsRegion;
 namespace mozilla {
 namespace layers {
 struct TileClient;
 } // namespace layers
 } // namespace mozilla
@@ -703,55 +704,53 @@ struct nsTArray_CopyWithConstructors
 };
 
 //
 // The default behaviour is to use memcpy/memmove for everything.
 //
 template<class E>
 struct MOZ_NEEDS_MEMMOVABLE_TYPE nsTArray_CopyChooser
 {
-  typedef nsTArray_CopyWithMemutils Type;
+  using Type = nsTArray_CopyWithMemutils;
 };
 
 //
 // Some classes require constructors/destructors to be called, so they are
 // specialized here.
 //
 #define DECLARE_USE_COPY_CONSTRUCTORS(T)                \
   template<>                                            \
   struct nsTArray_CopyChooser<T>                        \
   {                                                     \
-    typedef nsTArray_CopyWithConstructors<T> Type;      \
+    using Type = nsTArray_CopyWithConstructors<T>;      \
   };
 
-template<class E>
-struct nsTArray_CopyChooser<JS::Heap<E>>
-{
-  typedef nsTArray_CopyWithConstructors<JS::Heap<E>> Type;
-};
+#define DECLARE_USE_COPY_CONSTRUCTORS_FOR_TEMPLATE(T)   \
+  template<typename S>                                  \
+  struct nsTArray_CopyChooser<T<S>>                     \
+  {                                                     \
+    using Type = nsTArray_CopyWithConstructors<T<S>>;   \
+  };
+
+DECLARE_USE_COPY_CONSTRUCTORS_FOR_TEMPLATE(JS::Heap)
+DECLARE_USE_COPY_CONSTRUCTORS_FOR_TEMPLATE(std::function)
 
 DECLARE_USE_COPY_CONSTRUCTORS(nsRegion)
 DECLARE_USE_COPY_CONSTRUCTORS(nsIntRegion)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::layers::TileClient)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::SerializedStructuredCloneBuffer)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::ipc::StructuredCloneData)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::ClonedMessageData)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::StructuredCloneReadInfo);
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::ObjectStoreCursorResponse)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::SerializedStructuredCloneReadInfo);
 DECLARE_USE_COPY_CONSTRUCTORS(JSStructuredCloneData)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessagePortMessage)
 DECLARE_USE_COPY_CONSTRUCTORS(mozilla::SourceBufferTask)
-
-template<typename T>
-struct nsTArray_CopyChooser<std::function<T>>
-{
-  typedef nsTArray_CopyWithConstructors<std::function<T>> Type;
-};
-
+DECLARE_USE_COPY_CONSTRUCTORS(JS::ObjectPtr)
 
 //
 // Base class for nsTArray_Impl that is templated on element type and derived
 // nsTArray_Impl class, to allow extra conversions to be added for specific
 // types.
 //
 template<class E, class Derived>
 struct nsTArray_TypedBase : public nsTArray_SafeElementAtHelper<E, Derived>