Bug 1011660 - Remove separate DOMClass struct. (r=bz)
authorEric Faust <efaustbmo@gmail.com>
Wed, 18 Jun 2014 13:19:19 -0700
changeset 210263 f6b74b7b4995a64102f8fb6b4c9f51f9384a986b
parent 210262 ed9d62bef0df94f75f27a8d98fb4089b2f188cd4
child 210264 d00494b1dd572f49a9b9636d44ed0ac5c56c9d83
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1011660
milestone33.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 1011660 - Remove separate DOMClass struct. (r=bz)
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/bindings/DOMJSClass.h
dom/bindings/DOMJSProxyHandler.h
dom/xbl/nsXBLProtoImplField.cpp
js/xpconnect/src/XPCQuickStubs.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -763,27 +763,27 @@ TryPreserveWrapper(JSObject* obj)
       cache->PreserveWrapper(native);
     }
     return true;
   }
 
   // If this DOMClass is not cycle collected, then it isn't wrappercached,
   // so it does not need to be preserved. If it is cycle collected, then
   // we can't tell if it is wrappercached or not, so we just return false.
-  const DOMClass* domClass = GetDOMClass(obj);
+  const DOMJSClass* domClass = GetDOMClass(obj);
   return domClass && !domClass->mParticipant;
 }
 
 // Can only be called with a DOM JSClass.
 bool
 InstanceClassHasProtoAtDepth(const js::Class* clasp,
                              uint32_t protoID, uint32_t depth)
 {
-  const DOMClass& domClass = DOMJSClass::FromJSClass(clasp)->mClass;
-  return static_cast<uint32_t>(domClass.mInterfaceChain[depth]) == protoID;
+  const DOMJSClass* domClass = DOMJSClass::FromJSClass(clasp);
+  return static_cast<uint32_t>(domClass->mInterfaceChain[depth]) == protoID;
 }
 
 // Only set allowNativeWrapper to false if you really know you need it, if in
 // doubt use true. Setting it to false disables security wrappers.
 bool
 XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
                    xpcObjectHelper& helper, const nsIID* iid,
                    bool allowNativeWrapper, JS::MutableHandle<JS::Value> rval)
