Bug 910823 - Factor out the code for casting from a JSClass* to an nsXBLJSClass* into a helper function. r=waldo
authorDan Gohman <sunfish@google.com>
Wed, 11 Sep 2013 05:49:04 -0700
changeset 159461 fed748b27845500f2fcf35d8b0fcde767b53d843
parent 159460 42a4dec61095504a0287a80741e6a5dfb83e5b9a
child 159462 03174045ef8d72ab2a0486e656c988bb3644951d
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs910823
milestone26.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 910823 - Factor out the code for casting from a JSClass* to an nsXBLJSClass* into a helper function. r=waldo
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLProtoImpl.cpp
content/xbl/src/nsXBLService.h
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -71,17 +71,17 @@ using namespace mozilla::dom;
 //
 static void
 XBLFinalize(JSFreeOp *fop, JSObject *obj)
 {
   nsXBLDocumentInfo* docInfo =
     static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(obj));
   nsContentUtils::DeferredFinalize(docInfo);
   
-  nsXBLJSClass* c = static_cast<nsXBLJSClass*>(::JS_GetClass(obj));
+  nsXBLJSClass* c = nsXBLJSClass::fromJSClass(::JS_GetClass(obj));
   c->Drop();
 }
 
 static bool
 XBLEnumerate(JSContext *cx, JS::Handle<JSObject*> obj)
 {
   nsXBLPrototypeBinding* protoBinding =
     static_cast<nsXBLPrototypeBinding*>(::JS_GetReservedSlot(obj, 0).toPrivate());
@@ -133,16 +133,29 @@ nsXBLJSClass::Destroy()
     // Put this most-recently-used class on end of the LRU-sorted freelist.
     nsXBLService::gClassLRUList->insertBack(this);
     nsXBLService::gClassLRUListLength++;
   }
 
   return 0;
 }
 
+nsXBLJSClass*
+nsXBLService::getClass(const nsCString& k)
+{
+  nsCStringKey key(k);
+  return getClass(&key);
+}
+
+nsXBLJSClass*
+nsXBLService::getClass(nsCStringKey *k)
+{
+  return static_cast<nsXBLJSClass*>(nsXBLService::gClassTable->Get(k));
+}
+
 // Implementation /////////////////////////////////////////////////////////////////
 
 // Constructors/Destructors
 nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
   : mMarkedForDeath(false),
     mPrototypeBinding(aBinding)
 {
   NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
@@ -921,19 +934,18 @@ nsXBLBinding::DoInitJSClass(JSContext *c
       char buf[20];
       if (sizeof(jsid) == 4) {
         PR_snprintf(buf, sizeof(buf), " %lx", parent_proto_id.get());
       } else {
         MOZ_ASSERT(sizeof(jsid) == 8);
         PR_snprintf(buf, sizeof(buf), " %llx", parent_proto_id.get());
       }
       xblKey.Append(buf);
-      nsCStringKey key(xblKey);
 
-      c = static_cast<nsXBLJSClass*>(nsXBLService::gClassTable->Get(&key));
+      c = nsXBLService::getClass(xblKey);
       if (c) {
         className.Assign(c->name);
       } else {
         char buf[20];
         PR_snprintf(buf, sizeof(buf), " %llx", nsXBLJSClass::NewId());
         className.Append(buf);
       }
     }
@@ -949,17 +961,17 @@ nsXBLBinding::DoInitJSClass(JSContext *c
     *aNew = false;
     proto = &val.toObject();
   } else {
     // We need to initialize the class.
     *aNew = true;
 
     nsCStringKey key(xblKey);
     if (!c) {
-      c = static_cast<nsXBLJSClass*>(nsXBLService::gClassTable->Get(&key));
+      c = nsXBLService::getClass(&key);
     }
     if (c) {
       // If c is on the LRU list, remove it now!
       if (c->isInList()) {
         c->remove();
         nsXBLService::gClassLRUListLength--;
       }
     } else {
--- a/content/xbl/src/nsXBLProtoImpl.cpp
+++ b/content/xbl/src/nsXBLProtoImpl.cpp
@@ -56,17 +56,17 @@ nsXBLProtoImpl::InstallImplementation(ns
   nsresult rv = InitTargetObjects(aPrototypeBinding,
                                   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)));
+  aBinding->SetJSClass(nsXBLJSClass::fromJSClass(JS_GetClass(targetClassObject)));
 
   // If the prototype already existed, we don't need to install anything. return early.
   if (!targetObjectIsNew)
     return NS_OK;
 
   JS::Rooted<JSObject*> targetScriptObject(cx, holder->GetJSObject());
 
   JSAutoCompartment ac(cx, targetClassObject);
--- a/content/xbl/src/nsXBLService.h
+++ b/content/xbl/src/nsXBLService.h
@@ -10,16 +10,17 @@
 
 #include "mozilla/LinkedList.h"
 #include "nsString.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "js/Class.h"           // nsXBLJSClass derives from JSClass
 #include "nsTArray.h"
 
+class nsCStringKey;
 class nsXBLBinding;
 class nsXBLDocumentInfo;
 class nsXBLJSClass;
 class nsIContent;
 class nsIDocument;
 class nsString;
 class nsIURI;
 class nsIPrincipal;
@@ -127,16 +128,20 @@ public:
 
   static mozilla::LinkedList<nsXBLJSClass>* gClassLRUList;
                                              // LRU list of cached classes.
   static uint32_t gClassLRUListLength;       // Number of classes on LRU list.
   static uint32_t gClassLRUListQuota;        // Quota on class LRU list.
   static bool     gAllowDataURIs;            // Whether we should allow data
                                              // urls in -moz-binding. Needed for
                                              // testing.
+
+  // Look up the class by key in gClassTable.
+  static nsXBLJSClass *getClass(const nsCString &key);
+  static nsXBLJSClass *getClass(nsCStringKey *key);
 };
 
 class nsXBLJSClass : public mozilla::LinkedListElement<nsXBLJSClass>
                    , public JSClass
 {
 private:
   nsrefcnt mRefCnt;
   nsCString mKey;
@@ -151,11 +156,20 @@ public:
 
   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(); }
+
+  // Downcast from a pointer to JSClass to a pointer to nsXBLJSClass.
+  static nsXBLJSClass*
+  fromJSClass(JSClass* c)
+  {
+    nsXBLJSClass* x = static_cast<nsXBLJSClass*>(c);
+    MOZ_ASSERT(nsXBLService::getClass(x->mKey) == x);
+    return x;
+  }
 };
 
 #endif