Backed out 12 changesets (bug 1096328) for M11 and M5 Test failures on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 12 Jan 2015 14:48:15 +0100
changeset 223354 a7f64e53893ef5d4bed1996acce1e0d459b8df8d
parent 223353 e8ddeaeb82eee0c8f050ddad8c045e20c5df85c0
child 223355 965b5028e41e2a8df77a3c777c396e12807937a4
push id28088
push userryanvm@gmail.com
push dateMon, 12 Jan 2015 20:26:58 +0000
treeherdermozilla-central@2c951493eef5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1096328
milestone37.0a1
backs out12dd1ad43923ac63fa00cdf1484991d5624c4daf
4a067de94f2256ba11041b6e7102a349c5b57e1b
676112a4f0921a9b5c9e7edcbaac36d26cd32e56
e2e64e751ece7d318943a440a14ebaa26a7ec84d
9ed945e9a8a5237881ac75d5c0a93cd78af54bed
47be69b84be50cccb70c642e6562e8b60858450b
d6e68ba4846d8dfa13c6deeb6c7b6b216661052a
899d8cd8c4e8377104068154da3d8527baeaddc8
55c831086864e5655c6242d5eb1f593097b8e327
6005fd357342edf5f5282e584fbe5655c4fee340
0f330a5dd34661249917e477977cc2b67c48c440
c37e10cff7654d9a8b0f8af8571c3f40bcef72b3
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
Backed out 12 changesets (bug 1096328) for M11 and M5 Test failures on a CLOSED TREE Backed out changeset 12dd1ad43923 (bug 1096328) Backed out changeset 4a067de94f22 (bug 1096328) Backed out changeset 676112a4f092 (bug 1096328) Backed out changeset e2e64e751ece (bug 1096328) Backed out changeset 9ed945e9a8a5 (bug 1096328) Backed out changeset 47be69b84be5 (bug 1096328) Backed out changeset d6e68ba4846d (bug 1096328) Backed out changeset 899d8cd8c4e8 (bug 1096328) Backed out changeset 55c831086864 (bug 1096328) Backed out changeset 6005fd357342 (bug 1096328) Backed out changeset 0f330a5dd346 (bug 1096328) Backed out changeset c37e10cff765 (bug 1096328)
dom/base/AnonymousContent.cpp
dom/base/AnonymousContent.h
dom/base/DOMMatrix.cpp
dom/base/DOMMatrix.h
dom/base/DOMPoint.cpp
dom/base/DOMPoint.h
dom/base/NodeIterator.cpp
dom/base/NodeIterator.h
dom/base/TreeWalker.cpp
dom/base/TreeWalker.h
dom/base/URL.cpp
dom/base/URL.h
dom/base/nsGlobalWindow.cpp
dom/bindings/BindingUtils.h
dom/bindings/Bindings.conf
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/NonRefcountedDOMObject.h
dom/bindings/StructuredClone.cpp
dom/bindings/test/TestBindingHeader.h
dom/canvas/ImageData.cpp
dom/canvas/ImageData.h
dom/canvas/TextMetrics.h
dom/canvas/WebGLActiveInfo.cpp
dom/canvas/WebGLActiveInfo.h
dom/canvas/WebGLShaderPrecisionFormat.cpp
dom/canvas/WebGLShaderPrecisionFormat.h
dom/canvas/WebGLUniformLocation.cpp
dom/canvas/WebGLUniformLocation.h
dom/datastore/DataStoreCursor.cpp
dom/datastore/DataStoreCursor.h
dom/encoding/TextDecoder.h
dom/encoding/TextEncoder.h
dom/html/TimeRanges.cpp
dom/html/TimeRanges.h
dom/indexedDB/IDBKeyRange.cpp
dom/indexedDB/IDBKeyRange.h
dom/vr/VRDevice.cpp
dom/vr/VRDevice.h
dom/webidl/VRDevice.webidl
dom/workers/DataStoreCursor.cpp
dom/workers/DataStoreCursor.h
dom/workers/FileReaderSync.cpp
dom/workers/FileReaderSync.h
dom/workers/URL.cpp
dom/workers/URL.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/WorkerScope.h
dom/xslt/xpath/XPathEvaluator.cpp
dom/xslt/xpath/XPathEvaluator.h
dom/xslt/xpath/XPathExpression.h
js/ipc/JavaScriptShared.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -124,17 +124,16 @@ AnonymousContent::GetElementById(const n
     nsIAtom* id = kid->AsElement()->GetID();
     if (id && id == elementId) {
       return kid->AsElement();
     }
   }
   return nullptr;
 }
 
-bool
-AnonymousContent::WrapObject(JSContext* aCx,
-                             JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+AnonymousContent::WrapObject(JSContext* aCx)
 {
-  return AnonymousContentBinding::Wrap(aCx, this, aReflector);
+  return AnonymousContentBinding::Wrap(aCx, this);
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/base/AnonymousContent.h
+++ b/dom/base/AnonymousContent.h
@@ -22,17 +22,17 @@ class AnonymousContent MOZ_FINAL
 public:
   // Ref counting and cycle collection
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnonymousContent)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnonymousContent)
 
   explicit AnonymousContent(Element* aContentNode);
   nsCOMPtr<Element> GetContentNode();
   void SetContentNode(Element* aContentNode);
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject* WrapObject(JSContext* aCx);
 
   // WebIDL methods
   void SetTextContentForElement(const nsAString& aElementId,
                                 const nsAString& aText,
                                 ErrorResult& aRv);
 
   void GetTextContentForElement(const nsAString& aElementId,
                                 DOMString& aText,
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -18,21 +18,16 @@
 #include "nsAutoPtr.h"
 #include <math.h>
 
 namespace mozilla {
 namespace dom {
 
 static const double radPerDegree = 2.0 * M_PI / 360.0;
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrixReadOnly, mParent)
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrixReadOnly, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrixReadOnly, Release)
-
 already_AddRefed<DOMMatrix>
 DOMMatrixReadOnly::Translate(double aTx,
                              double aTy,
                              double aTz) const
 {
   nsRefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
   retval->TranslateSelf(aTx, aTy, aTz);
 
@@ -303,16 +298,21 @@ DOMMatrixReadOnly::Stringify(nsAString& 
       M41(), M42(), M43(), M44());
   } else {
     matrixStr.AppendPrintf("matrix(%g, %g, %g, %g, %g, %g)", A(), B(), C(), D(), E(), F());
   }
 
   aResult = matrixStr;
 }
 
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrix, mParent)
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrix, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrix, Release)
+
 already_AddRefed<DOMMatrix>
 DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
   return obj.forget();
 }
 
 already_AddRefed<DOMMatrix>
--- a/dom/base/DOMMatrix.h
+++ b/dom/base/DOMMatrix.h
@@ -35,19 +35,16 @@ public:
   {
     if (other.mMatrix2D) {
       mMatrix2D = new gfx::Matrix(*other.mMatrix2D);
     } else {
       mMatrix3D = new gfx::Matrix4x4(*other.mMatrix3D);
     }
   }
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrixReadOnly)
-
 #define GetMatrixMember(entry2D, entry3D, default) \
 { \
   if (mMatrix3D) { \
     return mMatrix3D->entry3D; \
   } \
   return mMatrix2D->entry2D; \
 }
 
@@ -128,18 +125,19 @@ public:
                                              JS::MutableHandle<JSObject*> aResult,
                                              ErrorResult& aRv) const;
   void                        Stringify(nsAString& aResult);
 protected:
   nsCOMPtr<nsISupports>     mParent;
   nsAutoPtr<gfx::Matrix>    mMatrix2D;
   nsAutoPtr<gfx::Matrix4x4> mMatrix3D;
 
-  virtual ~DOMMatrixReadOnly() {}
-
+  ~DOMMatrixReadOnly()
+  {
+  }
 private:
   DOMMatrixReadOnly() = delete;
   DOMMatrixReadOnly(const DOMMatrixReadOnly&) = delete;
   DOMMatrixReadOnly& operator=(const DOMMatrixReadOnly&) = delete;
 };
 
 class DOMMatrix MOZ_FINAL : public DOMMatrixReadOnly
 {
@@ -147,16 +145,19 @@ public:
   explicit DOMMatrix(nsISupports* aParent)
     : DOMMatrixReadOnly(aParent)
   {}
 
   DOMMatrix(nsISupports* aParent, const DOMMatrixReadOnly& other)
     : DOMMatrixReadOnly(aParent, other)
   {}
 
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrix)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMMatrix)
+
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const nsAString& aTransformList, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOther, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
@@ -240,14 +241,16 @@ public:
                                  double aZ,
                                  double aAngle);
   DOMMatrix* SkewXSelf(double aSx);
   DOMMatrix* SkewYSelf(double aSy);
   DOMMatrix* InvertSelf();
   DOMMatrix* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
 private:
   void Ensure3DMatrix();
+
+  ~DOMMatrix() {}
 };
 
 }
 }
 
 #endif /*MOZILLA_DOM_DOMMATRIX_H_*/
--- a/dom/base/DOMPoint.cpp
+++ b/dom/base/DOMPoint.cpp
@@ -7,20 +7,20 @@
 
 #include "mozilla/dom/DOMPointBinding.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "nsAutoPtr.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMPointReadOnly, mParent)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMPoint, mParent)
 
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPointReadOnly, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPointReadOnly, Release)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPoint, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPoint, Release)
 
 already_AddRefed<DOMPoint>
 DOMPoint::Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
                       ErrorResult& aRV)
 {
   nsRefPtr<DOMPoint> obj =
     new DOMPoint(aGlobal.GetAsSupports(), aParams.mX, aParams.mY,
                  aParams.mZ, aParams.mW);
--- a/dom/base/DOMPoint.h
+++ b/dom/base/DOMPoint.h
@@ -28,39 +28,39 @@ public:
     : mParent(aParent)
     , mX(aX)
     , mY(aY)
     , mZ(aZ)
     , mW(aW)
   {
   }
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPointReadOnly)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPointReadOnly)
-
   double X() const { return mX; }
   double Y() const { return mY; }
   double Z() const { return mZ; }
   double W() const { return mW; }
 
 protected:
-  virtual ~DOMPointReadOnly() {}
-
   nsCOMPtr<nsISupports> mParent;
   double mX, mY, mZ, mW;
 };
 
 class DOMPoint MOZ_FINAL : public DOMPointReadOnly
 {
+  ~DOMPoint() {}
+
 public:
   explicit DOMPoint(nsISupports* aParent, double aX = 0.0, double aY = 0.0,
                     double aZ = 0.0, double aW = 1.0)
     : DOMPointReadOnly(aParent, aX, aY, aZ, aW)
   {}
 
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPoint)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPoint)
+
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
               ErrorResult& aRV);
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, double aX, double aY,
               double aZ, double aW, ErrorResult& aRV);
 
   nsISupports* GetParentObject() const { return mParent; }
--- a/dom/base/NodeIterator.cpp
+++ b/dom/base/NodeIterator.cpp
@@ -283,16 +283,16 @@ void NodeIterator::ContentRemoved(nsIDoc
                                   nsIContent *aPreviousSibling)
 {
     nsINode *container = NODE_FROM(aContainer, aDocument);
 
     mPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
     mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
 }
 
-bool
-NodeIterator::WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+NodeIterator::WrapObject(JSContext *cx)
 {
-    return NodeIteratorBinding::Wrap(cx, this, aReflector);
+    return NodeIteratorBinding::Wrap(cx, this);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/NodeIterator.h
+++ b/dom/base/NodeIterator.h
@@ -64,17 +64,17 @@ public:
         return NextOrPrevNode(&NodePointer::MoveToNext, aResult);
     }
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult)
     {
         return NextOrPrevNode(&NodePointer::MoveToPrevious, aResult);
     }
     // The XPCOM Detach() is fine for our purposes
 
-    bool WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector);
+    JSObject* WrapObject(JSContext *cx);
 
 private:
     virtual ~NodeIterator();
 
     struct NodePointer {
         NodePointer() : mNode(nullptr) {}
         NodePointer(nsINode *aNode, bool aBeforeNode);
 
--- a/dom/base/TreeWalker.cpp
+++ b/dom/base/TreeWalker.cpp
@@ -445,16 +445,16 @@ TreeWalker::NextSiblingInternal(bool aRe
             return nullptr;
         }
         if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
             return nullptr;
         }
     }
 }
 
