Bug 865729 - Remove Context stack iterators. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Mon, 29 Apr 2013 11:16:23 -0700
changeset 130254 88dff387b118
parent 130253 7247e828e9f5
child 130255 a751e69be9f1
push id24609
push useremorley@mozilla.com
push dateTue, 30 Apr 2013 12:53:53 +0000
treeherdermozilla-central@3fb2370f4871 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs865729
milestone23.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 865729 - Remove Context stack iterators. r=gabor
content/base/src/nsContentUtils.cpp
js/xpconnect/idl/nsIJSContextStack.idl
js/xpconnect/src/XPCCallContext.cpp
js/xpconnect/src/XPCJSContextStack.cpp
js/xpconnect/src/XPCModule.h
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3008,46 +3008,16 @@ nsCxPusher::nsCxPusher()
 {
 }
 
 nsCxPusher::~nsCxPusher()
 {
   Pop();
 }
 
-static bool
-IsContextOnStack(JSContext *aContext)
-{
-  if (aContext == nsContentUtils::GetCurrentJSContext())
-    return true;
-
-  nsCOMPtr<nsIJSContextStackIterator>
-    iterator(do_CreateInstance("@mozilla.org/js/xpc/ContextStackIterator;1"));
-  NS_ENSURE_TRUE(iterator, false);
-
-  nsresult rv = iterator->Reset(nsContentUtils::XPConnect());
-  NS_ENSURE_SUCCESS(rv, false);
-
-  bool done;
-  JSContext *ctx = nullptr;
-  while (NS_SUCCEEDED(iterator->Done(&done)) && !done) {
-    rv = iterator->Prev(&ctx);
-    NS_ASSERTION(NS_SUCCEEDED(rv), "Broken iterator implementation");
-
-    if (!ctx) {
-      continue;
-    }
-
-    if (nsJSUtils::GetDynamicScriptContext(ctx) && ctx == aContext)
-      return true;
-  }
-
-  return false;
-}
-
 bool
 nsCxPusher::Push(EventTarget *aCurrentTarget)
 {
   if (mPushedSomething) {
     NS_ERROR("Whaaa! No double pushing with nsCxPusher::Push()!");
 
     return false;
   }
@@ -3133,17 +3103,20 @@ nsCxPusher::DoPush(JSContext* cx)
 {
   nsIXPConnect *xpc = nsContentUtils::XPConnect();
   if (!xpc) {
     // If someone tries to push a cx when we don't have the relevant state,
     // it's probably safest to just crash.
     MOZ_CRASH();
   }
 
-  if (cx && IsContextOnStack(cx)) {
+  // NB: The GetDynamicScriptContext is historical and might not be sane.
+  if (cx && nsJSUtils::GetDynamicScriptContext(cx) &&
+      xpc::danger::IsJSContextOnStack(cx))
+  {
     // If the context is on the stack, that means that a script
     // is running at the moment in the context.
     mScriptIsRunning = true;
   }
 
   if (!xpc::danger::PushJSContext(cx)) {
     MOZ_CRASH();
   }
--- a/js/xpconnect/idl/nsIJSContextStack.idl
+++ b/js/xpconnect/idl/nsIJSContextStack.idl
@@ -10,40 +10,14 @@
 
 [uuid(ff1e7ec6-249b-4bda-9068-7b06ebb58a2a)]
 interface nsIJSContextStack : nsISupports
 {
     readonly attribute int32_t  count;
     JSContext                   peek();
 };
 
-[uuid(c7e6b7aa-fc12-4ca7-b140-98c38b698961)]
-interface nsIJSContextStackIterator : nsISupports
-{
-    /**
-     * Resets this iterator to the beginning of this thread's stack.
-     */
-    void reset(in nsIJSContextStack stack);
-
-    /**
-     * Returns true if this iterator is at the end of its stack's contexts.
-     * @throws NS_ERROR_NOT_INITIALIZED If there has not been a previous call
-     *         to reset.
-     */
-    boolean done();
-
-    /**
-     * Returns the prev JSContext off of stack. Note that because we're 
-     * iterating over a stack, this value would be the next popped value.
-     *
-     * @throws NS_ERROR_NOT_INITIALIZED If there has not been a previous call
-     *         to reset.
-     * @throws NS_ERROR_NOT_AVAILABLE if already at the end.
-     */
-    JSContext prev();
-};
-
 [uuid(59ad3ff1-a2d3-4c11-b825-098bff3c3e15)]
 interface nsIThreadJSContextStack : nsIJSContextStack
 {
     /* inherits methods of nsIJSContextStack */
     [notxpcom,nostdcall] JSContext getSafeJSContext();
 };
--- a/js/xpconnect/src/XPCCallContext.cpp
+++ b/js/xpconnect/src/XPCCallContext.cpp
@@ -339,18 +339,17 @@ XPCCallContext::~XPCCallContext()
     }
 
     if (mJSContext) {
         if (mDestroyJSContextInDestructor) {
 #ifdef DEBUG_xpc_hacker
             printf("!xpc - doing deferred destruction of JSContext @ %p\n",
                    mJSContext);
 #endif
-            NS_ASSERTION(!XPCJSRuntime::Get()->GetJSContextStack()->
-                         DEBUG_StackHasJSContext(mJSContext),
+            NS_ASSERTION(!XPCJSRuntime::Get()->GetJSContextStack()->HasJSContext(mJSContext),
                          "JSContext still in threadjscontextstack!");
 
             JS_DestroyContext(mJSContext);
         }
     }
 
     if (shouldReleaseXPC && mXPC)
         NS_RELEASE(mXPC);
--- a/js/xpconnect/src/XPCJSContextStack.cpp
+++ b/js/xpconnect/src/XPCJSContextStack.cpp
@@ -98,26 +98,24 @@ XPCJSContextStack::Push(JSContext *cx)
             e.savedFrameChain = true;
         }
     }
 
     mStack.AppendElement(cx);
     return true;
 }
 
