Bug 851465 - Remove slim wrappers - remove various slim wrapper code and checks. r=bholley.
authorPeter Van der Beken <peterv@propagandism.org>
Fri, 19 Apr 2013 21:57:18 +0200
changeset 146573 1c5330960d0c49ac16f5d67fa653f93abf58e6a3
parent 146572 1b34a34b25389bf3a7d92598f473f4589684c093
child 146574 dda67b97f819e240dda98bebab946e643edd88cb
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs851465
milestone24.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 851465 - Remove slim wrappers - remove various slim wrapper code and checks. r=bholley.
dom/bindings/BindingUtils.h
js/xpconnect/src/XPCCallContext.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -530,39 +530,34 @@ MaybeWrapValue(JSContext* cx, JS::Mutabl
   if (rval.isString()) {
     JSString* str = rval.toString();
     if (JS::GetGCThingZone(str) != js::GetContextZone(cx)) {
       return JS_WrapValue(cx, rval.address());
     }
     return true;
   }
 
-  if (rval.isObject()) {
-    JSObject* obj = &rval.toObject();
-    if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
-      return JS_WrapValue(cx, rval.address());
-    }
+  if (!rval.isObject()) {
+    return true;
+  }
 
-    // We're same-compartment, but even then we might need to wrap
-    // objects specially.  Check for that.
-    if (GetSameCompartmentWrapperForDOMBinding(obj)) {
-      // We're a new-binding object, and "obj" now points to the right thing
-      rval.set(JS::ObjectValue(*obj));
-      return true;
-    }
-
-    if (!IS_SLIM_WRAPPER(obj)) {
-      // We might need a SOW
-      return JS_WrapValue(cx, rval.address());
-    }
-
-    // Fall through to returning true
+  JSObject* obj = &rval.toObject();
+  if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
+    return JS_WrapValue(cx, rval.address());
   }
 
-  return true;
+  // We're same-compartment, but even then we might need to wrap
+  // objects specially.  Check for that.
+  if (GetSameCompartmentWrapperForDOMBinding(obj)) {
+    // We're a new-binding object, and "obj" now points to the right thing
+    rval.set(JS::ObjectValue(*obj));
+    return true;
+  }
+
+  return JS_WrapValue(cx, rval.address());
 }
 
 static inline void
 WrapNewBindingForSameCompartment(JSContext* cx, JSObject* obj, void* value,
                                  JS::MutableHandle<JS::Value> rval)
 {
   rval.set(JS::ObjectValue(*obj));
 }