-bool
-TreeWalker::WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+TreeWalker::WrapObject(JSContext *cx)
 {
-    return TreeWalkerBinding::Wrap(aCx, this, aReflector);
+    return TreeWalkerBinding::Wrap(cx, this);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/TreeWalker.h
+++ b/dom/base/TreeWalker.h
@@ -60,17 +60,17 @@ public:
     already_AddRefed<nsINode> ParentNode(ErrorResult& aResult);
     already_AddRefed<nsINode> FirstChild(ErrorResult& aResult);
     already_AddRefed<nsINode> LastChild(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> NextSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult);
     already_AddRefed<nsINode> NextNode(ErrorResult& aResult);
 
-    bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
+    JSObject* WrapObject(JSContext *cx);
 
 private:
     nsCOMPtr<nsINode> mCurrentNode;
 
     /*
      * Implements FirstChild and LastChild which only vary in which direction
      * they search.
      * @param aReversed Controls whether we search forwards or backwards
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -41,20 +41,20 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 URL::URL(nsIURI* aURI)
   : mURI(aURI)
 {
 }
 
-bool
-URL::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+URL::WrapObject(JSContext* aCx)
 {
-  return URLBinding::Wrap(aCx, this, aReflector);
+  return URLBinding::Wrap(aCx, this);
 }
 
 /* static */ already_AddRefed<URL>
 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
                  URL& aBase, ErrorResult& aRv)
 {
   nsresult rv;
   nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -38,18 +38,18 @@ class URL MOZ_FINAL : public URLSearchPa
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(URL)
 
   explicit URL(nsIURI* aURI);
 
   // WebIDL methods
-  bool
-  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject*
+  WrapObject(JSContext* aCx);
 
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               URL& aBase, ErrorResult& aRv);
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               const nsAString& aBase, ErrorResult& aRv);
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2294,19 +2294,19 @@ CreateNativeGlobalForInner(JSContext* aC
   }
 
   // Determine if we need the Components object.
   bool needComponents = nsContentUtils::IsSystemPrincipal(aPrincipal) ||
                         TreatAsRemoteXUL(aPrincipal);
   uint32_t flags = needComponents ? 0 : nsIXPConnect::OMIT_COMPONENTS_OBJECT;
   flags |= nsIXPConnect::DONT_FIRE_ONNEWGLOBALHOOK;
 
-  if (!WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
-                           nsJSPrincipals::get(aPrincipal), false, aGlobal) ||
-      !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
+  aGlobal.set(WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
+                                  nsJSPrincipals::get(aPrincipal), false));
+  if (!aGlobal || !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
     return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
 
   // Set the location information for the new global, so that tools like
   // about:memory may use that information
   xpc::SetLocationForGlobal(aGlobal, aURI);
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -662,80 +662,57 @@ DefineWebIDLBindingUnforgeableProperties
                                                     JS::Handle<JSObject*> obj,
                                                     const NativeProperties* properties);
 
 bool
 DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
                                          JS::Handle<JSObject*> obj,
                                          const NativeProperties* properties);
 
-#define HAS_MEMBER_TYPEDEFS                                               \
-private:                                                                  \
-  typedef char yes[1];                                                    \
-  typedef char no[2]
-
 #ifdef _MSC_VER
 #define HAS_MEMBER_CHECK(_name)                                           \
-  template<typename V> static yes& Check##_name(char (*)[(&V::_name == 0) + 1])
+  template<typename V> static yes& Check(char (*)[(&V::_name == 0) + 1])
 #else
 #define HAS_MEMBER_CHECK(_name)                                           \
-  template<typename V> static yes& Check##_name(char (*)[sizeof(&V::_name) + 1])
+  template<typename V> static yes& Check(char (*)[sizeof(&V::_name) + 1])
 #endif
 
-#define HAS_MEMBER(_memberName, _valueName)                               \
-private:                                                                  \
-  HAS_MEMBER_CHECK(_memberName);                                          \
-  template<typename V> static no& Check##_memberName(...);                \
+#define HAS_MEMBER(_name)                                                 \
+template<typename T>                                                      \
+class Has##_name##Member {                                                \
+  typedef char yes[1];                                                    \
+  typedef char no[2];                                                     \
+  HAS_MEMBER_CHECK(_name);                                                \
+  template<typename V> static no& Check(...);                             \
                                                                           \
 public:                                                                   \
-  static bool const _valueName =                                          \
-    sizeof(Check##_memberName<T>(nullptr)) == sizeof(yes)
-
-template<class T>
-struct NativeHasMember
-{
-  HAS_MEMBER_TYPEDEFS;
-
-  HAS_MEMBER(GetParentObject, GetParentObject);
-  HAS_MEMBER(JSBindingFinalized, JSBindingFinalized);
-  HAS_MEMBER(WrapObject, WrapObject);
+  static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes);     \
 };
 
-template<class T>
-struct IsSmartPtr
+HAS_MEMBER(WrapObject)
+
+// HasWrapObject<T>::Value will be true if T has a WrapObject member but it's
+// not nsWrapperCache::WrapObject.
+template<typename T>
+struct HasWrapObject
 {
-  HAS_MEMBER_TYPEDEFS;
-
-  HAS_MEMBER(get, value);
-};
-
-template<class T>
-struct IsRefcounted
-{
-  HAS_MEMBER_TYPEDEFS;
-
-  HAS_MEMBER(AddRef, HasAddref);
-  HAS_MEMBER(Release, HasRelease);
+private:
+  typedef char yes[1];
+  typedef char no[2];
+  typedef JSObject* (nsWrapperCache::*WrapObject)(JSContext*,
+                                                  JS::Handle<JSObject*>);
+  template<typename U, U> struct SFINAE;
+  template <typename V> static no& Check(SFINAE<WrapObject, &V::WrapObject>*);
+  template <typename V> static yes& Check(...);
 
 public:
-  static bool const value = HasAddref && HasRelease;
-
-private:
-  // This struct only works if T is fully declared (not just forward declared).
-  // The IsBaseOf check will ensure that, we don't really need it for any other
-  // reason (the static assert will of course always be true).
-  static_assert(!IsBaseOf<nsISupports, T>::value || IsRefcounted::value,
-                "Classes derived from nsISupports are refcounted!");
-
+  static bool const Value = HasWrapObjectMember<T>::Value &&
+                            sizeof(Check<T>(nullptr)) == sizeof(yes);
 };
 