-#ifdef DEBUG
 bool
-XPCJSContextStack::DEBUG_StackHasJSContext(JSContext *cx)
+XPCJSContextStack::HasJSContext(JSContext *cx)
 {
     for (uint32_t i = 0; i < mStack.Length(); i++)
         if (cx == mStack[i].cx)
             return true;
     return false;
 }
-#endif
 
 static JSBool
 SafeGlobalResolve(JSContext *cx, JSHandleObject obj, JSHandleId id)
 {
     JSBool resolved;
     return JS_ResolveStandardClass(cx, obj, id, &resolved);
 }
 
@@ -208,50 +206,8 @@ XPCJSContextStack::GetSafeJSContext()
         mSafeJSContext = nullptr;
     }
 
     // Save it off so we can destroy it later.
     mOwnSafeJSContext = mSafeJSContext;
 
     return mSafeJSContext;
 }
-
-/***************************************************************************/
-
-NS_IMPL_ISUPPORTS1(nsXPCJSContextStackIterator, nsIJSContextStackIterator)
-
-NS_IMETHODIMP
-nsXPCJSContextStackIterator::Reset(nsIJSContextStack *aStack)
-{
-    NS_ASSERTION(aStack == nsXPConnect::GetXPConnect(),
-                 "aStack must be implemented by XPConnect singleton");
-    mStack = XPCJSRuntime::Get()->GetJSContextStack()->GetStack();
-    if (mStack->IsEmpty())
-        mStack = nullptr;
-    else
-        mPosition = mStack->Length() - 1;
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPCJSContextStackIterator::Done(bool *aDone)
-{
-    *aDone = !mStack;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXPCJSContextStackIterator::Prev(JSContext **aContext)
-{
-    if (!mStack)
-        return NS_ERROR_NOT_INITIALIZED;
-
-    *aContext = mStack->ElementAt(mPosition).cx;
-
-    if (mPosition == 0)
-        mStack = nullptr;
-    else
-        --mPosition;
-
-    return NS_OK;
-}
-
--- a/js/xpconnect/src/XPCModule.h
+++ b/js/xpconnect/src/XPCModule.h
@@ -7,61 +7,55 @@
 #include "xpcprivate.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozJSComponentLoader.h"
 #include "mozJSSubScriptLoader.h"
 
 /* Module implementation for the xpconnect library. */
 
 #define XPCVARIANT_CONTRACTID "@mozilla.org/xpcvariant;1"
-#define XPC_JSCONTEXT_STACK_ITERATOR_CONTRACTID                               \
-    "@mozilla.org/js/xpc/ContextStackIterator;1"
 
 // {FE4F7592-C1FC-4662-AC83-538841318803}
 #define SCRIPTABLE_INTERFACES_CID                                             \
     {0xfe4f7592, 0xc1fc, 0x4662,                                              \
       { 0xac, 0x83, 0x53, 0x88, 0x41, 0x31, 0x88, 0x3 } }
 
 #define MOZJSSUBSCRIPTLOADER_CONTRACTID "@mozilla.org/moz/jssubscript-loader;1"
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSID)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCException)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCJSContextStackIterator)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect,
                                          nsXPConnect::GetSingleton)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptError)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSComponentLoader)
 NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSSubScriptLoader)
 
 NS_DEFINE_NAMED_CID(NS_JS_ID_CID);
 NS_DEFINE_NAMED_CID(NS_XPCONNECT_CID);
 NS_DEFINE_NAMED_CID(NS_XPCEXCEPTION_CID);
 NS_DEFINE_NAMED_CID(NS_SCRIPTERROR_CID);
