Bug 753517 part 5. Enable the list IC for new DOM bindings too. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Fri, 24 Aug 2012 09:32:26 -0700
changeset 105396 dc3f29a730b10ace9129d2605c7a40822ee8121f
parent 105395 c526d9dfb684d8d7c053157861b9c147e8c5b0cb
child 105397 010b43686a5fb14887b56289d8635582eb49c9fb
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersbz
bugs753517
milestone17.0a1
Bug 753517 part 5. Enable the list IC for new DOM bindings too. r=bz.
dom/bindings/BindingUtils.h
dom/bindings/DOMJSProxyHandler.cpp
dom/bindings/DOMJSProxyHandler.h
js/xpconnect/src/dombindings.cpp
js/xpconnect/src/dombindings.h
js/xpconnect/src/xpcpublic.h
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -97,16 +97,17 @@ UnwrapDOMObject(JSObject* obj, DOMObject
 
 #ifdef DEBUG
   if (IsDOMClass(js::GetObjectClass(obj))) {
     MOZ_ASSERT(slot == eRegularDOMObject);
   } else {
     MOZ_ASSERT(js::IsObjectProxyClass(js::GetObjectClass(obj)) ||
                js::IsFunctionProxyClass(js::GetObjectClass(obj)));
     MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
+    MOZ_ASSERT(IsNewProxyBinding(js::GetProxyHandler(obj)));
     MOZ_ASSERT(slot == eProxyDOMObject);
   }
 #endif
 
   JS::Value val = js::GetReservedSlot(obj, slot);
   // XXXbz/khuey worker code tries to unwrap interface objects (which have
   // nothing here).  That needs to stop.
   // XXX We don't null-check UnwrapObject's result; aren't we going to crash
@@ -124,31 +125,32 @@ GetDOMClass(JSObject* obj)
 {
   js::Class* clasp = js::GetObjectClass(obj);
   if (IsDOMClass(clasp)) {
     return &DOMJSClass::FromJSClass(clasp)->mClass;
   }
 
   js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
   MOZ_ASSERT(handler->family() == ProxyFamily());
+  MOZ_ASSERT(IsNewProxyBinding(handler));
   return &static_cast<DOMProxyHandler*>(handler)->mClass;
 }
 
 inline DOMObjectSlot
 GetDOMClass(JSObject* obj, const DOMClass*& result)
 {
   js::Class* clasp = js::GetObjectClass(obj);
   if (IsDOMClass(clasp)) {
     result = &DOMJSClass::FromJSClass(clasp)->mClass;
     return eRegularDOMObject;
   }
 
   if (js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) {
     js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
-    if (handler->family() == ProxyFamily()) {
+    if (handler->family() == ProxyFamily() && IsNewProxyBinding(handler)) {
       result = &static_cast<DOMProxyHandler*>(handler)->mClass;
       return eProxyDOMObject;
     }
   }
 
   return eNonDOMObject;
 }
 
@@ -166,17 +168,18 @@ UnwrapDOMObjectToISupports(JSObject* obj
 }
 
 inline bool
 IsDOMObject(JSObject* obj)
 {
   js::Class* clasp = js::GetObjectClass(obj);
   return IsDOMClass(clasp) ||
          ((js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) &&
-          js::GetProxyHandler(obj)->family() == ProxyFamily());
+          (js::GetProxyHandler(obj)->family() == ProxyFamily() &&
+           IsNewProxyBinding(js::GetProxyHandler(obj))));
 }
 
 // Some callers don't want to set an exception when unwrappin fails
 // (for example, overload resolution uses unwrapping to tell what sort
 // 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 <prototypes::ID PrototypeID, class T, typename U>
 inline nsresult
--- a/dom/bindings/DOMJSProxyHandler.cpp
+++ b/dom/bindings/DOMJSProxyHandler.cpp
@@ -33,16 +33,27 @@ DefineStaticJSVals(JSContext* cx)
   JSAutoRequest ar(cx);
 
   return InternJSString(cx, s_length_id, "length");
 }
 
 
 int HandlerFamily;
 