@@ -913,17 +913,17 @@ ThrowConstructorWithoutNew(JSContext* cx
 {
   return ThrowErrorMessage(cx, MSG_CONSTRUCTOR_WITHOUT_NEW, name);
 }
 
 inline const NativePropertyHooks*
 GetNativePropertyHooks(JSContext *cx, JS::Handle<JSObject*> obj,
                        DOMObjectType& type)
 {
-  const DOMClass* domClass = GetDOMClass(obj);
+  const DOMJSClass* domClass = GetDOMClass(obj);
   if (domClass) {
     type = eInstance;
     return domClass->mNativeHooks;
   }
 
   if (JS_ObjectIsFunction(cx, obj)) {
     MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
     type = eInterface;
@@ -1681,17 +1681,17 @@ ReparentWrapper(JSContext* aCx, JS::Hand
 {
   js::AssertSameCompartment(aCx, aObjArg);
 
   // Check if we're near the stack limit before we get anywhere near the
   // transplanting code.
   JS_CHECK_RECURSION(aCx, return NS_ERROR_FAILURE);
 
   JS::Rooted<JSObject*> aObj(aCx, aObjArg);
-  const DOMClass* domClass = GetDOMClass(aObj);
+  const DOMJSClass* domClass = GetDOMClass(aObj);
 
   JS::Rooted<JSObject*> oldParent(aCx, JS_GetParent(aObj));
   JS::Rooted<JSObject*> newParent(aCx, domClass->mGetParent(aCx, aObj));
 
   JSAutoCompartment oldAc(aCx, oldParent);
 
   JSCompartment* oldCompartment = js::GetObjectCompartment(oldParent);
   JSCompartment* newCompartment = js::GetObjectCompartment(newParent);
@@ -1884,17 +1884,17 @@ GlobalObject::GetAsSupports() const
 bool
 InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj,
                      JS::Handle<JSObject*> instance,
                      bool* bp)
 {
   const DOMIfaceAndProtoJSClass* clasp =
     DOMIfaceAndProtoJSClass::FromJSClass(js::GetObjectClass(obj));
 
-  const DOMClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance, /* stopAtOuter = */ false));
+  const DOMJSClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance, /* stopAtOuter = */ false));
 
   MOZ_ASSERT(!domClass || clasp->mPrototypeID != prototypes::id::_ID_Count,
              "Why do we have a hasInstance hook if we don't have a prototype "
              "ID?");
 
   if (domClass &&
       domClass->mInterfaceChain[clasp->mDepth] == clasp->mPrototypeID) {
     *bp = true;
@@ -1953,17 +1953,17 @@ InterfaceHasInstance(JSContext* cx, JS::
   return InterfaceHasInstance(cx, obj, instanceObject, bp);
 }
 
 bool
 InterfaceHasInstance(JSContext* cx, int prototypeID, int depth,
                      JS::Handle<JSObject*> instance,
                      bool* bp)
 {
-  const DOMClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance));
+  const DOMJSClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance));
 
   MOZ_ASSERT(!domClass || prototypeID != prototypes::id::_ID_Count,
              "Why do we have a hasInstance hook if we don't have a prototype "
              "ID?");
 
   *bp = (domClass && domClass->mInterfaceChain[depth] == prototypeID);
   return true;
 }
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -174,34 +174,34 @@ UnwrapDOMObject(JSObject* obj)
 {
   MOZ_ASSERT(IsDOMClass(js::GetObjectClass(obj)),
              "Don't pass non-DOM objects to this function");
 
   JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
   return static_cast<T*>(val.toPrivate());
 }
 
-inline const DOMClass*
+inline const DOMJSClass*
 GetDOMClass(JSObject* obj)
 {
   const js::Class* clasp = js::GetObjectClass(obj);
   if (IsDOMClass(clasp)) {
-    return &DOMJSClass::FromJSClass(clasp)->mClass;
+    return DOMJSClass::FromJSClass(clasp);
   }
   return nullptr;
 }
 
 inline nsISupports*
 UnwrapDOMObjectToISupports(JSObject* aObject)
 {
-  const DOMClass* clasp = GetDOMClass(aObject);
+  const DOMJSClass* clasp = GetDOMClass(aObject);
   if (!clasp || !clasp->mDOMObjectIsISupports) {
     return nullptr;
   }
- 
+
   return UnwrapDOMObject<nsISupports>(aObject);
 }
 
 inline bool
 IsDOMObject(JSObject* obj)
 {
   return IsDOMClass(js::GetObjectClass(obj));
 }