@@ -637,17 +632,17 @@ WrapNewBindingObject(JSContext* cx, JS::
   bool sameCompartment =
     js::GetObjectCompartment(obj) == js::GetContextCompartment(cx);
   if (sameCompartment && couldBeDOMBinding) {
     WrapNewBindingForSameCompartment(cx, obj, value, rval);
     return true;
   }
 
   rval.set(JS::ObjectValue(*obj));
-  return (sameCompartment && IS_SLIM_WRAPPER(obj)) || JS_WrapValue(cx, rval.address());
+  return JS_WrapValue(cx, rval.address());
 }
 
 // Create a JSObject wrapping "value", for cases when "value" is a
 // non-wrapper-cached object using WebIDL bindings.  "value" must implement a
 // WrapObject() method taking a JSContext and a scope.
 template <class T>
 inline bool
 WrapNewBindingNonWrapperCachedObject(JSContext* cx,
--- a/js/xpconnect/src/XPCCallContext.cpp
+++ b/js/xpconnect/src/XPCCallContext.cpp
@@ -94,35 +94,31 @@ XPCCallContext::XPCCallContext(XPCContex
         if (!mWrapper) {
             JS_ReportError(mJSContext, "Permission denied to call method on |this|");
             mState = INIT_FAILED;
             return;
         }
     } else {
         js::Class *clasp = js::GetObjectClass(unwrapped);
         if (IS_WRAPPER_CLASS(clasp)) {
-            if (IS_SLIM_WRAPPER_OBJECT(unwrapped))
-                mFlattenedJSObject = unwrapped;
-            else
-                mWrapper = XPCWrappedNative::Get(unwrapped);
+            mWrapper = XPCWrappedNative::Get(unwrapped);
         } else if (IS_TEAROFF_CLASS(clasp)) {
             mTearOff = (XPCWrappedNativeTearOff*)js::GetObjectPrivate(unwrapped);
             mWrapper = XPCWrappedNative::Get(js::GetObjectParent(unwrapped));
         }
     }
     if (mWrapper) {
         mFlattenedJSObject = mWrapper->GetFlatJSObject();
 
         if (mTearOff)
             mScriptableInfo = nullptr;
         else
             mScriptableInfo = mWrapper->GetScriptableInfo();
     } else {
-        NS_ABORT_IF_FALSE(!mFlattenedJSObject || IS_SLIM_WRAPPER(mFlattenedJSObject),
-                          "should have a slim wrapper");
+        NS_ABORT_IF_FALSE(!mFlattenedJSObject, "What object do we have?");
     }
 
     if (!JSID_IS_VOID(name))
         SetName(name);
 
     if (argc != NO_ARGS)
         SetArgsAndResultPtr(argc, argv, rval);
 
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -833,18 +833,16 @@ XPCConvert::NativeInterface2JSObject(jsv
 
             if (flat) {
                 if (allowNativeWrapper && !JS_WrapObject(cx, flat.address()))
                     return false;
 
                 return CreateHolderIfNeeded(flat, d, dest);
             }
         }
-
-        MOZ_ASSERT_IF(flat, !IS_SLIM_WRAPPER_OBJECT(flat));
     } else {
         flat = nullptr;
     }
 
     // We can't simply construct a slim wrapper. Go ahead and create an
     // XPCWrappedNative for this object. At this point, |flat| could be
     // non-null, meaning that either we already have a wrapped native from
     // the cache (which might need to be QI'd to the new interface) or that