+// Store the information for the specialized ICs.
+struct SetListBaseInformation
+{
+  SetListBaseInformation() {
+    js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO);
+  }
+};
+
+SetListBaseInformation gSetListBaseInformation;
+
+
 bool
 DefineConstructor(JSContext* cx, JSObject* obj, DefineInterface aDefine, nsresult* aResult)
 {
   bool enabled;
   bool defined = aDefine(cx, obj, &enabled);
   MOZ_ASSERT(!defined || enabled,
              "We defined a constructor but the new bindings are disabled?");
   *aResult = defined ? NS_OK : NS_ERROR_FAILURE;
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -19,21 +19,21 @@ namespace mozilla {
 namespace dom {
 
 enum {
   JSPROXYSLOT_EXPANDO = 0
 };
 
 template<typename T> struct Prefable;
 
-class DOMProxyHandler : public js::BaseProxyHandler
+class DOMProxyHandler : public DOMBaseProxyHandler
 {
 public:
   DOMProxyHandler(const DOMClass& aClass)
-    : js::BaseProxyHandler(ProxyFamily()),
+    : DOMBaseProxyHandler(true),
       mClass(aClass)
   {
   }
 
   bool getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
                              JSPropertyDescriptor* desc);
   bool defineProperty(JSContext* cx, JSObject* proxy, jsid id,
                       JSPropertyDescriptor* desc);
--- a/js/xpconnect/src/dombindings.cpp
+++ b/js/xpconnect/src/dombindings.cpp
@@ -60,25 +60,16 @@ DefineStaticJSVals(JSContext *cx)
 
     return SET_JSID_TO_STRING(cx, prototype) &&
            SET_JSID_TO_STRING(cx, length) &&
            SET_JSID_TO_STRING(cx, iterator) &&
            DefinePropertyStaticJSVals(cx);
 }
 
 
-int HandlerFamily;
-
-struct SetListBaseInformation
-{
-    SetListBaseInformation() {
-        js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO);
-    }
-} gSetListBaseInformation;
-
 JSBool
 Throw(JSContext *cx, nsresult rv)
 {
     XPCThrower::Throw(rv, cx);
     return false;
 }
 
 template<class T>
--- a/js/xpconnect/src/dombindings.h
+++ b/js/xpconnect/src/dombindings.h
@@ -12,19 +12,19 @@
 #include "jsproxy.h"
 #include "xpcpublic.h"
 #include "nsString.h"
 
 namespace mozilla {
 namespace dom {
 namespace oldproxybindings {
 
-class ProxyHandler : public js::BaseProxyHandler {
+class ProxyHandler : public DOMBaseProxyHandler {
 protected:
-    ProxyHandler() : js::BaseProxyHandler(ProxyFamily())
+    ProxyHandler() : DOMBaseProxyHandler(false)
     {
     }
 
 public:
     virtual bool isInstanceOf(JSObject *prototype) = 0;
 };
 
 class NoType;
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -304,41 +304,59 @@ Throw(JSContext *cx, nsresult rv);
 nsCycleCollectionParticipant *
 xpc_JSCompartmentParticipant();
 
 namespace mozilla {
 namespace dom {
 
 extern int HandlerFamily;
 inline void* ProxyFamily() { return &HandlerFamily; }
+
+class DOMBaseProxyHandler : public js::BaseProxyHandler {
+protected:
+    DOMBaseProxyHandler(bool aNewDOMProxy) : js::BaseProxyHandler(ProxyFamily()),
+                                             mNewDOMProxy(aNewDOMProxy)
+    {
+    }
+
+public:
+    bool mNewDOMProxy;
+};
+
+inline bool IsNewProxyBinding(js::BaseProxyHandler* handler)
+{
+  MOZ_ASSERT(handler->family() == ProxyFamily());
+  return static_cast<DOMBaseProxyHandler*>(handler)->mNewDOMProxy;
+}
+
 inline bool IsDOMProxy(JSObject *obj)
 {
     return js::IsProxy(obj) &&
-           js::GetProxyHandler(obj)->family() == ProxyFamily();
+           js::GetProxyHandler(obj)->family() == ProxyFamily() &&
+           IsNewProxyBinding(js::GetProxyHandler(obj));
 }
 
 typedef bool
 (*DefineInterface)(JSContext *cx, JSObject *global, bool *enabled);
 
 extern bool
 DefineStaticJSVals(JSContext *cx);
 void
 Register(nsScriptNameSpaceManager* aNameSpaceManager);
 extern bool
 DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine,
                   nsresult *aResult);
 
 namespace oldproxybindings {
 
-extern int HandlerFamily;
-inline void* ProxyFamily() { return &HandlerFamily; }
 inline bool instanceIsProxy(JSObject *obj)
 {
     return js::IsProxy(obj) &&
-           js::GetProxyHandler(obj)->family() == ProxyFamily();
+           js::GetProxyHandler(obj)->family() == ProxyFamily() &&
+           !IsNewProxyBinding(js::GetProxyHandler(obj));
 }
 extern bool
 DefineStaticJSVals(JSContext *cx);
 void
 Register(nsScriptNameSpaceManager* aNameSpaceManager);
 
 } // namespace oldproxybindings