Bug 1189822 part 3. Stop using EnsureExpandoObject in codegen code when we just want to preserver the wrapper for a DOM proxy. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 17 May 2017 00:52:53 -0400
changeset 358626 5ccd27cf7166db5cdee297abcc8b5fd0ed4d81c6
parent 358625 d820067e4d5f330adef3711126e93c0869ec9c65
child 358627 793ab87511f5f4a77388cb5f7293251e9955afd9
push id90361
push userbzbarsky@mozilla.com
push dateWed, 17 May 2017 04:54:18 +0000
treeherdermozilla-inbound@159f82e6813c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1189822
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1189822 part 3. Stop using EnsureExpandoObject in codegen code when we just want to preserver the wrapper for a DOM proxy. r=peterv
dom/base/nsContentList.h
dom/bindings/Codegen.py
dom/html/HTMLFormControlsCollection.h
dom/html/HTMLOptionsCollection.h
dom/html/HTMLTableElement.cpp
dom/html/nsIHTMLCollection.h
--- a/dom/base/nsContentList.h
+++ b/dom/base/nsContentList.h
@@ -256,24 +256,29 @@ public:
                 void* aData,
                 bool aDeep = true,
                 nsIAtom* aMatchAtom = nullptr,
                 int32_t aMatchNameSpaceId = kNameSpaceID_None,
                 bool aFuncMayDependOnAttr = true);
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
+  using nsWrapperCache::PreserveWrapper;
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 protected:
   virtual ~nsContentList();
 
   virtual JSObject* GetWrapperPreserveColorInternal() override
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
+  virtual void PreserveWrapperInternal(nsISupports* aScriptObjectHolder) override
+  {
+    nsWrapperCache::PreserveWrapper(aScriptObjectHolder);
+  }
 public:
 
   // nsIDOMHTMLCollection
   NS_DECL_NSIDOMHTMLCOLLECTION
 
   // nsBaseContentList overrides
   virtual int32_t IndexOf(nsIContent *aContent, bool aDoFlush) override;
   virtual int32_t IndexOf(nsIContent* aContent) override;
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3733,27 +3733,16 @@ class CGWrapWithCacheMethod(CGAbstractMe
                 Argument(descriptor.nativeType + '*', 'aObject'),
                 Argument('nsWrapperCache*', 'aCache'),
                 Argument('JS::Handle<JSObject*>', 'aGivenProto'),
                 Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.properties = properties
 
     def definition_body(self):
-        if self.descriptor.proxy:
-            preserveWrapper = dedent(
-                """
-                // For DOM proxies, the only reliable way to preserve the wrapper
-                // is to force creation of the expando object.
-                JS::Rooted<JSObject*> unused(aCx,
-                  DOMProxyHandler::EnsureExpandoObject(aCx, aReflector));
-                """)
-        else:
-            preserveWrapper = "PreserveWrapper(aObject);\n"
-
         failureCode = dedent(
             """
             aCache->ReleaseWrapper(aObject);
             aCache->ClearWrapper();
             return false;
             """)
 
         return fill(
@@ -3799,30 +3788,29 @@ class CGWrapWithCacheMethod(CGAbstractMe
                        aCache->GetWrapperPreserveColor() == aReflector);
             // If proto != canonicalProto, we have to preserve our wrapper;
             // otherwise we won't be able to properly recreate it later, since
             // we won't know what proto to use.  Note that we don't check
             // aGivenProto here, since it's entirely possible (and even
             // somewhat common) to have a non-null aGivenProto which is the
             // same as canonicalProto.
             if (proto != canonicalProto) {
-              $*{preserveWrapper}
+              PreserveWrapper(aObject);
             }
 
             return true;
             """,
             assertInheritance=AssertInheritanceChain(self.descriptor),
             declareProto=DeclareProto(),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor,
                                                             failureCode),
             slots=InitMemberSlots(self.descriptor, failureCode),
             setImmutablePrototype=SetImmutablePrototype(self.descriptor,
-                                                        failureCode),
-            preserveWrapper=preserveWrapper)
+                                                        failureCode))
 
 
 class CGWrapMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument('T*', 'aObject'),
--- a/dom/html/HTMLFormControlsCollection.h
+++ b/dom/html/HTMLFormControlsCollection.h
@@ -74,23 +74,28 @@ public:
    *
    * @param aControls The list of sorted controls[out].
    * @return NS_OK or NS_ERROR_OUT_OF_MEMORY.
    */
   nsresult GetSortedControls(nsTArray<nsGenericHTMLFormElement*>& aControls) const;
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
+  using nsWrapperCache::PreserveWrapper;
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 protected:
   virtual ~HTMLFormControlsCollection();
   virtual JSObject* GetWrapperPreserveColorInternal() override
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
+  virtual void PreserveWrapperInternal(nsISupports* aScriptObjectHolder) override
+  {
+    nsWrapperCache::PreserveWrapper(aScriptObjectHolder);
+  }
 public:
 
   static bool ShouldBeInElements(nsIFormControl* aFormControl);
 
   HTMLFormElement* mForm;  // WEAK - the form owns me
 
   nsTArray<nsGenericHTMLFormElement*> mElements;  // Holds WEAK references - bug 36639
 
--- a/dom/html/HTMLOptionsCollection.h
+++ b/dom/html/HTMLOptionsCollection.h
@@ -39,24 +39,29 @@ class HTMLOptionsCollection final : publ
 public:
   explicit HTMLOptionsCollection(HTMLSelectElement* aSelect);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
   using nsWrapperCache::GetWrapper;
+  using nsWrapperCache::PreserveWrapper;
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 protected:
   virtual ~HTMLOptionsCollection();
 
   virtual JSObject* GetWrapperPreserveColorInternal() override
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
+  virtual void PreserveWrapperInternal(nsISupports* aScriptObjectHolder) override
+  {
+    nsWrapperCache::PreserveWrapper(aScriptObjectHolder);
+  }
 public:
 
   // nsIDOMHTMLOptionsCollection interface
   NS_DECL_NSIDOMHTMLOPTIONSCOLLECTION
 
   // nsIDOMHTMLCollection interface, all its methods are defined in
   // nsIDOMHTMLOptionsCollection
 
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -44,24 +44,29 @@ public:
   virtual void GetSupportedNames(nsTArray<nsString>& aNames) override;
 
   NS_IMETHOD    ParentDestroyed();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TableRowsCollection)
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
+  using nsWrapperCache::PreserveWrapper;
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 protected:
   virtual ~TableRowsCollection();
 
   virtual JSObject* GetWrapperPreserveColorInternal() override
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
+  virtual void PreserveWrapperInternal(nsISupports* aScriptObjectHolder) override
+  {
+    nsWrapperCache::PreserveWrapper(aScriptObjectHolder);
+  }
 
   // Those rows that are not in table sections
   HTMLTableElement* mParent;
 };
 
 
 TableRowsCollection::TableRowsCollection(HTMLTableElement *aParent)
   : mParent(aParent)
--- a/dom/html/nsIHTMLCollection.h
+++ b/dom/html/nsIHTMLCollection.h
@@ -81,16 +81,23 @@ public:
   JSObject* GetWrapper()
   {
     JSObject* obj = GetWrapperPreserveColor();
     if (obj) {
       JS::ExposeObjectToActiveJS(obj);
     }
     return obj;
   }
+  void PreserveWrapper(nsISupports* aScriptObjectHolder)
+  {
+    PreserveWrapperInternal(aScriptObjectHolder);
+  }
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) = 0;
 protected:
+  // Hook for calling nsWrapperCache::GetWrapperPreserveColor.
   virtual JSObject* GetWrapperPreserveColorInternal() = 0;
+  // Hook for calling nsWrapperCache::PreserveWrapper.
+  virtual void PreserveWrapperInternal(nsISupports* aScriptObjectHolder) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLCollection, NS_IHTMLCOLLECTION_IID)
 
 #endif /* nsIHTMLCollection_h___ */