-#undef HAS_MEMBER
-#undef HAS_MEMBER_CHECK
-#undef HAS_MEMBER_TYPEDEFS
-
 #ifdef DEBUG
 template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
 struct
 CheckWrapperCacheCast
 {
   static bool Check()
   {
     return reinterpret_cast<uintptr_t>(
@@ -994,17 +971,16 @@ GetOrCreateDOMReflectorNoWrap(JSContext*
 // WrapObject() method taking a JSContext and a scope.
 template <class T>
 inline bool
 WrapNewBindingNonWrapperCachedObject(JSContext* cx,
                                      JS::Handle<JSObject*> scopeArg,
                                      T* value,
                                      JS::MutableHandle<JS::Value> rval)
 {
-  static_assert(IsRefcounted<T>::value, "Don't pass owned classes in here.");
   MOZ_ASSERT(value);
   // We try to wrap in the compartment of the underlying object of "scope"
   JS::Rooted<JSObject*> obj(cx);
   {
     // scope for the JSAutoCompartment so that we restore the compartment
     // before we call JS_WrapValue.
     Maybe<JSAutoCompartment> ac;
     // Maybe<Handle> doesn't so much work, and in any case, adding
@@ -1014,39 +990,40 @@ WrapNewBindingNonWrapperCachedObject(JSC
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    if (!value->WrapObject(cx, &obj)) {
-      return false;
-    }
+    obj = value->WrapObject(cx);
+  }
+
+  if (!obj) {
+    return false;
   }
 
   // We can end up here in all sorts of compartments, per above.  Make
   // sure to JS_WrapValue!
   rval.set(JS::ObjectValue(*obj));
   return JS_WrapValue(cx, rval);
 }
 
 // Create a JSObject wrapping "value", for cases when "value" is a
 // non-wrapper-cached owned object using WebIDL bindings.  "value" must implement a
 // WrapObject() method taking a JSContext, a scope, and a boolean outparam that
 // is true if the JSObject took ownership
 template <class T>
 inline bool
-WrapNewBindingNonWrapperCachedObject(JSContext* cx,
-                                     JS::Handle<JSObject*> scopeArg,
-                                     nsAutoPtr<T>& value,
-                                     JS::MutableHandle<JS::Value> rval)
+WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
+                                          JS::Handle<JSObject*> scopeArg,
+                                          nsAutoPtr<T>& value,
+                                          JS::MutableHandle<JS::Value> rval)
 {
-  static_assert(!IsRefcounted<T>::value, "Only pass owned classes in here.");
   // We do a runtime check on value, because otherwise we might in
   // fact end up wrapping a null and invoking methods on it later.
   if (!value) {
     NS_RUNTIMEABORT("Don't try to wrap null objects");
   }
   // We try to wrap in the compartment of the underlying object of "scope"
   JS::Rooted<JSObject*> obj(cx);
   {
@@ -1059,33 +1036,37 @@ WrapNewBindingNonWrapperCachedObject(JSC
     JS::Rooted<JSObject*> scope(cx, scopeArg);
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
+    bool tookOwnership = false;
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    if (!value->WrapObject(cx, &obj)) {
-      return false;
+    obj = value->WrapObject(cx, &tookOwnership);
+    MOZ_ASSERT_IF(obj, tookOwnership);
+    if (tookOwnership) {
+      value.forget();
     }
-
-    value.forget();
+  }
+
+  if (!obj) {
+    return false;
   }
 
   // We can end up here in all sorts of compartments, per above.  Make
   // sure to JS_WrapValue!
   rval.set(JS::ObjectValue(*obj));
   return JS_WrapValue(cx, rval);
 }
 
-// Helper for smart pointers (nsRefPtr/nsCOMPtr).
-template <template <typename> class SmartPtr, typename T,
-          typename U=typename EnableIf<IsRefcounted<T>::value, T>::Type>
+// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
+template <template <typename> class SmartPtr, typename T>
 inline bool
 WrapNewBindingNonWrapperCachedObject(JSContext* cx, JS::Handle<JSObject*> scope,
                                      const SmartPtr<T>& value,
                                      JS::MutableHandle<JS::Value> rval)
 {
   return WrapNewBindingNonWrapperCachedObject(cx, scope, value.get(), rval);
 }
 
@@ -1114,18 +1095,19 @@ HandleNewBindingWrappingFailure(JSContex
 
   qsObjectHelper helper(value, GetWrapperCache(value));
   return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval,
                                                   helper, nullptr, true);
 }
 
 // Helper for calling HandleNewBindingWrappingFailure with smart pointers
 // (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
-
-template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
+HAS_MEMBER(get)
+
+template <class T, bool isSmartPtr=HasgetMember<T>::Value>
 struct HandleNewBindingWrappingFailureHelper
 {
   static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
                           const T& value, JS::MutableHandle<JS::Value> rval)
   {
     return HandleNewBindingWrappingFailure(cx, scope, value.get(), rval);
   }
 };
@@ -1480,17 +1462,17 @@ struct WrapNativeParentFallback<T, true 
   static inline JSObject* Wrap(JSContext* cx, T* parent, nsWrapperCache* cache)
   {
     return WrapNativeISupportsParent(cx, parent, cache);
   }
 };
 
 // Wrapping of our native parent, for cases when it's a WebIDL object (though
 // possibly preffed off).
-template<typename T, bool hasWrapObject=NativeHasMember<T>::WrapObject>
+template<typename T, bool hasWrapObject=HasWrapObject<T>::Value >
 struct WrapNativeParentHelper
 {
   static inline JSObject* Wrap(JSContext* cx, T* parent, nsWrapperCache* cache)
   {
     MOZ_ASSERT(cache);
 
     JSObject* obj;
     if ((obj = cache->GetWrapper())) {
@@ -1506,17 +1488,17 @@ struct WrapNativeParentHelper
 
     return obj;
   }
 };
 
 // Wrapping of our native parent, for cases when it's not a WebIDL object.  In
 // this case it must be nsISupports.
 template<typename T>
-struct WrapNativeParentHelper<T, false>
+struct WrapNativeParentHelper<T, false >
 {
   static inline JSObject* Wrap(JSContext* cx, T* parent, nsWrapperCache* cache)
   {
     JSObject* obj;
     if (cache && (obj = cache->GetWrapper())) {
 #ifdef DEBUG
       NS_ASSERTION(WrapNativeISupportsParent(cx, parent, cache) == obj,
                    "Unexpected object in nsWrapperCache");
@@ -1564,17 +1546,19 @@ WrapNativeParent(JSContext* cx, T* p, ns
 // things like the nsWrapperCache for it.
 template<typename T>
 static inline JSObject*
 WrapNativeParent(JSContext* cx, const T& p)
 {
   return WrapNativeParent(cx, GetParentPointer(p), GetWrapperCache(p), GetUseXBLScope(p));
 }
 
-template<typename T, bool WrapperCached=NativeHasMember<T>::GetParentObject>
+HAS_MEMBER(GetParentObject)
+
+template<typename T, bool WrapperCached=HasGetParentObjectMember<T>::Value>
 struct GetParentObject
 {
   static JSObject* Get(JSContext* cx, JS::Handle<JSObject*> obj)
   {
     MOZ_ASSERT(js::IsObjectInContextCompartment(obj, cx));
     T* native = UnwrapDOMObject<T>(obj);
     JSObject* wrappedParent = WrapNativeParent(cx, native->GetParentObject());
     return wrappedParent ? js::GetGlobalForObjectCrossCompartment(wrappedParent) : nullptr;
@@ -1643,33 +1627,32 @@ WrapCallThisObject<JS::Rooted<JSObject*>
     return nullptr;
   }
 
   return obj;
 }
 
 // Helper for calling GetOrCreateDOMReflector with smart pointers
 // (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
-template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
+template <class T, bool isSmartPtr=HasgetMember<T>::Value>
 struct GetOrCreateDOMReflectorHelper
 {
   static inline bool GetOrCreate(JSContext* cx, const T& value,
                                  JS::MutableHandle<JS::Value> rval)
   {
     return GetOrCreateDOMReflector(cx, value.get(), rval);
   }
 };
 
 template <class T>
 struct GetOrCreateDOMReflectorHelper<T, false>
 {
   static inline bool GetOrCreate(JSContext* cx, T& value,
                                  JS::MutableHandle<JS::Value> rval)
   {
-    static_assert(IsRefcounted<T>::value, "Don't pass owned classes in here.");
     return GetOrCreateDOMReflector(cx, &value, rval);
   }
 };
 
 template<class T>
 inline bool
 GetOrCreateDOMReflector(JSContext* cx, T& value,
                         JS::MutableHandle<JS::Value> rval)
@@ -1685,17 +1668,17 @@ inline bool
 GetOrCreateDOMReflector(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
                         JS::MutableHandle<JS::Value> rval)
 {
   return GetOrCreateDOMReflector(cx, value, rval);
 }
 
 // Helper for calling GetOrCreateDOMReflectorNoWrap with smart pointers
 // (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
-template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
+template <class T, bool isSmartPtr=HasgetMember<T>::Value>
 struct GetOrCreateDOMReflectorNoWrapHelper
 {
   static inline bool GetOrCreate(JSContext* cx, const T& value,
                                  JS::MutableHandle<JS::Value> rval)
   {
     return GetOrCreateDOMReflectorNoWrap(cx, value.get(), rval);
   }
 };
@@ -1724,17 +1707,17 @@ inline JSObject*
 GetCallbackFromCallbackObject(T* aObj)
 {
   return aObj->Callback();
 }
 
 // Helper for getting the callback JSObject* of a smart ptr around a
 // CallbackObject or a reference to a CallbackObject or something like
 // that.
-template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
+template <class T, bool isSmartPtr=HasgetMember<T>::Value>
 struct GetCallbackFromCallbackObjectHelper
 {
   static inline JSObject* Get(const T& aObj)
   {
     return GetCallbackFromCallbackObject(aObj.get());
   }
 };
 
@@ -2515,17 +2498,40 @@ UseDOMXray(JSObject* obj)
 inline bool
 HasConstructor(JSObject* obj)
 {
   return JS_IsNativeFunction(obj, Constructor) ||
          js::GetObjectClass(obj)->construct;
 }
  #endif
  
-template<class T, bool hasCallback=NativeHasMember<T>::JSBindingFinalized>
+// Transfer reference in ptr to smartPtr.
+template<class T>
+inline void
+Take(nsRefPtr<T>& smartPtr, T* ptr)
+{
+  smartPtr = dont_AddRef(ptr);
+}
+
+// Transfer ownership of ptr to smartPtr.
+template<class T>
+inline void
+Take(nsAutoPtr<T>& smartPtr, T* ptr)
+{
+  smartPtr = ptr;
+}
+
+inline void
+MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
+{
+}
+
+HAS_MEMBER(JSBindingFinalized)
+
+template<class T, bool hasCallback=HasJSBindingFinalizedMember<T>::Value>
 struct JSBindingFinalized
 {
   static void Finalized(T* self)
   {
   }
 };
 
 template<class T>
@@ -2742,138 +2748,34 @@ ToSupportsIsCorrect(T* aObject)
 template<class T>
 bool
 ToSupportsIsOnPrimaryInheritanceChain(T* aObject, nsWrapperCache* aCache)
 {
   return CastingAssertions<T>::ToSupportsIsOnPrimaryInheritanceChain(aObject,
                                                                      aCache);
 }
 
-// The BindingJSObjectCreator class is supposed to be used by a caller that
-// wants to create and initialise a binding JSObject. After initialisation has
-// been successfully completed it should call ForgetObject().
-// The BindingJSObjectCreator object will root the JSObject until ForgetObject()
-// is called on it. If the native object for the binding is refcounted it will
-// also hold a strong reference to it, that reference is transferred to the
-// JSObject (which holds the native in a slot) when ForgetObject() is called. If
-// the BindingJSObjectCreator object is destroyed and ForgetObject() was never
-// called on it then the JSObject's slot holding the native will be set to
-// undefined, and for a refcounted native the strong reference will be released.
-template<class T>
-class MOZ_STACK_CLASS BindingJSObjectCreator
-{
-public:
-  explicit BindingJSObjectCreator(JSContext* aCx)
-    : mReflector(aCx)
-  {
-  }
-
-  ~BindingJSObjectCreator()
-  {
-    if (mReflector) {
-      js::SetReservedOrProxyPrivateSlot(mReflector, DOM_OBJECT_SLOT,
-                                        JS::UndefinedValue());
-    }
-  }
-
-  void
-  CreateProxyObject(JSContext* aCx, const js::Class* aClass,
-                    const DOMProxyHandler* aHandler,
-                    JS::Handle<JSObject*> aProto,
-                    JS::Handle<JSObject*> aParent, T* aNative,
-                    JS::MutableHandle<JSObject*> aReflector)
-  {
-    js::ProxyOptions options;
-    options.setClass(aClass);
-    JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aNative));
-    aReflector.set(js::NewProxyObject(aCx, aHandler, proxyPrivateVal, aProto,
-                                      aParent, options));
-    if (aReflector) {
-      mNative = aNative;
-      mReflector = aReflector;
-    }
-  }
-
-  void
-  CreateObject(JSContext* aCx, const JSClass* aClass,
-               JS::Handle<JSObject*> aProto, JS::Handle<JSObject*> aParent,
-               T* aNative, JS::MutableHandle<JSObject*> aReflector)
-  {
-    aReflector.set(JS_NewObject(aCx, aClass, aProto, aParent));
-    if (aReflector) {
-      js::SetReservedSlot(aReflector, DOM_OBJECT_SLOT, JS::PrivateValue(aNative));
-      mNative = aNative;
-      mReflector = aReflector;
-    }
-  }
-
-  void
-  InitializationSucceeded()
-  {
-    void* dummy;
-    mNative.forget(&dummy);
-    mReflector = nullptr;
-  }
-
-private:
-  struct OwnedNative
-  {
-    // Make sure the native objects inherit from NonRefcountedDOMObject so
-    // that we log their ctor and dtor.
-    static_assert(IsBaseOf<NonRefcountedDOMObject, T>::value,
-                  "Non-refcounted objects with DOM bindings should inherit "
-                  "from NonRefcountedDOMObject.");
-
-    OwnedNative&
-    operator=(T* aNative)
-    {
-      return *this;
-    }
-
-    // This signature sucks, but it's the only one that will make a nsRefPtr
-    // just forget about its pointer without warning.
-    void
-    forget(void**)
-    {
-    }
-  };
-
-  JS::Rooted<JSObject*> mReflector;
-  typename Conditional<IsRefcounted<T>::value, nsRefPtr<T>, OwnedNative>::Type mNative;
-};
-
-template<class T,
+template<class T, template <typename> class SmartPtr,
          bool isISupports=IsBaseOf<nsISupports, T>::value>
 class DeferredFinalizer
 {
-  typedef typename Conditional<IsRefcounted<T>::value,
-                               nsRefPtr<T>, nsAutoPtr<T>>::Type SmartPtr;
-  typedef nsTArray<SmartPtr> SmartPtrArray;
-
-  template<class U>
-  static inline void
-  AppendAndTake(nsTArray<nsRefPtr<U>>& smartPtrArray, U* ptr)
-  {
-    smartPtrArray.AppendElement(dont_AddRef(ptr));
-  }
-  template<class U>
-  static inline void
-  AppendAndTake(nsTArray<nsAutoPtr<U>>& smartPtrArray, U* ptr)
-  {
-    smartPtrArray.AppendElement(ptr);
-  }
+  typedef nsTArray<SmartPtr<T> > SmartPtrArray;
 
   static void*
   AppendDeferredFinalizePointer(void* aData, void* aObject)
   {
     SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData);
     if (!pointers) {
       pointers = new SmartPtrArray();
     }
-    AppendAndTake(*pointers, static_cast<T*>(aObject));
+
+    T* self = static_cast<T*>(aObject);
+
+    SmartPtr<T>* defer = pointers->AppendElement();
+    Take(*defer, self);
     return pointers;
   }
   static bool
   DeferredFinalize(uint32_t aSlice, void* aData)
   {
     MOZ_ASSERT(aSlice > 0, "nonsensical/useless call with aSlice == 0");
     SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData);
     uint32_t oldLen = pointers->Length();
@@ -2893,32 +2795,32 @@ public:
   static void
   AddForDeferredFinalization(T* aObject)
   {
     cyclecollector::DeferredFinalize(AppendDeferredFinalizePointer,
                                      DeferredFinalize, aObject);
   }
 };
 
-template<class T>
-class DeferredFinalizer<T, true>
+template<class T, template <typename> class SmartPtr>
+class DeferredFinalizer<T, SmartPtr, true>
 {
 public:
   static void
   AddForDeferredFinalization(T* aObject)
   {
     cyclecollector::DeferredFinalize(reinterpret_cast<nsISupports*>(aObject));
   }
 };
 
-template<class T>
+template<class T, template <typename> class SmartPtr>
 static void
 AddForDeferredFinalization(T* aObject)
 {
-  DeferredFinalizer<T>::AddForDeferredFinalization(aObject);
+  DeferredFinalizer<T, SmartPtr>::AddForDeferredFinalization(aObject);
 }
 
 // This returns T's CC participant if it participates in CC or null if it
 // doesn't. This also returns null for classes that don't inherit from
 // nsISupports (QI should be used to get the participant for those).
 template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
 class GetCCParticipant
 {
@@ -3202,36 +3104,27 @@ WrappedJSToDictionary(nsISupports* aObje
 
 template<class T, class S>
 inline nsRefPtr<T>
 StrongOrRawPtr(already_AddRefed<S>&& aPtr)
 {
   return aPtr.template downcast<T>();
 }
 
-template<class T,
-         class ReturnType=typename Conditional<IsRefcounted<T>::value, T*,
-                                               nsAutoPtr<T>>::Type>
-inline ReturnType
+template<class T>
+inline T*
 StrongOrRawPtr(T* aPtr)
 {
-  return ReturnType(aPtr);
+  return aPtr;
 }
 
 template<class T, template<typename> class SmartPtr, class S>
 inline void
 StrongOrRawPtr(SmartPtr<S>&& aPtr) = delete;
 
-template<class T>
-struct StrongPtrForMember
-{
-  typedef typename Conditional<IsRefcounted<T>::value,
-                               nsRefPtr<T>, nsAutoPtr<T>>::Type Type;
-};
-
 inline
 JSObject*
 GetErrorPrototype(JSContext* aCx, JS::Handle<JSObject*> aForObj)
 {
   return JS_GetErrorPrototype(aCx);
 }
 
 } // namespace dom
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -39,16 +39,32 @@
 #                   in the WebIDL.
 #   * wrapperCache: True if this object is a wrapper cache.  Objects that are
 #                   not can only be returned from a limited set of methods,
 #                   cannot be prefable, and must ensure that they disallow
 #                   XPConnect wrapping.  Always false for callback interfaces.
 #                   Always true for worker descriptors for non-callback
 #                   interfaces.  Defaults to true for non-worker non-callback
 #                   descriptors.
+#   * nativeOwnership: Describes how the native object is held. 3 possible
+#                      types: worker object ('worker'), non-refcounted object
+#                      ('owned'), refcounted object ('refcounted').
+#                      Non-refcounted objects need to inherit from
+#                      mozilla::dom::NonRefcountedDOMObject and preferably use
+#                      MOZ_COUNT_CTOR/MOZ_COUNT_DTOR in their
+#                      constructor/destructor so they participate in leak
+#                      logging.
+#                      This mostly determines how the finalizer releases the
+#                      binding's hold on the native object. For a worker object
+#                      it'll call Release, for a non-refcounted object it'll
+#                      call delete through XPConnect's deferred finalization
+#                      mechanism, for a refcounted object it'll call Release
+#                      through XPConnect's deferred finalization mechanism.
+#                      'worker' opts into old style worker models. Defaults to
+#                      'refcounted'.
 #
 #   The following fields are either a string, an array (defaults to an empty
 #   array) or a dictionary with three possible keys (all, getterOnly and
 #   setterOnly) each having such an array as the value
 #
 #   * implicitJSContext - attributes and methods specified in the .webidl file
 #                         that require a JSContext as the first argument
 #
@@ -1206,25 +1222,25 @@ DOMInterfaces = {
 
 'Text': {
     # Total hack to allow binding code to realize that nsTextNode can
     # in fact be cast to Text.
     'headerFile': 'nsTextNode.h',
 },
 
 'TextDecoder': {
-    'wrapperCache': False
+    'nativeOwnership': 'owned',
 },
 
 'TextEncoder': {
-    'wrapperCache': False
+    'nativeOwnership': 'owned',
 },
 
 'TextMetrics': {
-    'wrapperCache': False
+    'nativeOwnership': 'owned',
 },
 
 'TimeRanges': {
     'wrapperCache': False
 },
 
 'TouchList': {
     'headerFile': 'mozilla/dom/TouchEvent.h',
@@ -1250,23 +1266,18 @@ DOMInterfaces = {
 'URL' : [{
     'wrapperCache': False,
 },
 {
     'workers': True,
     'wrapperCache': False,
 }],
 
-'VRFieldOfView': {
-    'wrapperCache': False,
-},
-
 'VRFieldOfViewReadOnly': {
-    'concrete': False,
-    'wrapperCache': False,
+    'concrete': False
 },
 
 'VRDevice': {
     'concrete': False
 },
 
 'VTTCue': {
     'nativeType': 'mozilla::dom::TextTrackCue'
@@ -1573,16 +1584,17 @@ DOMInterfaces = {
 },
 
 'XPathEvaluator': {
     'wrapperCache': False
 },
 
 'XPathExpression': {
     'wrapperCache': False,
+    'nativeOwnership': 'owned',
 },
 
 'XSLTProcessor': {
     'nativeType': 'txMozillaXSLTProcessor',
 },
 
 'XULDocument': {
     'headerFile': 'XULDocument.h'
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1560,26 +1560,34 @@ class CGAddPropertyHook(CGAbstractClassH
             // We don't want to preserve if we don't have a wrapper.
             if (self->GetWrapperPreserveColor()) {
               PreserveWrapper(self);
             }
             return true;
             """)
 
 
+def DeferredFinalizeSmartPtr(descriptor):
+    if descriptor.nativeOwnership == 'owned':
+        smartPtr = 'nsAutoPtr'
+    else:
+        smartPtr = 'nsRefPtr'
+    return smartPtr
+
+
 def finalizeHook(descriptor, hookName, freeOp):
     finalize = "JSBindingFinalized<%s>::Finalized(self);\n" % descriptor.nativeType
     if descriptor.wrapperCache:
         finalize += "ClearWrapper(self, self);\n"
     if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
         finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
     if descriptor.isGlobal():
         finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), obj);\n" % freeOp
-    finalize += ("AddForDeferredFinalization<%s>(self);\n" %
-                 descriptor.nativeType)
+    finalize += ("AddForDeferredFinalization<%s, %s >(self);\n" %
+                 (descriptor.nativeType, DeferredFinalizeSmartPtr(descriptor)))
     return CGIfWrapper(CGGeneric(finalize), "self")
 
 
 class CGClassFinalizeHook(CGAbstractClassHook):
     """
     A hook for finalize, used to release our native object.
     """
     def __init__(self, descriptor):
@@ -3052,45 +3060,60 @@ class CGConstructorEnabled(CGAbstractMet
         else:
           conditionsWrapper = CGGeneric("return true;\n")
 
         body.append(conditionsWrapper)
         return body.define()
 
 
 def CreateBindingJSObject(descriptor, properties):
-    objDecl = "BindingJSObjectCreator<%s> creator(aCx);\n" % descriptor.nativeType
-
     # We don't always need to root obj, but there are a variety
     # of cases where we do, so for simplicity, just always root it.
+    objDecl = "JS::Rooted<JSObject*> obj(aCx);\n"
     if descriptor.proxy:
         create = dedent(
             """
-            creator.CreateProxyObject(aCx, &Class.mBase, DOMProxyHandler::getInstance(),
-                                      proto, global, aObject, aReflector);
-            if (!aReflector) {
-              return false;
+            JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aObject));
+            js::ProxyOptions options;
+            options.setClass(&Class.mBase);
+            obj = NewProxyObject(aCx, DOMProxyHandler::getInstance(),
+                                 proxyPrivateVal, proto, global, options);
+            if (!obj) {
+              return nullptr;
             }
 
             """)
         if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
             create += dedent("""
-                js::SetProxyExtra(aReflector, JSPROXYSLOT_EXPANDO,
+                js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
                                   JS::PrivateValue(&aObject->mExpandoAndGeneration));
 
                 """)
     else:
         create = dedent(
             """
-            creator.CreateObject(aCx, Class.ToJSClass(), proto, global, aObject, aReflector);
-            if (!aReflector) {
-              return false;
-            }
+            obj = JS_NewObject(aCx, Class.ToJSClass(), proto, global);
+            if (!obj) {
+              return nullptr;
+            }
+
+            js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
             """)
-    return objDecl + create
+    create = objDecl + create
+
+    if descriptor.nativeOwnership == 'refcounted':
+        create += "NS_ADDREF(aObject);\n"
+    else:
+        create += dedent("""
+            // Make sure the native objects inherit from NonRefcountedDOMObject so that we
+            // log their ctor and dtor.
+            MustInheritFromNonRefcountedDOMObject(aObject);
+            *aTookOwnership = true;
+            """)
+    return create
 
 
 def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturnValue=""):
     """
     properties is a PropertyArrays instance
     """
     unforgeables = []
 
@@ -3153,17 +3176,17 @@ def InitUnforgeableProperties(descriptor
         return ""
 
     if descriptor.proxy:
         unforgeableProperties = CGGeneric(
             "// Unforgeable properties on proxy-based bindings are stored in an object held\n"
             "// by the interface prototype object.\n")
     else:
         unforgeableProperties = CGWrapper(
-            InitUnforgeablePropertiesOnObject(descriptor, "aReflector", properties, "false"),
+            InitUnforgeablePropertiesOnObject(descriptor, "obj", properties, "nullptr"),
             pre=(
                 "// Important: do unforgeable property setup after we have handed\n"
                 "// over ownership of the C++ object to obj as needed, so that if\n"
                 "// we fail and it ends up GCed it won't have problems in the\n"
                 "// finalizer trying to drop its ownership of the C++ object.\n"))
     return CGWrapper(unforgeableProperties, pre="\n").define()
 
 
@@ -3191,72 +3214,73 @@ def InitMemberSlots(descriptor, wrapperC
     ClearWrapper.
     """
     if not descriptor.interface.hasMembersInSlots():
         return ""
     if wrapperCache:
         clearWrapper = "  aCache->ClearWrapper();\n"
     else:
         clearWrapper = ""
-    return ("if (!UpdateMemberSlots(aCx, aReflector, aObject)) {\n"
+    return ("if (!UpdateMemberSlots(aCx, obj, aObject)) {\n"
             "%s"
-            "  return false;\n"
+            "  return nullptr;\n"
             "}\n" % clearWrapper)
 
 
 class CGWrapWithCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that implements nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
-                Argument('nsWrapperCache*', 'aCache'),
-                Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
-        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
+                Argument('nsWrapperCache*', 'aCache')]
+        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
             $*{assertion}
 
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
                        "nsISupports must be on our primary inheritance chain");
 
             JS::Rooted<JSObject*> parent(aCx, WrapNativeParent(aCx, aObject->GetParentObject()));
             if (!parent) {
-              return false;
+              return nullptr;
             }
 
             // That might have ended up wrapping us already, due to the wonders
-            // of XBL.  Check for that, and bail out as needed.
-            aReflector.set(aCache->GetWrapper());
-            if (aReflector) {
-              return true;
+            // of XBL.  Check for that, and bail out as needed.  Scope so we don't
+            // collide with the "obj" we declare in CreateBindingJSObject.
+            {
+              JSObject* obj = aCache->GetWrapper();
+              if (obj) {
+                return obj;
+              }
             }
 
             JSAutoCompartment ac(aCx, parent);
             JS::Rooted<JSObject*> global(aCx, js::GetGlobalForObjectCrossCompartment(parent));
             JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
             if (!proto) {
-              return false;
+              return nullptr;
             }
 
             $*{createObject}
 
             $*{unforgeable}
 
-            aCache->SetWrapper(aReflector);
+            aCache->SetWrapper(obj);
             $*{slots}
-            creator.InitializationSucceeded();
-            return true;
+            return obj;
             """,
             assertion=AssertInheritanceChain(self.descriptor),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
             slots=InitMemberSlots(self.descriptor, True))
 
 
 class CGWrapMethod(CGAbstractMethod):
@@ -3264,56 +3288,53 @@ class CGWrapMethod(CGAbstractMethod):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument('T*', 'aObject')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args,
                                   inline=True, templateArgs=["class T"])
 
     def definition_body(self):
-        return dedent("""
-            JS::Rooted<JSObject*> reflector(aCx);
-            return Wrap(aCx, aObject, aObject, &reflector) ? reflector.get() : nullptr;
-            """)
+        return "return Wrap(aCx, aObject, aObject);\n"
 
 
 class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that does not implement
     nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
-                Argument(descriptor.nativeType + '*', 'aObject'),
-                Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
-        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
+                Argument(descriptor.nativeType + '*', 'aObject')]
+        if descriptor.nativeOwnership == 'owned':
+            args.append(Argument('bool*', 'aTookOwnership'))
+        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
             $*{assertions}
 
             JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
             JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
             if (!proto) {
-              return false;
+              return nullptr;
             }
 
             $*{createObject}
 
             $*{unforgeable}
 
             $*{slots}
-            creator.InitializationSucceeded();
-            return true;
+            return obj;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
             slots=InitMemberSlots(self.descriptor, False))
 
 
 class CGWrapGlobalMethod(CGAbstractMethod):
@@ -3325,70 +3346,70 @@ class CGWrapGlobalMethod(CGAbstractMetho
     """
     def __init__(self, descriptor, properties):
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
                 Argument('nsWrapperCache*', 'aCache'),
                 Argument('JS::CompartmentOptions&', 'aOptions'),
                 Argument('JSPrincipals*', 'aPrincipal'),
-                Argument('bool', 'aInitStandardClasses'),
-                Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
-        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
+                Argument('bool', 'aInitStandardClasses')]
+        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
         self.descriptor = descriptor
         self.properties = properties
 
     def definition_body(self):
         if self.properties.hasNonChromeOnly():
             properties = "GlobalPropertiesAreOwn() ? &sNativeProperties : nullptr"
         else:
             properties = "nullptr"
         if self.properties.hasChromeOnly():
             chromeProperties = "GlobalPropertiesAreOwn() && nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
         else:
             chromeProperties = "nullptr"
 
         if self.descriptor.workers:
             fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
-// JS_FireOnNewGlobalObject(aCx, aReflector);
+// JS_FireOnNewGlobalObject(aCx, obj);
 """
         else:
             fireOnNewGlobal = ""
 
         return fill(
             """
             $*{assertions}
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
                        "nsISupports must be on our primary inheritance chain");
 
+            JS::Rooted<JSObject*> obj(aCx);
             CreateGlobal<${nativeType}, GetProtoObjectHandle>(aCx,
                                              aObject,
                                              aCache,
                                              Class.ToJSClass(),
                                              aOptions,
                                              aPrincipal,
                                              aInitStandardClasses,
-                                             aReflector);
-            if (!aReflector) {
-              return false;
-            }
-
-            // aReflector is a new global, so has a new compartment.  Enter it
+                                             &obj);
+            if (!obj) {
+              return nullptr;
+            }
+
+            // obj is a new global, so has a new compartment.  Enter it
             // before doing anything with it.
-            JSAutoCompartment ac(aCx, aReflector);
-
-            if (!DefineProperties(aCx, aReflector, ${properties}, ${chromeProperties})) {
-              return false;
+            JSAutoCompartment ac(aCx, obj);
+
+            if (!DefineProperties(aCx, obj, ${properties}, ${chromeProperties})) {
+              return nullptr;
             }
             $*{unforgeable}
 
             $*{slots}
             $*{fireOnNewGlobal}
 
-            return true;
+            return obj;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
             nativeType=self.descriptor.nativeType,
             properties=properties,
             chromeProperties=chromeProperties,
             unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
             slots=InitMemberSlots(self.descriptor, True),
             fireOnNewGlobal=fireOnNewGlobal)
@@ -4678,16 +4699,22 @@ def getJSToNativeConversionInfo(type, de
         # addrefing anyway, so there is no point trying to avoid it here and it
         # makes other things simpler since we can assume the return value is a
         # strong ref.
         forceOwningType = ((descriptor.interface.isCallback() and
                             not descriptor.workers) or
                            isMember or
                            isCallbackReturnValue)
 
+        if forceOwningType and descriptor.nativeOwnership == 'owned':
+            raise TypeError("Interface %s has 'owned' nativeOwnership, so we "
+                            "don't know how to keep it alive in %s" %
+                            (descriptor.interface.identifier.name,
+                             sourceDescription))
+
         typeName = descriptor.nativeType
         typePtr = typeName + "*"
 
         # Compute a few things:
         #  - declType is the type we want to return as the first element of our
         #    tuple.
         #  - holderType is the type we want to return as the third element
         #    of our tuple.
@@ -4701,18 +4728,16 @@ def getJSToNativeConversionInfo(type, de
                 declType = typePtr
         else:
             if forceOwningType:
                 declType = "OwningNonNull<" + typeName + ">"
             else:
                 declType = "NonNull<" + typeName + ">"
 
         templateBody = ""
-        if forceOwningType:
-            templateBody += 'static_assert(IsRefcounted<%s>::value, "We can only store refcounted classes.");' % typeName
         if not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal():
             if failureCode is not None:
                 templateBody += str(CastableObjectUnwrapper(
                     descriptor,
                     "&${val}.toObject()",
                     "${declName}",
                     failureCode))
             else:
@@ -5739,21 +5764,25 @@ def getWrapTemplateForType(type, descrip
             wrappingCode = ("if (!%s) {\n" % (result) +
                             indent(setNull()) +
                             "}\n")
         else:
             wrappingCode = ""
 
         if not descriptor.interface.isExternal() and not descriptor.skipGen:
             if descriptor.wrapperCache:
+                assert descriptor.nativeOwnership != 'owned'
                 wrapMethod = "GetOrCreateDOMReflector"
             else:
                 if not returnsNewObject:
                     raise MethodNotNewObjectError(descriptor.interface.identifier.name)
-                wrapMethod = "WrapNewBindingNonWrapperCachedObject"
+                if descriptor.nativeOwnership == 'owned':
+                    wrapMethod = "WrapNewBindingNonWrapperCachedOwnedObject"
+                else:
+                    wrapMethod = "WrapNewBindingNonWrapperCachedObject"
             wrap = "%s(cx, ${obj}, %s, ${jsvalHandle})" % (wrapMethod, result)
             if not descriptor.hasXPConnectImpls:
                 # Can only fail to wrap as a new-binding object
                 # if they already threw an exception.
                 #XXX Assertion disabled for now, see bug 991271.
                 failed = ("MOZ_ASSERT(true || JS_IsExceptionPending(cx));\n" +
                           exceptionCode)
             else:
@@ -6064,18 +6093,21 @@ def getRetvalDeclarationForType(returnTy
         result = CGGeneric(returnType.unroll().inner.identifier.name)
         if returnType.nullable():
             result = CGTemplatedType("Nullable", result)
         return result, None, None, None, None
     if returnType.isGeckoInterface():
         result = CGGeneric(descriptorProvider.getDescriptor(
             returnType.unroll().inner.identifier.name).nativeType)
         conversion = None
-        if isMember:
-            result = CGGeneric("StrongPtrForMember<%s>::Type" % result.define())
+        if descriptorProvider.getDescriptor(
+                returnType.unroll().inner.identifier.name).nativeOwnership == 'owned':
+            result = CGTemplatedType("nsAutoPtr", result)
+        elif isMember:
+            result = CGTemplatedType("nsRefPtr", result)
         else:
             conversion = CGGeneric("StrongOrRawPtr<%s>" % result.define())
             result = CGGeneric("auto")
         return result, None, None, None, conversion
     if returnType.isCallback():
         name = returnType.unroll().identifier.name
         return CGGeneric("nsRefPtr<%s>" % name), None, None, None, None
     if returnType.isAny():
@@ -6656,17 +6688,18 @@ class CGPerSignatureCall(CGThing):
     def isFallible(self):
         return 'infallible' not in self.extendedAttributes
 
     def wrap_return_value(self):
         wrapCode = ""
 
         returnsNewObject = memberReturnsNewObject(self.idlNode)
         if (returnsNewObject and
-            self.returnType.isGeckoInterface()):
+            self.returnType.isGeckoInterface() and
+            not self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned'):
             wrapCode += dedent(
                 """
                 static_assert(!IsPointer<decltype(result)>::value,
                               "NewObject implies that we need to keep the object alive with a strong reference.");
                 """)
 
         setSlot = self.idlNode.isAttr() and self.idlNode.slotIndex is not None
         if setSlot:
@@ -10956,27 +10989,26 @@ def memberProperties(m, descriptor):
     return props
 
 class CGDescriptor(CGThing):
     def __init__(self, descriptor):
         CGThing.__init__(self)
 
         assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
 
+        if descriptor.nativeOwnership == 'owned' and (
+                descriptor.interface.hasChildInterfaces() or
+                descriptor.interface.parent):
+            raise TypeError("Owned interface cannot have a parent or children")
+
         self._deps = descriptor.interface.getDeps()
 
         cgThings = []
         cgThings.append(CGGeneric(declare="typedef %s NativeType;\n" %
                                   descriptor.nativeType))
-        parent = descriptor.interface.parent
-        if parent:
-            cgThings.append(CGGeneric("static_assert(IsRefcounted<NativeType>::value == IsRefcounted<%s::NativeType>::value,\n"
-                                      "              \"Can't inherit from an interface with a different ownership model.\");\n" %
-                                      toBindingNamespace(descriptor.parentPrototypeName)))
-
         # These are set to true if at least one non-static
         # method/getter/setter or jsonifier exist on the interface.
         (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasLenientSetter,
             hasPromiseReturningMethod) = False, False, False, False, False, False
         jsonifierMethod = None
         crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
         for n in descriptor.interface.namedConstructors:
             cgThings.append(CGClassConstructor(descriptor, n,
@@ -12176,20 +12208,17 @@ class CGForwardDeclarations(CGWrapper):
 
 
 class CGBindingRoot(CGThing):
     """
     Root codegen class for binding generation. Instantiate the class, and call
     declare or define to generate header or cpp code (respectively).
     """
     def __init__(self, config, prefix, webIDLFile):
-        bindingHeaders = dict.fromkeys((
-            'mozilla/dom/NonRefcountedDOMObject.h',
-            ),
-            True)
+        bindingHeaders = {}
         bindingDeclareHeaders = dict.fromkeys((
             'mozilla/dom/BindingDeclarations.h',
             'mozilla/dom/Nullable.h',
             'mozilla/ErrorResult.h',
             ),
             True)
 
         descriptors = config.getDescriptors(webIDLFile=webIDLFile,
@@ -12221,16 +12250,18 @@ class CGBindingRoot(CGThing):
         bindingDeclareHeaders["js/RootingAPI.h"] = not bindingDeclareHeaders["jsapi.h"]
 
         def descriptorRequiresPreferences(desc):
             iface = desc.interface
             return any(m.getExtendedAttribute("Pref") for m in iface.members + [iface])
 
         bindingHeaders["mozilla/Preferences.h"] = any(
             descriptorRequiresPreferences(d) for d in descriptors)
+        bindingHeaders["mozilla/dom/NonRefcountedDOMObject.h"] = any(
+            d.nativeOwnership == 'owned' for d in descriptors)
         bindingHeaders["mozilla/dom/DOMJSProxyHandler.h"] = any(
             d.concrete and d.proxy for d in descriptors)
 
         def descriptorHasChromeOnly(desc):
             return (any(isChromeOnly(a) for a in desc.interface.members) or
                     desc.interface.getExtendedAttribute("ChromeOnly") is not None or
                     # JS-implemented interfaces with an interface object get a
                     # chromeonly _create method.
@@ -13030,40 +13061,50 @@ class CGExampleClass(CGBindingImplClass)
     """
     Codegen for the actual example class implementation for this descriptor
     """
     def __init__(self, descriptor):
         CGBindingImplClass.__init__(self, descriptor,
                                     CGExampleMethod, CGExampleGetter, CGExampleSetter,
                                     wantGetParent=descriptor.wrapperCache)
 
+        self.refcounted = descriptor.nativeOwnership == "refcounted"
+
         self.parentIface = descriptor.interface.parent
         if self.parentIface:
             self.parentDesc = descriptor.getDescriptor(
                 self.parentIface.identifier.name)
             bases = [ClassBase(self.nativeLeafName(self.parentDesc))]
         else:
-            bases = [ ClassBase("nsISupports /* or NonRefcountedDOMObject if this is a non-refcounted object */") ]
-            if descriptor.wrapperCache:
-                bases.append(ClassBase("nsWrapperCache /* Change wrapperCache in the binding configuration if you don't want this */"))
-
-        destructorVisibility = "protected"
-        if self.parentIface:
-            extradeclarations = (
-                "public:\n"
-                "  NS_DECL_ISUPPORTS_INHERITED\n"
-                "  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(%s, %s)\n"
-                "\n" % (self.nativeLeafName(descriptor),
-                        self.nativeLeafName(self.parentDesc)))
-        else:
-            extradeclarations = (
-                "public:\n"
-                "  NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n"
-                "  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(%s)\n"
-                "\n" % self.nativeLeafName(descriptor))
+            bases = []
+            if self.refcounted:
+                bases.append(ClassBase("nsISupports /* Change nativeOwnership in the binding configuration if you don't want this */"))
+                if descriptor.wrapperCache:
+                    bases.append(ClassBase("nsWrapperCache /* Change wrapperCache in the binding configuration if you don't want this */"))
+            else:
+                bases.append(ClassBase("NonRefcountedDOMObject"))
+
+        if self.refcounted:
+            destructorVisibility = "protected"
+            if self.parentIface:
+                extradeclarations = (
+                    "public:\n"
+                    "  NS_DECL_ISUPPORTS_INHERITED\n"
+                    "  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(%s, %s)\n"
+                    "\n" % (self.nativeLeafName(descriptor),
+                            self.nativeLeafName(self.parentDesc)))
+            else:
+                extradeclarations = (
+                    "public:\n"
+                    "  NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n"
+                    "  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(%s)\n"
+                    "\n" % self.nativeLeafName(descriptor))
+        else:
+            destructorVisibility = "public"
+            extradeclarations = ""
 
         if descriptor.interface.hasChildInterfaces():
             decorators = ""
         else:
             decorators = "MOZ_FINAL"
 
         CGClass.__init__(self, self.nativeLeafName(descriptor),
                          bases=bases,
@@ -13071,52 +13112,64 @@ class CGExampleClass(CGBindingImplClass)
                                                         visibility="public")],
                          destructor=ClassDestructor(visibility=destructorVisibility),
                          methods=self.methodDecls,
                          decorators=decorators,
                          extradeclarations=extradeclarations)
 
     def define(self):
         # Just override CGClass and do our own thing
-        ctordtor = dedent("""
-            ${nativeType}::${nativeType}()
-            {
-                // Add |MOZ_COUNT_CTOR(${nativeType});| for a non-refcounted object.
-            }
-
-            ${nativeType}::~${nativeType}()
-            {
-                // Add |MOZ_COUNT_DTOR(${nativeType});| for a non-refcounted object.
-            }
-            """)
-
-        if self.parentIface:
-            ccImpl = dedent("""
-
-                // Only needed for refcounted objects.
-                NS_IMPL_CYCLE_COLLECTION_INHERITED_0(${nativeType}, ${parentType})
-                NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
-                NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
-                NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
-                NS_INTERFACE_MAP_END_INHERITING(${parentType})
-
+        if self.refcounted:
+            ctordtor = dedent("""
+                ${nativeType}::${nativeType}()
+                {
+                }
+
+                ${nativeType}::~${nativeType}()
+                {
+                }
+                """)
+        else:
+            ctordtor = dedent("""
+                ${nativeType}::${nativeType}()
+                {
+                  MOZ_COUNT_CTOR(${nativeType});
+                }
+
+                ${nativeType}::~${nativeType}()
+                {
+                  MOZ_COUNT_DTOR(${nativeType});
+                }
                 """)
-        else:
-            ccImpl = dedent("""
-
-                // Only needed for refcounted objects.
-                NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${nativeType})
-                NS_IMPL_CYCLE_COLLECTING_ADDREF(${nativeType})
-                NS_IMPL_CYCLE_COLLECTING_RELEASE(${nativeType})
-                NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
-                  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-                  NS_INTERFACE_MAP_ENTRY(nsISupports)
-                NS_INTERFACE_MAP_END
-
-                """)
+
+        if self.refcounted:
+            if self.parentIface:
+                ccImpl = dedent("""
+
+                    NS_IMPL_CYCLE_COLLECTION_INHERITED_0(${nativeType}, ${parentType})
+                    NS_IMPL_ADDREF_INHERITED(${nativeType}, ${parentType})
+                    NS_IMPL_RELEASE_INHERITED(${nativeType}, ${parentType})
+                    NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
+                    NS_INTERFACE_MAP_END_INHERITING(${parentType})
+
+                    """)
+            else:
+                ccImpl = dedent("""
+
+                    NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(${nativeType})
+                    NS_IMPL_CYCLE_COLLECTING_ADDREF(${nativeType})
+                    NS_IMPL_CYCLE_COLLECTING_RELEASE(${nativeType})
+                    NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(${nativeType})
+                      NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+                      NS_INTERFACE_MAP_ENTRY(nsISupports)
+                    NS_INTERFACE_MAP_END
+
+                    """)
+        else:
+            ccImpl = ""
 
         classImpl = ccImpl + ctordtor + "\n" + dedent("""
             JSObject*
             ${nativeType}::WrapObject(JSContext* aCx)
             {
               return ${ifaceName}Binding::Wrap(aCx, this);
             }
 
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -451,20 +451,26 @@ class Descriptor(DescriptorProvider):
                     raise SyntaxError("%s supports named properties but does "
                                       "not have a named getter.\n%s" %
                                       (self.interface, self.interface.location))
                 iface = self.interface
                 while iface:
                     iface.setUserData('hasProxyDescendant', True)
                     iface = iface.parent
 
+        self.nativeOwnership = desc.get('nativeOwnership', 'refcounted')
+        if not self.nativeOwnership in ('owned', 'refcounted'):
+            raise TypeError("Descriptor for %s has unrecognized value (%s) "
+                            "for nativeOwnership" %
+                            (self.interface.identifier.name, self.nativeOwnership))
         if desc.get('wantsQI', None) != None:
             self._wantsQI = desc.get('wantsQI', None)
         self.wrapperCache = (not self.interface.isCallback() and
-                             desc.get('wrapperCache', True))
+                             (self.nativeOwnership != 'owned' and
+                              desc.get('wrapperCache', True)))
 
         def make_name(name):
             return name + "_workers" if self.workers else name
         self.name = make_name(interface.identifier.name)
 
         # self.extendedAttributes is a dict of dicts, keyed on
         # all/getterOnly/setterOnly and then on member name. Values are an
         # array of extended attributes.
--- a/dom/bindings/NonRefcountedDOMObject.h
+++ b/dom/bindings/NonRefcountedDOMObject.h
@@ -7,22 +7,22 @@
 #ifndef mozilla_dom_NonRefcountedDOMObject_h__
 #define mozilla_dom_NonRefcountedDOMObject_h__
 
 #include "nsISupportsImpl.h"
 
 namespace mozilla {
 namespace dom {
 
-// Natives for DOM classes that aren't refcounted need to inherit from this
-// class.
+// Natives for DOM classes with 'owned' as the value for nativeOwnership in
+// Bindings.conf need to inherit from this class.
 // If you're seeing objects of this class leak then natives for one of the DOM
-// classes inheriting from it is leaking. If the native for that class has
-// MOZ_COUNT_CTOR/DTOR in its constructor/destructor then it should show up in
-// the leak log too.
+// classes with 'owned' as the value for nativeOwnership in Bindings.conf is
+// leaking. If the native for that class has MOZ_COUNT_CTOR/DTOR in its
+// constructor/destructor then it should show up in the leak log too.
 class NonRefcountedDOMObject
 {
 protected:
   NonRefcountedDOMObject()
   {
     MOZ_COUNT_CTOR(NonRefcountedDOMObject);
   }
   ~NonRefcountedDOMObject()
--- a/dom/bindings/StructuredClone.cpp
+++ b/dom/bindings/StructuredClone.cpp
@@ -27,19 +27,17 @@ ReadStructuredCloneImageData(JSContext* 
 
   // Protect the result from a moving GC in ~nsRefPtr.
   JS::Rooted<JSObject*> result(aCx);
   {
     // Construct the ImageData.
     nsRefPtr<ImageData> imageData = new ImageData(width, height,
                                                   dataArray.toObject());
     // Wrap it in a JS::Value.
-    if (!imageData->WrapObject(aCx, &result)) {
-      return nullptr;
-    }
+    result = imageData->WrapObject(aCx);
   }
   return result;
 }
 
 bool
 WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter,
                               ImageData* aImageData)
 {
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -85,17 +85,17 @@ public:
 
 NS_DEFINE_STATIC_IID_ACCESSOR(TestExternalInterface, NS_TEST_EXTERNAL_INTERFACE_IID)
 
 class TestNonWrapperCacheInterface : public nsISupports
 {
 public:
   NS_DECL_ISUPPORTS
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  virtual JSObject* WrapObject(JSContext* cx);
 };
 
 class OnlyForUseInConstructor : public nsISupports,
                                 public nsWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS
   // We need a GetParentObject to make binding codegen happy
--- a/dom/canvas/ImageData.cpp
+++ b/dom/canvas/ImageData.cpp
@@ -103,16 +103,16 @@ void
 ImageData::DropData()
 {
   if (mData) {
     mData = nullptr;
     mozilla::DropJSObjects(this);
   }
 }
 
-bool
-ImageData::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+ImageData::WrapObject(JSContext* cx)
 {
-  return ImageDataBinding::Wrap(aCx, this, aReflector);
+  return ImageDataBinding::Wrap(cx, this);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/ImageData.h
+++ b/dom/canvas/ImageData.h
@@ -68,17 +68,17 @@ public:
     aData.set(GetDataObject());
   }
   JSObject* GetDataObject() const
   {
     JS::ExposeObjectToActiveJS(mData);
     return mData;
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject* WrapObject(JSContext* cx);
 
 private:
   void HoldData();
   void DropData();
 
   ImageData() = delete;
 
   uint32_t mWidth, mHeight;
--- a/dom/canvas/TextMetrics.h
+++ b/dom/canvas/TextMetrics.h
@@ -25,19 +25,19 @@ public:
     MOZ_COUNT_DTOR(TextMetrics);
   }
 
   float Width() const
   {
     return width;
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  JSObject* WrapObject(JSContext* aCx, bool* aTookOwnership)
   {
-    return TextMetricsBinding::Wrap(aCx, this, aReflector);
+    return TextMetricsBinding::Wrap(aCx, this, aTookOwnership);
   }
 
 private:
   float width;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/WebGLActiveInfo.cpp
+++ b/dom/canvas/WebGLActiveInfo.cpp
@@ -6,16 +6,15 @@
 #include "WebGLActiveInfo.h"
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 #include "WebGLTexture.h"
 
 namespace mozilla {
 
-bool
-WebGLActiveInfo::WrapObject(JSContext* aCx,
-                            JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+WebGLActiveInfo::WrapObject(JSContext* cx)
 {
-    return dom::WebGLActiveInfoBinding::Wrap(aCx, this, aReflector);
+    return dom::WebGLActiveInfoBinding::Wrap(cx, this);
 }
 
 } // namespace mozilla
--- a/dom/canvas/WebGLActiveInfo.h
+++ b/dom/canvas/WebGLActiveInfo.h
@@ -30,17 +30,17 @@ public:
     GLenum Type() const {
         return mType;
     }
 
     void GetName(nsString& retval) const {
         retval = mName;
     }
 
-    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+    JSObject* WrapObject(JSContext* cx);
 
    NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo)
 
 private:
     // Private destructor, to discourage deletion outside of Release():
     ~WebGLActiveInfo()
     {
     }
--- a/dom/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/dom/canvas/WebGLShaderPrecisionFormat.cpp
@@ -5,16 +5,15 @@
 
 #include "WebGLShaderPrecisionFormat.h"
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 
 namespace mozilla {
 
-bool
-WebGLShaderPrecisionFormat::WrapObject(JSContext* aCx,
-                                       JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+WebGLShaderPrecisionFormat::WrapObject(JSContext* cx)
 {
-    return dom::WebGLShaderPrecisionFormatBinding::Wrap(aCx, this, aReflector);
+    return dom::WebGLShaderPrecisionFormatBinding::Wrap(cx, this);
 }
 
 } // namespace mozilla
--- a/dom/canvas/WebGLShaderPrecisionFormat.h
+++ b/dom/canvas/WebGLShaderPrecisionFormat.h
@@ -19,17 +19,17 @@ public:
     WebGLShaderPrecisionFormat(WebGLContext* context, GLint rangeMin,
                                GLint rangeMax, GLint precision)
         : WebGLContextBoundObject(context)
         , mRangeMin(rangeMin)
         , mRangeMax(rangeMax)
         , mPrecision(precision)
     { }
 
-    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+    JSObject* WrapObject(JSContext* cx);
 
     // WebIDL WebGLShaderPrecisionFormat API
     GLint RangeMin() const {
         return mRangeMin;
     }
 
     GLint RangeMax() const {
         return mRangeMax;
--- a/dom/canvas/WebGLUniformLocation.cpp
+++ b/dom/canvas/WebGLUniformLocation.cpp
@@ -7,21 +7,20 @@
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 #include "WebGLProgram.h"
 #include "WebGLShader.h"
 
 namespace mozilla {
 
-bool
-WebGLUniformLocation::WrapObject(JSContext* aCx,
-                                 JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+WebGLUniformLocation::WrapObject(JSContext* cx)
 {
-    return dom::WebGLUniformLocationBinding::Wrap(aCx, this, aReflector);
+    return dom::WebGLUniformLocationBinding::Wrap(cx, this);
 }
 
 WebGLUniformLocation::WebGLUniformLocation(WebGLContext* context,
                                            WebGLProgram* program,
                                            GLint location,
                                            const WebGLUniformInfo& info)
     : WebGLContextBoundObject(context)
     , mProgram(program)
--- a/dom/canvas/WebGLUniformLocation.h
+++ b/dom/canvas/WebGLUniformLocation.h
@@ -26,17 +26,17 @@ public:
 
     const WebGLUniformInfo& Info() const { return mInfo; }
 
     WebGLProgram* Program() const { return mProgram; }
     GLint Location() const { return mLocation; }
     uint32_t ProgramGeneration() const { return mProgramGeneration; }
     int ElementSize() const { return mElementSize; }
 
-    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+    JSObject* WrapObject(JSContext* cx);
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLUniformLocation)
     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WebGLUniformLocation)
 
 protected:
     ~WebGLUniformLocation() { }
 
     // nsRefPtr, not WebGLRefPtr, so that we don't prevent the program from being explicitly deleted.
--- a/dom/datastore/DataStoreCursor.cpp
+++ b/dom/datastore/DataStoreCursor.cpp
@@ -24,21 +24,20 @@ NS_IMPL_CYCLE_COLLECTION(DataStoreCursor
 
 already_AddRefed<DataStoreCursor>
 DataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<DataStoreCursor> cursor = new DataStoreCursor();
   return cursor.forget();
 }
 
-bool
-DataStoreCursor::WrapObject(JSContext* aCx,
-                            JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+DataStoreCursor::WrapObject(JSContext* aCx)
 {
-  return DataStoreCursorBinding::Wrap(aCx, this, aReflector);
+  return DataStoreCursorBinding::Wrap(aCx, this);
 }
 
 already_AddRefed<DataStore>
 DataStoreCursor::GetStore(ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mCursor);
 
@@ -68,9 +67,9 @@ DataStoreCursor::SetDataStoreCursorImpl(
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mCursor);
 
   mCursor = &aCursor;
 }
 
 } //namespace dom
-} //namespace mozilla
+} //namespace mozilla
\ No newline at end of file
--- a/dom/datastore/DataStoreCursor.h
+++ b/dom/datastore/DataStoreCursor.h
@@ -28,17 +28,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(DataStoreCursor)
 
   // WebIDL (internal functions)
 
   static already_AddRefed<DataStoreCursor> Constructor(GlobalObject& aGlobal,
                                                        ErrorResult& aRv);
 
-  bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject* WrapObject(JSContext *aCx);
 
   // WebIDL (public APIs)
 
   already_AddRefed<DataStore> GetStore(ErrorResult& aRv);
 
   already_AddRefed<Promise> Next(ErrorResult& aRv);
 
   void Close(ErrorResult& aRv);
@@ -51,9 +51,9 @@ public:
 private:
   ~DataStoreCursor() {}
   nsRefPtr<DataStoreCursorImpl> mCursor;
 };
 
 } //namespace dom
 } //namespace mozilla
 
-#endif
+#endif
\ No newline at end of file
--- a/dom/encoding/TextDecoder.h
+++ b/dom/encoding/TextDecoder.h
@@ -44,19 +44,19 @@ public:
     MOZ_COUNT_CTOR(TextDecoder);
   }
 
   ~TextDecoder()
   {
     MOZ_COUNT_DTOR(TextDecoder);
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  JSObject* WrapObject(JSContext* aCx, bool* aTookOwnership)
   {
-    return TextDecoderBinding::Wrap(aCx, this, aReflector);
+    return TextDecoderBinding::Wrap(aCx, this, aTookOwnership);
   }
 
   /**
    * Validates provided label and throws an exception if invalid label.
    *
    * @param aLabel       The encoding label (case insensitive) provided.
    * @param aFatal       indicates whether to throw an 'EncodingError'
    *                     exception or not when decoding.
--- a/dom/encoding/TextEncoder.h
+++ b/dom/encoding/TextEncoder.h
@@ -37,19 +37,19 @@ public:
   TextEncoder()
   {
   }
 
   virtual
   ~TextEncoder()
   {}
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  JSObject* WrapObject(JSContext* aCx, bool* aTookOwnership)
   {
-    return TextEncoderBinding::Wrap(aCx, this, aReflector);
+    return TextEncoderBinding::Wrap(aCx, this, aTookOwnership);
   }
 
 protected:
 
   /**
    * Validates provided encoding and throws an exception if invalid encoding.
    * If no encoding is provided then mEncoding is default initialised to "utf-8".
    *
--- a/dom/html/TimeRanges.cpp
+++ b/dom/html/TimeRanges.cpp
@@ -161,16 +161,16 @@ TimeRanges::Find(double aTime, double aE
   for (index_type i = 0; i < mRanges.Length(); ++i) {
     if (aTime < mRanges[i].mEnd && (aTime + aError) >= mRanges[i].mStart) {
       return i;
     }
   }
   return NoIndex;
 }
 
-bool
-TimeRanges::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+TimeRanges::WrapObject(JSContext* aCx)
 {
-  return TimeRangesBinding::Wrap(aCx, this, aReflector);
+  return TimeRangesBinding::Wrap(aCx, this);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/TimeRanges.h
+++ b/dom/html/TimeRanges.h
@@ -45,17 +45,17 @@ public:
   void Normalize(double aError = 0.0);
 
   // Mutate this TimeRange to be the union of this and aOtherRanges.
   void Union(const TimeRanges* aOtherRanges, double aError);
 
   // Mutate this TimeRange to be the intersection of this and aOtherRanges.
   void Intersection(const TimeRanges* aOtherRanges);
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject* WrapObject(JSContext* aCx);
 
   uint32_t Length() const
   {
     return mRanges.Length();
   }
 
   virtual double Start(uint32_t aIndex, ErrorResult& aRv);
 
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -242,20 +242,20 @@ IDBKeyRange::DropJSObjects()
   mCachedLowerVal.setUndefined();
   mCachedUpperVal.setUndefined();
   mHaveCachedLowerVal = false;
   mHaveCachedUpperVal = false;
   mRooted = false;
   mozilla::DropJSObjects(this);
 }
 
-bool
-IDBKeyRange::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+IDBKeyRange::WrapObject(JSContext* aCx)
 {
-  return IDBKeyRangeBinding::Wrap(aCx, this, aReflector);
+  return IDBKeyRangeBinding::Wrap(aCx, this);
 }
 
 void
 IDBKeyRange::GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
                       ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
--- a/dom/indexedDB/IDBKeyRange.h
+++ b/dom/indexedDB/IDBKeyRange.h
@@ -135,18 +135,18 @@ public:
 
   nsresult
   BindToStatement(mozIStorageStatement* aStatement) const;
 
   void
   DropJSObjects();
 
   // WebIDL
-  bool
-  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject*
+  WrapObject(JSContext* aCx);
 
   nsISupports*
   GetParentObject() const
   {
     return mGlobal;
   }
 
   void
--- a/dom/vr/VRDevice.cpp
+++ b/dom/vr/VRDevice.cpp
@@ -12,39 +12,48 @@
 #include "gfxVR.h"
 #include "nsIFrame.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
-VRFieldOfView*
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfView, mParent)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfView, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfView, Release)
+
+already_AddRefed<VRFieldOfView>
 VRFieldOfView::Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
                            ErrorResult& aRV)
 {
-  return new VRFieldOfView(aParams.mUpDegrees, aParams.mRightDegrees,
-                           aParams.mDownDegrees, aParams.mLeftDegrees);
+  nsRefPtr<VRFieldOfView> obj =
+    new VRFieldOfView(aGlobal.GetAsSupports(),
+                      aParams.mUpDegrees, aParams.mRightDegrees,
+                      aParams.mDownDegrees, aParams.mLeftDegrees);
+  return obj.forget();
 }
 
-VRFieldOfView*
+already_AddRefed<VRFieldOfView>
 VRFieldOfView::Constructor(const GlobalObject& aGlobal,
                            double aUpDegrees, double aRightDegrees,
                            double aDownDegrees, double aLeftDegrees,
                            ErrorResult& aRV)
 {
-  return new VRFieldOfView(aUpDegrees, aRightDegrees, aDownDegrees,
-                           aLeftDegrees);
+  nsRefPtr<VRFieldOfView> obj =
+    new VRFieldOfView(aGlobal.GetAsSupports(),
+                      aUpDegrees, aRightDegrees,
+                      aDownDegrees, aLeftDegrees);
+  return obj.forget();
 }
 
-bool
-VRFieldOfView::WrapObject(JSContext* aCx,
-                          JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+VRFieldOfView::WrapObject(JSContext* aCx)
 {
-  return VRFieldOfViewBinding::Wrap(aCx, this, aReflector);
+  return VRFieldOfViewBinding::Wrap(aCx, this);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRPositionState, mParent)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRPositionState, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRPositionState, Release)
 
 VRPositionState::VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
   : mParent(aParent)
@@ -195,47 +204,49 @@ public:
   virtual already_AddRefed<DOMPoint> GetEyeTranslation(VREye aEye) MOZ_OVERRIDE
   {
     gfx::Point3D p = mHMD->GetEyeTranslation(EyeToEye(aEye));
 
     nsRefPtr<DOMPoint> obj = new DOMPoint(mParent, p.x, p.y, p.z, 0.0);
     return obj.forget();
   }
 
-  virtual VRFieldOfView* GetCurrentEyeFieldOfView(VREye aEye) MOZ_OVERRIDE
+  virtual already_AddRefed<VRFieldOfView> GetCurrentEyeFieldOfView(VREye aEye) MOZ_OVERRIDE
   {
     return CopyFieldOfView(mHMD->GetEyeFOV(EyeToEye(aEye)));
   }
 
-  virtual VRFieldOfView* GetRecommendedEyeFieldOfView(VREye aEye) MOZ_OVERRIDE
+  virtual already_AddRefed<VRFieldOfView> GetRecommendedEyeFieldOfView(VREye aEye) MOZ_OVERRIDE
   {
     return CopyFieldOfView(mHMD->GetRecommendedEyeFOV(EyeToEye(aEye)));
   }
 
-  virtual VRFieldOfView* GetMaximumEyeFieldOfView(VREye aEye) MOZ_OVERRIDE
+  virtual already_AddRefed<VRFieldOfView> GetMaximumEyeFieldOfView(VREye aEye) MOZ_OVERRIDE
   {
     return CopyFieldOfView(mHMD->GetMaximumEyeFOV(EyeToEye(aEye)));
   }
 
   virtual already_AddRefed<DOMRect> GetRecommendedEyeRenderRect(VREye aEye) MOZ_OVERRIDE
   {
     const IntSize& a(mHMD->SuggestedEyeResolution());
     nsRefPtr<DOMRect> obj =
       new DOMRect(mParent,
                   (aEye == VREye::Left) ? 0 : a.width, 0,
                   a.width, a.height);
     return obj.forget();
   }
 
 protected:
-  VRFieldOfView*
+  already_AddRefed<VRFieldOfView>
   CopyFieldOfView(const gfx::VRFieldOfView& aSrc)
   {
-    return new VRFieldOfView(aSrc.upDegrees, aSrc.rightDegrees,
-                             aSrc.downDegrees, aSrc.leftDegrees);
+    nsRefPtr<VRFieldOfView> obj =
+      new VRFieldOfView(mParent, aSrc.upDegrees, aSrc.rightDegrees,
+                        aSrc.downDegrees, aSrc.leftDegrees);
+    return obj.forget();
   }
 };
 
 class HMDPositionVRDevice : public PositionSensorVRDevice
 {
 public:
   HMDPositionVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD)
     : PositionSensorVRDevice(aParent)
--- a/dom/vr/VRDevice.h
+++ b/dom/vr/VRDevice.h
@@ -21,59 +21,68 @@
 
 #include "gfxVR.h"
 
 namespace mozilla {
 namespace dom {
 
 class Element;
 
-class VRFieldOfViewReadOnly : public NonRefcountedDOMObject
+class VRFieldOfViewReadOnly : public nsWrapperCache
 {
 public:
-  VRFieldOfViewReadOnly(double aUpDegrees, double aRightDegrees,
+  VRFieldOfViewReadOnly(nsISupports* aParent,
+                        double aUpDegrees, double aRightDegrees,
                         double aDownDegrees, double aLeftDegrees)
-    : mUpDegrees(aUpDegrees)
+    : mParent(aParent)
+    , mUpDegrees(aUpDegrees)
     , mRightDegrees(aRightDegrees)
     , mDownDegrees(aDownDegrees)
     , mLeftDegrees(aLeftDegrees)
   {
   }
 
   double UpDegrees() const { return mUpDegrees; }
   double RightDegrees() const { return mRightDegrees; }
   double DownDegrees() const { return mDownDegrees; }
   double LeftDegrees() const { return mLeftDegrees; }
 
 protected:
+  nsCOMPtr<nsISupports> mParent;
   double mUpDegrees;
   double mRightDegrees;
   double mDownDegrees;
   double mLeftDegrees;
 };
 
 class VRFieldOfView MOZ_FINAL : public VRFieldOfViewReadOnly
 {
+  ~VRFieldOfView() {}
 public:
-  explicit VRFieldOfView(double aUpDegrees = 0.0, double aRightDegrees = 0.0,
+  explicit VRFieldOfView(nsISupports* aParent,
+                         double aUpDegrees = 0.0, double aRightDegrees = 0.0,
                          double aDownDegrees = 0.0, double aLeftDegrees = 0.0)
-    : VRFieldOfViewReadOnly(aUpDegrees, aRightDegrees, aDownDegrees, aLeftDegrees)
+    : VRFieldOfViewReadOnly(aParent, aUpDegrees, aRightDegrees, aDownDegrees, aLeftDegrees)
   {}
 
-  static VRFieldOfView*
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfView)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfView)
+
+  static already_AddRefed<VRFieldOfView>
   Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
               ErrorResult& aRv);
 
-  static VRFieldOfView*
+  static already_AddRefed<VRFieldOfView>
   Constructor(const GlobalObject& aGlobal,
               double aUpDegrees, double aRightDegrees,
               double aDownDegrees, double aLeftDegrees,
               ErrorResult& aRv);
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  nsISupports* GetParentObject() const { return mParent; }
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   void SetUpDegrees(double aVal) { mUpDegrees = aVal; }
   void SetRightDegrees(double aVal) { mRightDegrees = aVal; }
   void SetDownDegrees(double aVal) { mDownDegrees = aVal; }
   void SetLeftDegrees(double aVal) { mLeftDegrees = aVal; }
 };
 
 class VRPositionState MOZ_FINAL : public nsWrapperCache
@@ -176,19 +185,19 @@ protected:
 class HMDVRDevice : public VRDevice
 {
 public:
   virtual already_AddRefed<DOMPoint> GetEyeTranslation(VREye aEye) = 0;
 
   virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
                               const VRFieldOfViewInit& aRightFOV,
                               double zNear, double zFar) = 0;
-  virtual VRFieldOfView* GetCurrentEyeFieldOfView(VREye aEye) = 0;
-  virtual VRFieldOfView* GetRecommendedEyeFieldOfView(VREye aEye) = 0;
-  virtual VRFieldOfView* GetMaximumEyeFieldOfView(VREye aEye) = 0;
+  virtual already_AddRefed<VRFieldOfView> GetCurrentEyeFieldOfView(VREye aEye) = 0;
+  virtual already_AddRefed<VRFieldOfView> GetRecommendedEyeFieldOfView(VREye aEye) = 0;
+  virtual already_AddRefed<VRFieldOfView> GetMaximumEyeFieldOfView(VREye aEye) = 0;
   virtual already_AddRefed<DOMRect> GetRecommendedEyeRenderRect(VREye aEye) = 0;
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   void XxxToggleElementVR(Element& aElement);
 
   gfx::VRHMDInfo *GetHMD() { return mHMD.get(); }
 
--- a/dom/webidl/VRDevice.webidl
+++ b/dom/webidl/VRDevice.webidl
@@ -76,25 +76,22 @@ interface VRDevice {
 
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDevice.h"]
 interface HMDVRDevice : VRDevice {
   /* The translation that should be applied to the view matrix for rendering each eye */
   DOMPoint getEyeTranslation(VREye whichEye);
 
   // the FOV that the HMD was configured with
-  [NewObject]
   VRFieldOfView getCurrentEyeFieldOfView(VREye whichEye);
 
   // the recommended FOV, per eye.
-  [NewObject]
   VRFieldOfView getRecommendedEyeFieldOfView(VREye whichEye);
 
   // the maximum FOV, per eye.  Above this, rendering will look broken.
-  [NewObject]
   VRFieldOfView getMaximumEyeFieldOfView(VREye whichEye);
 
   // Set a field of view.  If either of the fields of view is null,
   // or if their values are all zeros, then the recommended field of view
   // for that eye will be used.
   void setFieldOfView(optional VRFieldOfViewInit leftFOV,
                       optional VRFieldOfViewInit rightFOV,
                       optional double zNear = 0.01,
@@ -117,16 +114,15 @@ interface PositionSensorVRDevice : VRDev
    * Return a VRPositionState dictionary containing the state of this position sensor,
    * at an optional past time or predicted for a future time if timeOffset is != 0.
    *
    * The VRPositionState will contain the position, orientation, and velocity
    * and acceleration of each of these properties.  Use "hasPosition" and "hasOrientation"
    * to check if the associated members are valid; if these are false, those members
    * will be null.
    */
-  [NewObject]
   VRPositionState getState(optional double timeOffset = 0.0);
 
   /* Zero this sensor, treating its current position and orientation
    * as the "origin/zero" values.
    */
   void zeroSensor();
 };
--- a/dom/workers/DataStoreCursor.cpp
+++ b/dom/workers/DataStoreCursor.cpp
@@ -35,21 +35,20 @@ already_AddRefed<WorkerDataStoreCursor>
 WorkerDataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
 {
   // We don't allow Gecko to create WorkerDataStoreCursor through JS codes like
   // window.DataStoreCursor() on the worker, so disable this for now.
   NS_NOTREACHED("Cannot use the chrome constructor on the worker!");
   return nullptr;
 }
 
-bool
-WorkerDataStoreCursor::WrapObject(JSContext* aCx,
-                                  JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+WorkerDataStoreCursor::WrapObject(JSContext* aCx)
 {
-  return DataStoreCursorBinding_workers::Wrap(aCx, this, aReflector);
+  return DataStoreCursorBinding_workers::Wrap(aCx, this);
 }
 
 // A WorkerMainThreadRunnable which holds a reference to DataStoreCursor.
 class DataStoreCursorRunnable : public WorkerMainThreadRunnable
 {
 protected:
   nsMainThreadPtrHandle<DataStoreCursor> mBackingCursor;
 
--- a/dom/workers/DataStoreCursor.h
+++ b/dom/workers/DataStoreCursor.h
@@ -30,17 +30,17 @@ public:
 
   explicit WorkerDataStoreCursor(WorkerDataStore* aWorkerStore);
 
   // WebIDL (internal functions)
 
   static already_AddRefed<WorkerDataStoreCursor> Constructor(GlobalObject& aGlobal,
                                                              ErrorResult& aRv);
 
-  bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject* WrapObject(JSContext *aCx);
 
   // WebIDL (public APIs)
 
   already_AddRefed<WorkerDataStore> GetStore(JSContext *aCx, ErrorResult& aRv);
 
   already_AddRefed<Promise> Next(JSContext *aCx, ErrorResult& aRv);
 
   void Close(JSContext *aCx, ErrorResult& aRv);
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -36,21 +36,20 @@ using mozilla::dom::GlobalObject;
 already_AddRefed<FileReaderSync>
 FileReaderSync::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<FileReaderSync> frs = new FileReaderSync();
 
   return frs.forget();
 }
 
-bool
-FileReaderSync::WrapObject(JSContext* aCx,
-                           JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+FileReaderSync::WrapObject(JSContext* aCx)
 {
-  return FileReaderSyncBinding_workers::Wrap(aCx, this, aReflector);
+  return FileReaderSyncBinding_workers::Wrap(aCx, this);
 }
 
 void
 FileReaderSync::ReadAsArrayBuffer(JSContext* aCx,
                                   JS::Handle<JSObject*> aScopeObj,
                                   File& aBlob,
                                   JS::MutableHandle<JSObject*> aRetval,
                                   ErrorResult& aRv)
--- a/dom/workers/FileReaderSync.h
+++ b/dom/workers/FileReaderSync.h
@@ -36,17 +36,17 @@ private:
 
   nsresult ConvertStream(nsIInputStream *aStream, const char *aCharset,
                          nsAString &aResult);
 
 public:
   static already_AddRefed<FileReaderSync>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject* WrapObject(JSContext* aCx);
 
   void ReadAsArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aScopeObj,
                          File& aBlob, JS::MutableHandle<JSObject*> aRetval,
                          ErrorResult& aRv);
   void ReadAsBinaryString(File& aBlob, nsAString& aResult, ErrorResult& aRv);
   void ReadAsText(File& aBlob, const Optional<nsAString>& aEncoding,
                   nsAString& aResult, ErrorResult& aRv);
   void ReadAsDataURL(File& aBlob, nsAString& aResult, ErrorResult& aRv);
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -567,20 +567,20 @@ URL::~URL()
     mURLProxy = nullptr;
 
     if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
       NS_ERROR("Failed to dispatch teardown runnable!");
     }
   }
 }
 
-bool
-URL::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+URL::WrapObject(JSContext* aCx)
 {
-  return URLBinding_workers::Wrap(aCx, this, aReflector);
+  return URLBinding_workers::Wrap(aCx, this);
 }
 
 void
 URL::GetHref(nsString& aHref, ErrorResult& aRv) const
 {
   nsRefPtr<GetterRunnable> runnable =
     new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
                        mURLProxy);
--- a/dom/workers/URL.h
+++ b/dom/workers/URL.h
@@ -40,18 +40,18 @@ public:
 
   nsISupports*
   GetParentObject() const
   {
     // There's only one global on a worker, so we don't need to specify.
     return nullptr;
   }
 
-  bool
-  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  JSObject*
+  WrapObject(JSContext* aCx);
 
   // Methods for WebIDL
 
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               URL& aBase, ErrorResult& aRv);
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -6248,20 +6248,18 @@ WorkerPrivate::CreateGlobalScope(JSConte
   if (IsSharedWorker()) {
     globalScope = new SharedWorkerGlobalScope(this, SharedWorkerName());
   } else if (IsServiceWorker()) {
     globalScope = new ServiceWorkerGlobalScope(this, SharedWorkerName());
   } else {
     globalScope = new DedicatedWorkerGlobalScope(this);
   }
 
-  JS::Rooted<JSObject*> global(aCx);
-  if (!globalScope->WrapGlobalObject(aCx, &global)) {
-    return nullptr;
-  }
+  JS::Rooted<JSObject*> global(aCx, globalScope->WrapGlobalObject(aCx));
+  NS_ENSURE_TRUE(global, nullptr);
 
   JSAutoCompartment ac(aCx, global);
 
   if (!RegisterBindings(aCx, global)) {
     return nullptr;
   }
 
   mScope = globalScope.forget();
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -357,30 +357,29 @@ WorkerGlobalScope::GetIndexedDB(ErrorRes
   return indexedDB.forget();
 }
 
 DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
 : WorkerGlobalScope(aWorkerPrivate)
 {
 }
 
-bool
-DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
-                                             JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
   return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
                                                          options,
                                                          GetWorkerPrincipal(),
-                                                         true, aReflector);
+                                                         true);
 }
 
 void
 DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
                                         JS::Handle<JS::Value> aMessage,
                                         const Optional<Sequence<JS::Value>>& aTransferable,
                                         ErrorResult& aRv)
 {
@@ -389,29 +388,28 @@ DedicatedWorkerGlobalScope::PostMessage(
 }
 
 SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
                                                  const nsCString& aName)
 : WorkerGlobalScope(aWorkerPrivate), mName(aName)
 {
 }
 
-bool
-SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
-                                          JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
   return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
                                                       GetWorkerPrincipal(),
-                                                      true, aReflector);
+                                                      true);
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope,
                                    mClients)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope)
 NS_INTERFACE_MAP_END_INHERITING(WorkerGlobalScope)
 
 NS_IMPL_ADDREF_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope)
@@ -423,29 +421,28 @@ ServiceWorkerGlobalScope::ServiceWorkerG
     mScope(NS_ConvertUTF8toUTF16(aScope))
 {
 }
 
 ServiceWorkerGlobalScope::~ServiceWorkerGlobalScope()
 {
 }
 
-bool
-ServiceWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
-                                           JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+ServiceWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
   return ServiceWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
                                                        GetWorkerPrincipal(),
-                                                       true, aReflector);
+                                                       true);
 }
 
 ServiceWorkerClients*
 ServiceWorkerGlobalScope::Clients()
 {
   if (!mClients) {
     mClients = new ServiceWorkerClients(this);
   }
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -52,18 +52,18 @@ protected:
 
   explicit WorkerGlobalScope(WorkerPrivate* aWorkerPrivate);
   virtual ~WorkerGlobalScope();
 
 public:
   virtual JSObject*
   WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
-  virtual bool
-  WrapGlobalObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) = 0;
+  virtual JSObject*
+  WrapGlobalObject(JSContext* aCx) = 0;
 
   virtual JSObject*
   GetGlobalJSObject(void) MOZ_OVERRIDE
   {
     return GetWrapper();
   }
 
   NS_DECL_ISUPPORTS_INHERITED