@@ -870,17 +868,19 @@ XPCConvert::NativeInterface2JSObject(jsv
     nsresult rv;
     XPCWrappedNative* wrapper;
     nsRefPtr<XPCWrappedNative> strongWrapper;
     if (!flat) {
         rv = XPCWrappedNative::GetNewOrUsed(aHelper, xpcscope, iface,
                                             getter_AddRefs(strongWrapper));
 
         wrapper = strongWrapper;
-    } else if (IS_WN_WRAPPER_OBJECT(flat)) {
+    } else {
+        MOZ_ASSERT(IS_WN_WRAPPER_OBJECT(flat));
+
         wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(flat));
 
         // If asked to return the wrapper we'll return a strong reference,
         // otherwise we'll just return its JSObject in d (which should be
         // rooted in that case).
         if (dest)
             strongWrapper = wrapper;
         if (iface)
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -465,18 +465,17 @@ nsJSIID::Enumerate(nsIXPConnectWrappedNa
  *
  * 2 - Prototype chains. Suppose someone creates a vanilla JS object |a| and
  *     sets its __proto__ to some WN |b|. If |b instanceof nsIFoo| returns true,
  *     one would expect |a instanceof nsIFoo| to return true as well, since
  *     instanceof is transitive up the prototype chain in ECMAScript. Moreover,
  *     there's chrome code that relies on this.
  *
  * This static method handles both complexities, returning either an XPCWN, a
- * slim wrapper, a DOM object, or null. The object may well be cross-compartment
- * from |cx|.
+ * DOM object, or null. The object may well be cross-compartment from |cx|.
  */
 static JSObject *
 FindObjectForHasInstance(JSContext *cx, HandleObject objArg)
 {
     RootedObject obj(cx, objArg), proto(cx);
     while (obj && !IS_WRAPPER_CLASS(js::GetObjectClass(obj)) && !IsDOMObject(obj)) {
         if (js::IsWrapper(obj)) {
             obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -2535,21 +2535,17 @@ PreserveWrapper(JSContext *cx, JSObject 
     RootedObject obj(cx, objArg);
     XPCCallContext ccx(NATIVE_CALLER, cx);
     if (!ccx.IsValid())
         return false;
 
     if (!IS_WRAPPER_CLASS(js::GetObjectClass(obj)))
         return mozilla::dom::TryPreserveWrapper(obj);
 
-    nsISupports *supports = nullptr;
-    if (IS_WN_WRAPPER_OBJECT(obj))
-        supports = XPCWrappedNative::Get(obj)->Native();
-    else
-        supports = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
+    nsISupports *supports = XPCWrappedNative::Get(obj)->Native();
 
     // For pre-Paris DOM bindings objects, we only support Node.
     if (nsCOMPtr<nsINode> node = do_QueryInterface(supports)) {
         nsContentUtils::PreserveWrapper(supports, node);
         return true;
     }
     return false;
 }
--- a/js/xpconnect/src/XPCQuickStubs.cpp
+++ b/js/xpconnect/src/XPCQuickStubs.cpp
@@ -560,24 +560,20 @@ getWrapper(JSContext *cx,
     // JS objects are parented to their wrapper, so we snag the tearoff object
     // along the way (if desired), and then set |obj| to its parent.
     js::Class* clasp = js::GetObjectClass(obj);
     if (clasp == &XPC_WN_Tearoff_JSClass) {
         *tearoff = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(obj);
         obj = js::GetObjectParent(obj);
     }
 
-    // If we've got a WN or slim wrapper, store things the way callers expect.
-    // Otherwise, leave things null and return.
-    if (IS_WRAPPER_CLASS(clasp)) {
-        if (IS_WN_WRAPPER_OBJECT(obj))
-            *wrapper = (XPCWrappedNative*) js::GetObjectPrivate(obj);
-        else
-            *cur = obj;
-    }
+    // If we've got a WN, store things the way callers expect. Otherwise, leave
+    // things null and return.
+    if (IS_WRAPPER_CLASS(clasp))
+        *wrapper = XPCWrappedNative::Get(obj);
 
     return NS_OK;
 }
 
 nsresult
 castNative(JSContext *cx,
            XPCWrappedNative *wrapper,
            JSObject *curArg,
@@ -592,22 +588,18 @@ castNative(JSContext *cx,
         nsresult rv = getNativeFromWrapper(cx,wrapper, iid, ppThis, pThisRef,
                                            vp);
 
         if (rv != NS_ERROR_NO_INTERFACE)
             return rv;
     } else if (cur) {
         nsISupports *native;
         if (!(native = mozilla::dom::UnwrapDOMObjectToISupports(cur))) {
-            if (IS_SLIM_WRAPPER(cur)) {
-                native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
-            } else {
-                *pThisRef = nullptr;
-                return NS_ERROR_ILLEGAL_VALUE;
-            }
+            *pThisRef = nullptr;
+            return NS_ERROR_ILLEGAL_VALUE;
         }
 
         if (NS_SUCCEEDED(getNative(native, cur, iid, ppThis, pThisRef, vp))) {
             return NS_OK;
         }
     }
 
     *pThisRef = nullptr;
@@ -625,38 +617,31 @@ castNativeFromWrapper(JSContext *cx,
                       nsresult *rv)
 {
     XPCWrappedNative *wrapper;
     XPCWrappedNativeTearOff *tearoff;
     JSObject *cur;
 
     if (IS_WRAPPER_CLASS(js::GetObjectClass(obj))) {
         cur = obj;
-        wrapper = IS_WN_WRAPPER_OBJECT(cur) ?
-                  (XPCWrappedNative*)xpc_GetJSPrivate(obj) :
-                  nullptr;
+        wrapper = (XPCWrappedNative*)xpc_GetJSPrivate(obj);
         tearoff = nullptr;
     } else {
         *rv = getWrapper(cx, obj, &wrapper, &cur, &tearoff);
         if (NS_FAILED(*rv))
             return nullptr;
     }
 
     nsISupports *native;
     if (wrapper) {
         native = wrapper->GetIdentityObject();
         cur = wrapper->GetFlatJSObject();
         if (!native || !HasBitInInterfacesBitmap(cur, interfaceBit)) {
             native = nullptr;
         }
-    } else if (cur && IS_SLIM_WRAPPER(cur)) {
-        native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
-        if (!native || !HasBitInInterfacesBitmap(cur, interfaceBit)) {
-            native = nullptr;
-        }
     } else if (cur && protoDepth >= 0) {
         const mozilla::dom::DOMClass* domClass =
             mozilla::dom::GetDOMClass(cur);
         native = mozilla::dom::UnwrapDOMObject<nsISupports>(cur);
         if (native &&
             (uint32_t)domClass->mInterfaceChain[protoDepth] != protoID) {
             native = nullptr;
         }
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -1315,17 +1315,17 @@ XPCWrappedNative::ReparentWrapperIfFound
     nsresult rv;
 
     nsRefPtr<XPCWrappedNative> wrapper;
     RootedObject flat(cx);
     nsWrapperCache* cache = nullptr;
     CallQueryInterface(aCOMObj, &cache);
     if (cache) {
         flat = cache->GetWrapper();
-        if (flat && !IS_SLIM_WRAPPER_OBJECT(flat)) {
+        if (flat) {
             wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(flat));
             NS_ASSERTION(wrapper->GetScope() == aOldScope,
                          "Incorrect scope passed");
         }
     } else {
         rv = XPCWrappedNative::GetUsedOnly(aCOMObj, aOldScope, iface,
                                            getter_AddRefs(wrapper));
         if (NS_FAILED(rv))
@@ -1336,18 +1336,17 @@ XPCWrappedNative::ReparentWrapperIfFound
     }
 
     if (!flat)
         return NS_OK;
 
     // ReparentWrapperIfFound is really only meant to be called from DOM code
     // which must happen only on the main thread. Bail if we're on some other
     // thread or have a non-main-thread-only wrapper.
-    if (wrapper &&
-        wrapper->GetProto() &&
+    if (wrapper->GetProto() &&
         !wrapper->GetProto()->ClassIsMainThreadOnly()) {
         return NS_ERROR_FAILURE;
     }
 
     JSAutoCompartment ac(cx, aNewScope->GetGlobalJSObject());
 
     if (aOldScope != aNewScope) {
         // Oh, so now we need to move the wrapper to a different scope.
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -588,68 +588,44 @@ XPC_WN_Shared_Enumerate(JSContext *cx, J
                 return false;
         }
     }
     return true;
 }
 
 /***************************************************************************/
 
-#ifdef DEBUG_slimwrappers
-static uint32_t sFinalizedSlimWrappers;
-#endif
-
 enum WNHelperType {
     WN_NOHELPER,
     WN_HELPER
 };
 
 static void
 WrappedNativeFinalize(js::FreeOp *fop, JSObject *obj, WNHelperType helperType)
 {
     js::Class* clazz = js::GetObjectClass(obj);
     if (clazz->flags & JSCLASS_DOM_GLOBAL) {
         mozilla::dom::DestroyProtoAndIfaceCache(obj);
     }
     nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
     if (!p)
         return;
 
-    if (IS_SLIM_WRAPPER_OBJECT(obj)) {
-        SLIM_LOG(("----- %i finalized slim wrapper (%p, %p)\n",
-                  ++sFinalizedSlimWrappers, obj, p));
-
-        nsWrapperCache* cache;
-        CallQueryInterface(p, &cache);
-        cache->ClearWrapper();
-
-        XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
-        MOZ_ASSERT(rt, "XPCJSRuntime should exist during a GC.");
-        rt->DeferredRelease(p);
-        return;
-    }
-
     XPCWrappedNative* wrapper = static_cast<XPCWrappedNative*>(p);
     if (helperType == WN_HELPER)
         wrapper->GetScriptableCallback()->Finalize(wrapper, js::CastToJSFreeOp(fop), obj);
     wrapper->FlatJSObjectFinalized();
 }
 
 static void
 XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
 {
     WrappedNativeFinalize(fop, obj, WN_NOHELPER);
 }
 
-static void
-TraceInsideSlimWrapper(JSTracer *trc, JSObject *obj)
-{
-    GetSlimWrapperProto(obj)->TraceSelf(trc);
-}
-
 /*
  * General comment about XPConnect tracing: Given a C++ object |wrapper| and its
  * corresponding JS object |obj|, calling |wrapper->TraceSelf| will ask the JS
  * engine to mark |obj|. Eventually, this will lead to the trace hook being
  * called for |obj|. The trace hook should call |wrapper->TraceInside|, which
  * should mark any JS objects held by |wrapper| as members.
  */
 
@@ -657,26 +633,19 @@ static void
 MarkWrappedNative(JSTracer *trc, JSObject *obj)
 {
     js::Class* clazz = js::GetObjectClass(obj);
     if (clazz->flags & JSCLASS_DOM_GLOBAL) {
         mozilla::dom::TraceProtoAndIfaceCache(trc, obj);
     }
     MOZ_ASSERT(IS_WRAPPER_CLASS(clazz));
 
-    if (IS_WN_WRAPPER_OBJECT(obj)) {
-        XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
-        if (wrapper) {
-            if (wrapper->IsValid())
-                wrapper->TraceInside(trc);
-        }
-    } else {
-        MOZ_ASSERT(IS_SLIM_WRAPPER_OBJECT(obj));
-        TraceInsideSlimWrapper(trc, obj);
-    }
+    XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
+    if (wrapper && wrapper->IsValid())
+        wrapper->TraceInside(trc);
 }
 
 static void
 XPC_WN_NoHelper_Trace(JSTracer *trc, JSObject *obj)
 {
     MarkWrappedNative(trc, obj);
 }
 
@@ -1366,19 +1335,16 @@ XPCNativeScriptableShared::PopulateJSCla
     if (mFlags.WantHasInstance())
         mJSClass.base.hasInstance = XPC_WN_Helper_HasInstance;
 
     mJSClass.base.trace = XPC_WN_NoHelper_Trace;
 
     if (mFlags.WantOuterObject())
         mJSClass.base.ext.outerObject = XPC_WN_OuterObject;
 
-    if (!(mFlags & nsIXPCScriptable::WANT_OUTER_OBJECT))
-        mCanBeSlim = true;
-
     mJSClass.base.ext.isWrappedNative = true;
 }
 
 /***************************************************************************/
 /***************************************************************************/
 
 // Compatibility hack.
 //
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1241,19 +1241,17 @@ nsXPConnect::GetNativeOfWrapper(JSContex
     NS_ASSERTION(aJSObj, "bad param");
 
     aJSObj = js::CheckedUnwrap(aJSObj, /* stopAtOuter = */ false);
     if (!aJSObj) {
         JS_ReportError(aJSContext, "Permission denied to get native of security wrapper");
         return nullptr;
     }
     if (IS_WRAPPER_CLASS(js::GetObjectClass(aJSObj))) {
-        if (IS_SLIM_WRAPPER_OBJECT(aJSObj))
-            return (nsISupports*)xpc_GetJSPrivate(aJSObj);
-        else if (XPCWrappedNative *wn = XPCWrappedNative::Get(aJSObj))
+        if (XPCWrappedNative *wn = XPCWrappedNative::Get(aJSObj))
             return wn->Native();
         return nullptr;
     }
 
     nsCOMPtr<nsISupports> canonical =
         do_QueryInterface(mozilla::dom::UnwrapDOMObjectToISupports(aJSObj));
     return canonical;
 }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -10,23 +10,16 @@
  * JS objects. JS manipulation of C++ objects tends to be significantly more
  * complex. This comment explains how it is orchestrated by XPConnect.
  *
  * For each C++ object to be manipulated in JS, there is a corresponding JS
  * object. This is called the "flattened JS object". By default, there is an
  * additional C++ object involved of type XPCWrappedNative. The XPCWrappedNative
  * holds pointers to the C++ object and the flat JS object.
  *
- * As an optimization, some C++ objects don't have XPCWrappedNatives, although
- * they still have a corresponding flattened JS object. These are called "slim
- * wrappers": all the wrapping information is stored in extra fields of the C++
- * object and the JS object. Slim wrappers are only used for DOM objects. As a
- * deoptimization, slim wrappers can be "morphed" into XPCWrappedNatives if the
- * extra fields of the XPCWrappedNative become necessary.
- *
  * All XPCWrappedNative objects belong to an XPCWrappedNativeScope. These scopes
  * are essentially in 1:1 correspondence with JS global objects. The
  * XPCWrappedNativeScope has a pointer to the JS global object. The parent of a
  * flattened JS object is, by default, the global JS object corresponding to the
  * wrapper's XPCWrappedNativeScope (the exception to this rule is when a
  * PreCreate hook asks for a different parent; see nsIXPCScriptable below).
  *
  * Some C++ objects (notably DOM objects) have information associated with them
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -126,24 +126,20 @@ static inline bool IS_SLIM_WRAPPER(JSObj
 extern bool
 xpc_OkToHandOutWrapper(nsWrapperCache *cache);
 
 inline JSObject*
 xpc_FastGetCachedWrapper(nsWrapperCache *cache, JSObject *scope, jsval *vp)
 {
     if (cache) {
         JSObject* wrapper = cache->GetWrapper();
-        NS_ASSERTION(!wrapper ||
-                     !cache->IsDOMBinding() ||
-                     !IS_SLIM_WRAPPER(wrapper),
-                     "Should never have a slim wrapper when IsDOMBinding()");
         if (wrapper &&
             js::GetObjectCompartment(wrapper) == js::GetObjectCompartment(scope) &&
             (cache->IsDOMBinding() ? !cache->HasSystemOnlyWrapper() :
-             (IS_SLIM_WRAPPER(wrapper) || xpc_OkToHandOutWrapper(cache)))) {
+                                     xpc_OkToHandOutWrapper(cache))) {
             *vp = OBJECT_TO_JSVAL(wrapper);
             return wrapper;
         }
     }
 
     return nullptr;
 }
 
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -56,21 +56,19 @@ using namespace XrayUtils;
 XrayType
 GetXrayType(JSObject *obj)
 {
     obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
     if (mozilla::dom::UseDOMXray(obj))
         return XrayForDOMObject;
 
     js::Class* clasp = js::GetObjectClass(obj);
-    if (IS_WRAPPER_CLASS(clasp) || clasp->ext.innerObject) {
-        NS_ASSERTION(clasp->ext.innerObject || IS_WN_WRAPPER_OBJECT(obj),
-                     "We forgot to Morph a slim wrapper!");
+    if (IS_WRAPPER_CLASS(clasp) || clasp->ext.innerObject)
         return XrayForWrappedNative;
-    }
+
     return NotXray;
 }
 
 ResolvingId::ResolvingId(JSContext *cx, HandleObject wrapper, HandleId id)
   : mId(id),
     mHolder(cx, getHolderObject(wrapper)),
     mPrev(getResolvingId(mHolder)),
     mXrayShadowing(false)