@@ -215,17 +215,17 @@ IsDOMObject(JSObject* obj)
 // of thing it's looking at).
 // U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
 template <class T, typename U>
 MOZ_ALWAYS_INLINE nsresult
 UnwrapObject(JSObject* obj, U& value, prototypes::ID protoID,
              uint32_t protoDepth)
 {
   /* First check to see whether we have a DOM object */
-  const DOMClass* domClass = GetDOMClass(obj);
+  const DOMJSClass* domClass = GetDOMClass(obj);
   if (!domClass) {
     /* Maybe we have a security wrapper or outer window? */
     if (!js::IsWrapper(obj)) {
       /* Not a DOM object, not a wrapper, just bail */
       return NS_ERROR_XPC_BAD_CONVERT_JS;
     }
 
     obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
@@ -855,17 +855,17 @@ WrapNewBindingObject(JSContext* cx, T* v
       // At this point, obj is null, so just return false.
       // Callers seem to be testing JS_IsExceptionPending(cx) to
       // figure out whether WrapObject() threw.
       return false;
     }
   }
 
 #ifdef DEBUG
-  const DOMClass* clasp = GetDOMClass(obj);
+  const DOMJSClass* clasp = GetDOMClass(obj);
   // clasp can be null if the cache contained a non-DOM object.
   if (clasp) {
     // Some sanity asserts about our object.  Specifically:
     // 1)  If our class claims we're nsISupports, we better be nsISupports
     //     XXXbz ideally, we could assert that reinterpret_cast to nsISupports
     //     does the right thing, but I don't see a way to do it.  :(
     // 2)  If our class doesn't claim we're nsISupports we better be
     //     reinterpret_castable to nsWrapperCache.
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -310,24 +310,22 @@ def DOMClass(descriptor):
     # Pad out the list to the right length with _ID_Count so we
     # guarantee that all the lists are the same length.  _ID_Count
     # is never the ID of any prototype, so it's safe to use as
     # padding.
     protoList.extend(['prototypes::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList)))
 
     return fill(
         """
-        {
           { ${protoChain} },
           IsBaseOf<nsISupports, ${nativeType} >::value,
           ${hooks},
           GetParentObject<${nativeType}>::Get,
           GetProtoObject,
           GetCCParticipant<${nativeType}>::Get()
-        }
         """,
         protoChain=', '.join(protoList),
         nativeType=descriptor.nativeType,
         hooks=NativePropertyHooks(descriptor))
 
 
 class CGDOMJSClass(CGThing):
     """
@@ -1732,17 +1730,17 @@ class CGClassHasInstanceHook(CGAbstractS
                     *bp = !!qiResult;
                     return true;
                     """,
                     nativeType=self.descriptor.nativeType,
                     name=self.descriptor.interface.identifier.name))
 
         hasInstanceCode = dedent("""
 
-            const DOMClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance, /* stopAtOuter = */ false));
+            const DOMJSClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance, /* stopAtOuter = */ false));
             *bp = false;
             if (!domClass) {
               // Not a DOM object, so certainly not an instance of this interface
               return true;
             }
             """)
         if self.descriptor.interface.identifier.name == "ChromeWindow":
             setBp = "*bp = UnwrapDOMObject<nsGlobalWindow>(js::UncheckedUnwrap(instance, /* stopAtOuter = */ false))->IsChromeWindow()"
--- a/dom/bindings/DOMJSClass.h
+++ b/dom/bindings/DOMJSClass.h
@@ -162,18 +162,24 @@ typedef JSObject* (*ParentGetter)(JSCont
  * Returns a handle to the relevent WebIDL prototype object for the given global
  * (which may be a handle to null on out of memory).  Once allocated, the
  * prototype object is guaranteed to exist as long as the global does, since the
  * global traces its array of WebIDL prototypes and constructors.
  */
 typedef JS::Handle<JSObject*> (*ProtoGetter)(JSContext* aCx,
                                              JS::Handle<JSObject*> aGlobal);
 
-struct DOMClass
+// Special JSClass for reflected DOM objects.
+struct DOMJSClass
 {
+  // It would be nice to just inherit from JSClass, but that precludes pure
+  // compile-time initialization of the form |DOMJSClass = {...};|, since C++
+  // only allows brace initialization for aggregate/POD types.
+  const js::Class mBase;
+
   // A list of interfaces that this object implements, in order of decreasing
   // derivedness.
   const prototypes::ID mInterfaceChain[MAX_PROTOTYPE_CHAIN_LENGTH];
 
   // We store the DOM object in reserved slot with index DOM_OBJECT_SLOT or in
   // the proxy private if we use a proxy object.
   // Sometimes it's an nsISupports and sometimes it's not; this class tells
   // us which it is.
@@ -183,27 +189,16 @@ struct DOMClass
 
   ParentGetter mGetParent;
   ProtoGetter mGetProto;
 
   // This stores the CC participant for the native, null if this class is for a
   // worker or for a native inheriting from nsISupports (we can get the CC
   // participant by QI'ing in that case).
   nsCycleCollectionParticipant* mParticipant;
-};
-
-// Special JSClass for reflected DOM objects.
-struct DOMJSClass
-{
-  // It would be nice to just inherit from JSClass, but that precludes pure
-  // compile-time initialization of the form |DOMJSClass = {...};|, since C++
-  // only allows brace initialization for aggregate/POD types.
-  const js::Class mBase;
-
-  const DOMClass mClass;
 
   static const DOMJSClass* FromJSClass(const JSClass* base) {
     MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
     return reinterpret_cast<const DOMJSClass*>(base);
   }
 
   static const DOMJSClass* FromJSClass(const js::Class* base) {
     return FromJSClass(Jsvalify(base));
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -13,18 +13,16 @@
 #include "jsproxy.h"
 #include "nsString.h"
 
 #define DOM_PROXY_OBJECT_SLOT js::PROXY_PRIVATE_SLOT
 
 namespace mozilla {
 namespace dom {
 
-class DOMClass;
-
 enum {
   JSPROXYSLOT_EXPANDO = 0
 };
 
 template<typename T> struct Prefable;
 
 // This variable exists solely to provide a unique address for use as an identifier.
 extern const char HandlerFamily;
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -107,17 +107,17 @@ static const uint32_t FIELD_SLOT = 1;
 
 bool
 ValueHasISupportsPrivate(JS::Handle<JS::Value> v)
 {
   if (!v.isObject()) {
     return false;
   }
 
-  const DOMClass* domClass = GetDOMClass(&v.toObject());
+  const DOMJSClass* domClass = GetDOMClass(&v.toObject());
   if (domClass) {
     return domClass->mDOMObjectIsISupports;
   }
 
   const JSClass* clasp = ::JS_GetClass(&v.toObject());
   const uint32_t HAS_PRIVATE_NSISUPPORTS =
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS;
   return (clasp->flags & HAS_PRIVATE_NSISUPPORTS) == HAS_PRIVATE_NSISUPPORTS;
--- a/js/xpconnect/src/XPCQuickStubs.cpp
+++ b/js/xpconnect/src/XPCQuickStubs.cpp
@@ -641,17 +641,17 @@ castNativeFromWrapper(JSContext *cx,
     nsISupports *native;
     if (wrapper) {
         native = wrapper->GetIdentityObject();
         cur = wrapper->GetFlatJSObject();
         if (!native || !HasBitInInterfacesBitmap(cur, interfaceBit)) {
             native = nullptr;
         }
     } else if (cur && protoDepth >= 0) {
-        const mozilla::dom::DOMClass* domClass =
+        const mozilla::dom::DOMJSClass* domClass =
             mozilla::dom::GetDOMClass(cur);
         native = mozilla::dom::UnwrapDOMObject<nsISupports>(cur);
         if (native &&
             (uint32_t)domClass->mInterfaceChain[protoDepth] != protoID) {
             native = nullptr;
         }
     } else {
         native = nullptr;
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -613,17 +613,17 @@ CycleCollectedJSRuntime::NoteGCThingXPCO
   }
   // XXX This test does seem fragile, we should probably whitelist classes
   //     that do hold a strong reference, but that might not be possible.
   else if (aClasp->flags & JSCLASS_HAS_PRIVATE &&
            aClasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "js::GetObjectPrivate(obj)");
     aCb.NoteXPCOMChild(static_cast<nsISupports*>(js::GetObjectPrivate(aObj)));
   } else {
-    const DOMClass* domClass = GetDOMClass(aObj);
+    const DOMJSClass* domClass = GetDOMClass(aObj);
     if (domClass) {
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "UnwrapDOMObject(obj)");
       if (domClass->mDOMObjectIsISupports) {
         aCb.NoteXPCOMChild(UnwrapDOMObject<nsISupports>(aObj));
       } else if (domClass->mParticipant) {
         aCb.NoteNativeChild(UnwrapDOMObject<void>(aObj),
                             domClass->mParticipant);
       }