@@ -143,19 +143,18 @@ public:
 
 class DedicatedWorkerGlobalScope MOZ_FINAL : public WorkerGlobalScope
 {
   ~DedicatedWorkerGlobalScope() { }
 
 public:
   explicit DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate);
 
-  virtual bool
-  WrapGlobalObject(JSContext* aCx,
-                   JS::MutableHandle<JSObject*> aReflector) MOZ_OVERRIDE;
+  virtual JSObject*
+  WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
 
   void
   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
               const Optional<Sequence<JS::Value>>& aTransferable,
               ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(message)
 };
@@ -165,19 +164,18 @@ class SharedWorkerGlobalScope MOZ_FINAL 
   const nsCString mName;
 
   ~SharedWorkerGlobalScope() { }
 
 public:
   SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
                           const nsCString& aName);
 
-  virtual bool
-  WrapGlobalObject(JSContext* aCx,
-                   JS::MutableHandle<JSObject*> aReflector) MOZ_OVERRIDE;
+  virtual JSObject*
+  WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
 
   void GetName(DOMString& aName) const
   {
     aName.AsAString() = NS_ConvertUTF8toUTF16(mName);
   }
 
   IMPL_EVENT_HANDLER(connect)
 };
@@ -191,19 +189,18 @@ class ServiceWorkerGlobalScope MOZ_FINAL
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
                                            WorkerGlobalScope)
 
   ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsACString& aScope);
 