-NS_DEFINE_NAMED_CID(NS_XPC_JSCONTEXT_STACK_ITERATOR_CID);
 NS_DEFINE_NAMED_CID(MOZJSCOMPONENTLOADER_CID);
 NS_DEFINE_NAMED_CID(MOZ_JSSUBSCRIPTLOADER_CID);
 
 #define XPCONNECT_CIDENTRIES                                                  \
   { &kNS_JS_ID_CID, false, NULL,  nsJSIDConstructor },                        \
   { &kNS_XPCONNECT_CID, false, NULL,  nsIXPConnectConstructor },              \
   { &kNS_XPCEXCEPTION_CID, false, NULL, nsXPCExceptionConstructor },          \
   { &kNS_SCRIPTERROR_CID, false, NULL, nsScriptErrorConstructor },            \
-  { &kNS_XPC_JSCONTEXT_STACK_ITERATOR_CID, false, NULL, nsXPCJSContextStackIteratorConstructor }, \
   { &kMOZJSCOMPONENTLOADER_CID, false, NULL, mozJSComponentLoaderConstructor },\
   { &kMOZ_JSSUBSCRIPTLOADER_CID, false, NULL, mozJSSubScriptLoaderConstructor },
 
 #define XPCONNECT_CONTRACTS                                                   \
   { XPC_ID_CONTRACTID, &kNS_JS_ID_CID },                                      \
   { XPC_XPCONNECT_CONTRACTID, &kNS_XPCONNECT_CID },                           \
   { XPC_CONTEXT_STACK_CONTRACTID, &kNS_XPCONNECT_CID },                       \
   { XPC_RUNTIME_CONTRACTID, &kNS_XPCONNECT_CID },                             \
   { XPC_EXCEPTION_CONTRACTID, &kNS_XPCEXCEPTION_CID },                        \
   { NS_SCRIPTERROR_CONTRACTID, &kNS_SCRIPTERROR_CID },                        \
-  { XPC_JSCONTEXT_STACK_ITERATOR_CONTRACTID, &kNS_XPC_JSCONTEXT_STACK_ITERATOR_CID }, \
   { MOZJSCOMPONENTLOADER_CONTRACTID, &kMOZJSCOMPONENTLOADER_CID },            \
   { MOZJSSUBSCRIPTLOADER_CONTRACTID, &kMOZ_JSSUBSCRIPTLOADER_CID },
 
 #define XPCONNECT_CATEGORIES \
   { "module-loader", "js", MOZJSCOMPONENTLOADER_CONTRACTID },
 
 nsresult xpcModuleCtor();
 void xpcModuleDtor();
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1685,18 +1685,17 @@ nsXPConnect::ReleaseJSContext(JSContext 
         printf("!xpc - deferring destruction of JSContext @ %p\n",
                (void *)aJSContext);
 #endif
         ccx->SetDestroyJSContextInDestructor(true);
         return NS_OK;
     }
     // else continue on and synchronously destroy the JSContext ...
 
