Bug 821850 - Store a strong ref to the JSClass in nsXBLBinding. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Fri, 08 Feb 2013 14:24:20 +0000
changeset 131188 a1ddf64db133ef81006afb800287f4294d16dbc8
parent 131187 c092442efc7b13b8453c070fc7afdf2cb7e3d5d2
child 131189 583ed5f34e84e39530b6297e50765bb54a576204
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs821850
milestone21.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 821850 - Store a strong ref to the JSClass in nsXBLBinding. r=bz
content/xbl/src/nsXBLBinding.h
content/xbl/src/nsXBLProtoImpl.cpp
content/xbl/src/nsXBLService.h
--- a/content/xbl/src/nsXBLBinding.h
+++ b/content/xbl/src/nsXBLBinding.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXBLBinding_h_
 #define nsXBLBinding_h_
 
+#include "nsXBLService.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsINodeList.h"
 #include "nsIStyleRuleProcessor.h"
 #include "nsClassHashtable.h"
 #include "nsTArray.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsImpl.h"
@@ -53,16 +54,21 @@ public:
   nsIContent* GetAnonymousContent() { return mContent.get(); }
 
   nsXBLBinding* GetBaseBinding() { return mNextBinding; }
   void SetBaseBinding(nsXBLBinding *aBinding);
 
   nsIContent* GetBoundElement() { return mBoundElement; }
   void SetBoundElement(nsIContent *aElement);
 
+  void SetJSClass(nsXBLJSClass *aClass) {
+    MOZ_ASSERT(!mJSClass && aClass);
+    mJSClass = aClass;
+  }
+
   bool IsStyleBinding() const { return mIsStyleBinding; }
   void SetIsStyleBinding(bool aIsStyle) { mIsStyleBinding = aIsStyle; }
 
   void MarkForDeath();
   bool MarkedForDeath() const { return mMarkedForDeath; }
 
   bool HasStyleSheets() const;
   bool InheritsStyle() const;
@@ -125,16 +131,19 @@ public:
 protected:
 
   bool mIsStyleBinding;
   bool mMarkedForDeath;
 
   nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
   nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
   nsRefPtr<nsXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
+  nsRefPtr<nsXBLJSClass> mJSClass; // Strong. The class object also holds a strong reference,
+                                   // which might be somewhat redundant, but be safe to avoid
+                                   // worrying about edge cases.
   
   nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
   
   // A hash from nsIContent* -> (a sorted array of nsXBLInsertionPoint)
   nsClassHashtable<nsISupportsHashKey, nsInsertionPointList>* mInsertionPointTable;
 };
 
 #endif // nsXBLBinding_h_
--- a/content/xbl/src/nsXBLProtoImpl.cpp
+++ b/content/xbl/src/nsXBLProtoImpl.cpp
@@ -71,16 +71,19 @@ nsXBLProtoImpl::InstallImplementation(ns
   bool targetObjectIsNew = false;
   nsresult rv = InitTargetObjects(aPrototypeBinding, context,
                                   aBinding->GetBoundElement(),
                                   getter_AddRefs(holder), &targetClassObject,
                                   &targetObjectIsNew);
   NS_ENSURE_SUCCESS(rv, rv); // kick out if we were unable to properly intialize our target objects
   MOZ_ASSERT(targetClassObject);
 
+  // Stash a strong reference to the JSClass in the binding.
+  aBinding->SetJSClass(static_cast<nsXBLJSClass*>(JS_GetClass(targetClassObject)));
+
   // If the prototype already existed, we don't need to install anything. return early.
   if (!targetObjectIsNew)
     return NS_OK;
 
   JSObject * targetScriptObject;
   holder->GetJSObject(&targetScriptObject);
 
   JSContext *cx = context->GetNativeContext();
--- a/content/xbl/src/nsXBLService.h
+++ b/content/xbl/src/nsXBLService.h
@@ -144,11 +144,13 @@ public:
 
   static uint64_t NewId() { return ++sIdCount; }
 
   nsCString& Key() { return mKey; }
   void SetKey(const nsCString& aKey) { mKey = aKey; }
 
   nsrefcnt Hold() { return ++mRefCnt; }
   nsrefcnt Drop() { return --mRefCnt ? mRefCnt : Destroy(); }
+  nsrefcnt AddRef() { return Hold(); }
+  nsrefcnt Release() { return Drop(); }
 };
 
 #endif