-  virtual bool
-  WrapGlobalObject(JSContext* aCx,
-                   JS::MutableHandle<JSObject*> aReflector) MOZ_OVERRIDE;
+  virtual JSObject*
+  WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
 
   void
   GetScope(DOMString& aScope) const
   {
     aScope.AsAString() = mScope;
   }
 
   void
--- a/dom/xslt/xpath/XPathEvaluator.cpp
+++ b/dom/xslt/xpath/XPathEvaluator.cpp
@@ -153,21 +153,20 @@ XPathEvaluator::CreateExpression(const n
         }
 
         return nullptr;
     }
 
     return new XPathExpression(Move(expression), mRecycler, aDocument);
 }
 
-bool
-XPathEvaluator::WrapObject(JSContext* aCx,
-                           JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+XPathEvaluator::WrapObject(JSContext* aCx)
 {
-    return dom::XPathEvaluatorBinding::Wrap(aCx, this, aReflector);
+    return dom::XPathEvaluatorBinding::Wrap(aCx, this);
 }
 
 /* static */
 already_AddRefed<XPathEvaluator>
 XPathEvaluator::Constructor(const GlobalObject& aGlobal,
                             ErrorResult& rv)
 {
     nsRefPtr<XPathEvaluator> newObj = new XPathEvaluator(nullptr);
--- a/dom/xslt/xpath/XPathEvaluator.h
+++ b/dom/xslt/xpath/XPathEvaluator.h
@@ -37,17 +37,17 @@ public:
     explicit XPathEvaluator(nsIDocument* aDocument = nullptr);
 
     NS_DECL_ISUPPORTS
 
     // nsIDOMXPathEvaluator interface
     NS_DECL_NSIDOMXPATHEVALUATOR
 
     // WebIDL API
-    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+    JSObject* WrapObject(JSContext* aCx);
     nsIDocument* GetParentObject()
     {
         nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
         return doc;
     }
     static already_AddRefed<XPathEvaluator>
         Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
     XPathExpression*
--- a/dom/xslt/xpath/XPathExpression.h
+++ b/dom/xslt/xpath/XPathExpression.h
@@ -29,19 +29,19 @@ class XPathResult;
  */
 class XPathExpression MOZ_FINAL : public NonRefcountedDOMObject
 {
 public:
     XPathExpression(nsAutoPtr<Expr>&& aExpression, txResultRecycler* aRecycler,
                     nsIDocument *aDocument);
     ~XPathExpression();
 
-    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+    JSObject* WrapObject(JSContext* aCx, bool* aTookOwnership)
     {
-        return XPathExpressionBinding::Wrap(aCx, this, aReflector);
+        return XPathExpressionBinding::Wrap(aCx, this, aTookOwnership);
     }
 
     already_AddRefed<XPathResult>
         Evaluate(JSContext* aCx, nsINode& aContextNode, uint16_t aType,
                  JS::Handle<JSObject*> aInResult, ErrorResult& aRv)
     {
         return EvaluateWithContext(aCx, aContextNode, 1, 1, aType, aInResult,
                                    aRv);
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -76,17 +76,17 @@ IdToObjectMap::remove(ObjectId id)
 ObjectToIdMap::ObjectToIdMap()
   : table_(nullptr)
 {
 }
 
 ObjectToIdMap::~ObjectToIdMap()
 {
     if (table_) {
-        dom::AddForDeferredFinalization<Table>(table_);
+        dom::AddForDeferredFinalization<Table, nsAutoPtr>(table_);
         table_ = nullptr;
     }
 }
 
 bool
 ObjectToIdMap::init()
 {
     if (table_)
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -284,21 +284,20 @@ RTCStatsQuery::~RTCStatsQuery() {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 #endif
 
 NS_IMPL_ISUPPORTS0(PeerConnectionImpl)
 
 #ifdef MOZILLA_INTERNAL_API
-bool
-PeerConnectionImpl::WrapObject(JSContext* aCx,
-                               JS::MutableHandle<JSObject*> aReflector)
+JSObject*
+PeerConnectionImpl::WrapObject(JSContext* aCx)
 {
-  return PeerConnectionImplBinding::Wrap(aCx, this, aReflector);
+  return PeerConnectionImplBinding::Wrap(aCx, this);
 }
 #endif
 
 bool PCUuidGenerator::Generate(std::string* idp) {
   nsresult rv;
 
   if(!mGenerator) {
     mGenerator = do_GetService("@mozilla.org/uuid-generator;1", &rv);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -246,17 +246,17 @@ public:
     kIncompatibleSessionDescription   = 6,
     kIncompatibleMediaStreamTrack     = 8,
     kInternalError                    = 9
   };
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
 #ifdef MOZILLA_INTERNAL_API
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  virtual JSObject* WrapObject(JSContext* cx);
 #endif
 
   static already_AddRefed<PeerConnectionImpl>
       Constructor(const mozilla::dom::GlobalObject& aGlobal, ErrorResult& rv);
   static PeerConnectionImpl* CreatePeerConnection();
   static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc,
                                           IceConfiguration *aDst);
   already_AddRefed<DOMMediaStream> MakeMediaStream(uint32_t aHint);