-    NS_ASSERTION(!XPCJSRuntime::Get()->GetJSContextStack()->
-                 DEBUG_StackHasJSContext(aJSContext),
+    NS_ASSERTION(!XPCJSRuntime::Get()->GetJSContextStack()->HasJSContext(aJSContext),
                  "JSContext still in threadjscontextstack!");
 
     if (noGC)
         JS_DestroyContextNoGC(aJSContext);
     else
         JS_DestroyContext(aJSContext);
     return NS_OK;
 }
@@ -2103,16 +2102,22 @@ PushJSContext(JSContext *aCx)
 }
 
 NS_EXPORT_(void)
 PopJSContext()
 {
     XPCJSRuntime::Get()->GetJSContextStack()->Pop();
 }
 
+bool
+IsJSContextOnStack(JSContext *aCx)
+{
+  return XPCJSRuntime::Get()->GetJSContextStack()->HasJSContext(aCx);
+}
+
 } /* namespace danger */
 } /* namespace xpc */
 
 nsIPrincipal*
 nsXPConnect::GetPrincipal(JSObject* obj, bool allowShortCircuit) const
 {
     NS_ASSERTION(IS_WRAPPER_CLASS(js::GetObjectClass(obj)),
                  "What kind of wrapper is this?");
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3646,48 +3646,28 @@ public:
     JSContext *Peek()
     {
         return mStack.IsEmpty() ? NULL : mStack[mStack.Length() - 1].cx;
     }
 
     JSContext *Pop();
     bool Push(JSContext *cx);
     JSContext *GetSafeJSContext();
-
-#ifdef DEBUG
-    bool DEBUG_StackHasJSContext(JSContext *cx);
-#endif
+    bool HasJSContext(JSContext *cx);
 
     const InfallibleTArray<XPCJSContextInfo>* GetStack()
     { return &mStack; }
 
 private:
     AutoInfallibleTArray<XPCJSContextInfo, 16> mStack;
     JSContext*  mSafeJSContext;
     JSContext*  mOwnSafeJSContext;
 };
 
 /***************************************************************************/
-
-#define NS_XPC_JSCONTEXT_STACK_ITERATOR_CID                                   \
-{ 0x05bae29d, 0x8aef, 0x486d,                                                 \
-  { 0x84, 0xaa, 0x53, 0xf4, 0x8f, 0x14, 0x68, 0x11 } }
-
-class nsXPCJSContextStackIterator MOZ_FINAL : public nsIJSContextStackIterator
-{
-public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIJSCONTEXTSTACKITERATOR
-
-private:
-    const InfallibleTArray<XPCJSContextInfo> *mStack;
-    uint32_t mPosition;
-};
-
-/***************************************************************************/
 // 'Components' object
 
 class nsXPCComponents : public nsIXPCComponents,
                         public nsIXPCScriptable,
                         public nsIClassInfo,
                         public nsISecurityCheckedComponent
 {
 public:
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -467,16 +467,18 @@ xpc_JSZoneParticipant();
 // should go through one of the RAII classes (nsCxPusher, or one of the
 // convenience wrappers defined in nsContentUtils.h).
 namespace xpc {
 namespace danger {
 
 NS_EXPORT_(bool) PushJSContext(JSContext *aCx);
 NS_EXPORT_(void) PopJSContext();
 
+bool IsJSContextOnStack(JSContext *aCx);
+
 } /* namespace danger */
 } /* namespace xpc */
 
 namespace mozilla {
 namespace dom {
 
 extern int HandlerFamily;
 inline void* ProxyFamily() { return &HandlerFamily; }