Bug 792235 - rm JS_SuspendRequest (r=mrbkap)
authorLuke Wagner <luke@mozilla.com>
Tue, 04 Sep 2012 14:43:25 -0700
changeset 107555 46c3160c248125f2e493070d5c8089e678b0d98d
parent 107554 13afdf7150cfddb690cc6408cdc263d332f89b65
child 107556 1b9a3e26763a25c292aea34ea3ea72ebdc133e2f
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersmrbkap
bugs792235
milestone18.0a1
Bug 792235 - rm JS_SuspendRequest (r=mrbkap)
dom/base/nsDOMClassInfo.cpp
js/src/ctypes/CTypes.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/jsgc.cpp
js/src/shell/js.cpp
js/xpconnect/src/XPCJSContextStack.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -7446,18 +7446,16 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     }
 
     if (sDialogArguments_id == id && win->IsModalContentWindow()) {
       nsCOMPtr<nsIArray> args;
       ((nsGlobalModalWindow *)win)->GetDialogArguments(getter_AddRefs(args));
 
       nsIScriptContext *script_cx = win->GetContext();
       if (script_cx) {
-        JSAutoSuspendRequest asr(cx);
-
         // Make nsJSContext::SetProperty()'s magic argument array
         // handling happen.
         rv = script_cx->SetProperty(obj, "dialogArguments", args);
         NS_ENSURE_SUCCESS(rv, rv);
 
         *objp = obj;
       }
 
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -5564,34 +5564,27 @@ FunctionType::Call(JSContext* cx,
   int32_t lastErrorStatus; // The status as defined by |GetLastError|
   int32_t savedLastError = GetLastError();
   SetLastError(0);
 #endif //defined(XP_WIN)
   int errnoStatus;         // The status as defined by |errno|
   int savedErrno = errno;
   errno = 0;
 
-  // suspend the request before we call into the function, since the call
-  // may block or otherwise take a long time to return.
-  {
-    JSAutoSuspendRequest suspend(cx);
-    ffi_call(&fninfo->mCIF, FFI_FN(fn), returnValue.mData,
-             reinterpret_cast<void**>(values.begin()));
-
-    // Save error value.
-    // We need to save it before leaving the scope of |suspend| as destructing
-    // |suspend| has the side-effect of clearing |GetLastError|
-    // (see bug 684017).
-
-    errnoStatus = errno;
+  ffi_call(&fninfo->mCIF, FFI_FN(fn), returnValue.mData,
+           reinterpret_cast<void**>(values.begin()));
+
+  // Save error value.
+  // We need to save it before leaving the scope of |suspend| as destructing
+  // |suspend| has the side-effect of clearing |GetLastError|
+  // (see bug 684017).
+
+  errnoStatus = errno;
 #if defined(XP_WIN)
-    lastErrorStatus = GetLastError();
-#endif // defined(XP_WIN)
-  }
-#if defined(XP_WIN)
+  lastErrorStatus = GetLastError();
   SetLastError(savedLastError);
 #endif // defined(XP_WIN)
 
   errno = savedErrno;
 
   // Store the error value for later consultation with |ctypes.getStatus|
   JSObject *objCTypes = CType::GetGlobalCTypes(cx, typeObj);
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -732,17 +732,16 @@ JSRuntime::JSRuntime()
     nativeStackQuota(0),
     interpreterFrames(NULL),
     cxCallback(NULL),
     destroyCompartmentCallback(NULL),
     compartmentNameCallback(NULL),
     activityCallback(NULL),
     activityCallbackArg(NULL),
 #ifdef JS_THREADSAFE
-    suspendCount(0),
     requestDepth(0),
 # ifdef DEBUG
     checkRequestDepth(0),
 # endif
 #endif
     gcSystemAvailableChunkListHead(NULL),
     gcUserAvailableChunkListHead(NULL),
     gcKeepAtoms(0),
@@ -1161,17 +1160,17 @@ static void
 StopRequest(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
     rt->assertValidThread();
     JS_ASSERT(rt->requestDepth != 0);
     if (rt->requestDepth != 1) {
         rt->requestDepth--;
     } else {
-        rt->conservativeGC.updateForRequestEnd(rt->suspendCount);
+        rt->conservativeGC.updateForRequestEnd();
         rt->requestDepth = 0;
 
         if (rt->activityCallback)
             rt->activityCallback(rt->activityCallbackArg, false);
     }
 }
 #endif /* JS_THREADSAFE */
 
@@ -1189,85 +1188,27 @@ JS_EndRequest(JSContext *cx)
 {
 #ifdef JS_THREADSAFE
     JS_ASSERT(cx->outstandingRequests != 0);
     cx->outstandingRequests--;
     StopRequest(cx);
 #endif
 }
 
-/* Yield to pending GC operations, regardless of request depth */
-JS_PUBLIC_API(void)
-JS_YieldRequest(JSContext *cx)
-{
-#ifdef JS_THREADSAFE
-    CHECK_REQUEST(cx);
-    JS_ResumeRequest(cx, JS_SuspendRequest(cx));
-#endif
-}
-
-JS_PUBLIC_API(unsigned)
-JS_SuspendRequest(JSContext *cx)
-{
-#ifdef JS_THREADSAFE
-    JSRuntime *rt = cx->runtime;
-    rt->assertValidThread();
-
-    unsigned saveDepth = rt->requestDepth;
-    if (!saveDepth)
-        return 0;
-
-    rt->suspendCount++;
-    rt->requestDepth = 1;
-    StopRequest(cx);
-    return saveDepth;
-#else
-    return 0;
-#endif
-}
-
-JS_PUBLIC_API(void)
-JS_ResumeRequest(JSContext *cx, unsigned saveDepth)
-{
-#ifdef JS_THREADSAFE
-    JSRuntime *rt = cx->runtime;
-    rt->assertValidThread();
-    if (saveDepth == 0)
-        return;
-    JS_ASSERT(saveDepth >= 1);
-    JS_ASSERT(!rt->requestDepth);
-    JS_ASSERT(rt->suspendCount);
-    StartRequest(cx);
-    rt->requestDepth = saveDepth;
-    rt->suspendCount--;
-#endif
-}
-
 JS_PUBLIC_API(JSBool)
 JS_IsInRequest(JSRuntime *rt)
 {
 #ifdef JS_THREADSAFE
     rt->assertValidThread();
     return rt->requestDepth != 0;
 #else
     return false;
 #endif
 }
 
-JS_PUBLIC_API(JSBool)
-JS_IsInSuspendedRequest(JSRuntime *rt)
-{
-#ifdef JS_THREADSAFE
-    rt->assertValidThread();
-    return rt->suspendCount != 0;
-#else
-    return false;
-#endif
-}
-
 JS_PUBLIC_API(JSContextCallback)
 JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback)
 {
     JSContextCallback old;
 
     old = rt->cxCallback;
     rt->cxCallback = cxCallback;
     return old;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2901,32 +2901,19 @@ JS_PUBLIC_API(void)
 JS_SetRuntimePrivate(JSRuntime *rt, void *data);
 
 extern JS_PUBLIC_API(void)
 JS_BeginRequest(JSContext *cx);
 
 extern JS_PUBLIC_API(void)
 JS_EndRequest(JSContext *cx);
 
-/* Yield to pending GC operations, regardless of request depth */
-extern JS_PUBLIC_API(void)
-JS_YieldRequest(JSContext *cx);
-
-extern JS_PUBLIC_API(unsigned)
-JS_SuspendRequest(JSContext *cx);
-
-extern JS_PUBLIC_API(void)
-JS_ResumeRequest(JSContext *cx, unsigned saveDepth);
-
 extern JS_PUBLIC_API(JSBool)
 JS_IsInRequest(JSRuntime *rt);
 
-extern JS_PUBLIC_API(JSBool)
-JS_IsInSuspendedRequest(JSRuntime *rt);
-
 #ifdef __cplusplus
 JS_END_EXTERN_C
 
 namespace JS {
 
 extern mozilla::ThreadLocal<JSRuntime *> TlsRuntime;
 
 inline bool
@@ -2953,66 +2940,26 @@ template <> struct RootMethods<jsid>
     static bool poisoned(jsid id) { return IsPoisonedId(id); }
 };
 
 } /* namespace JS */
 
 class JSAutoRequest {
   public:
     JSAutoRequest(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : mContext(cx), mSaveDepth(0) {
+        : mContext(cx) {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
         JS_BeginRequest(mContext);
     }
     ~JSAutoRequest() {
         JS_EndRequest(mContext);
     }
 
-    void suspend() {
-        mSaveDepth = JS_SuspendRequest(mContext);
-    }
-    void resume() {
-        JS_ResumeRequest(mContext, mSaveDepth);
-    }
-
   protected:
     JSContext *mContext;
-    unsigned  mSaveDepth;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-
-#if 0
-  private:
-    static void *operator new(size_t) CPP_THROW_NEW { return 0; };
-    static void operator delete(void *, size_t) { };
-#endif
-};
-
-class JSAutoSuspendRequest {
-  public:
-    JSAutoSuspendRequest(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
-        : mContext(cx), mSaveDepth(0) {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-        if (mContext) {
-            mSaveDepth = JS_SuspendRequest(mContext);
-        }
-    }
-    ~JSAutoSuspendRequest() {
-        resume();
-    }
-
-    void resume() {
-        if (mContext) {
-            JS_ResumeRequest(mContext, mSaveDepth);
-            mContext = 0;
-        }
-    }
-
-  protected:
-    JSContext *mContext;
-    unsigned mSaveDepth;
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 
 #if 0
   private:
     static void *operator new(size_t) CPP_THROW_NEW { return 0; };
     static void operator delete(void *, size_t) { };
 #endif
 };
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -160,21 +160,18 @@ struct ConservativeGCData
          */
         JS_ASSERT(!hasStackToScan());
 #endif
     }
 
     JS_NEVER_INLINE void recordStackTop();
 
 #ifdef JS_THREADSAFE
-    void updateForRequestEnd(unsigned suspendCount) {
-        if (suspendCount)
-            recordStackTop();
-        else
-            nativeStackTop = NULL;
+    void updateForRequestEnd() {
+        nativeStackTop = NULL;
     }
 #endif
 
     bool hasStackToScan() const {
         return !!nativeStackTop;
     }
 };
 
@@ -497,19 +494,16 @@ struct JSRuntime : js::RuntimeFriendFiel
 
     /* Call this to get the name of a compartment. */
     JSCompartmentNameCallback compartmentNameCallback;
 
     js::ActivityCallback  activityCallback;
     void                 *activityCallbackArg;
 
 #ifdef JS_THREADSAFE
-    /* Number of JS_SuspendRequest calls withot JS_ResumeRequest. */
-    unsigned            suspendCount;
-
     /* The request depth for this thread. */
     unsigned            requestDepth;
 
 # ifdef DEBUG
     unsigned            checkRequestDepth;
 # endif
 #endif
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1201,17 +1201,16 @@ MarkConservativeStackRoots(JSTracer *trc
 
     if (rt->gcIncrementalState == MARK_ROOTS)
         rt->gcSavedRoots.clearAndFree();
 #endif
 
     ConservativeGCData *cgcd = &rt->conservativeGC;
     if (!cgcd->hasStackToScan()) {
 #ifdef JS_THREADSAFE
-        JS_ASSERT(!rt->suspendCount);
         JS_ASSERT(!rt->requestDepth);
 #endif
         return;
     }
 
     uintptr_t *stackMin, *stackEnd;
 #if JS_STACK_GROWTH_DIRECTION > 0
     stackMin = rt->nativeStackBase;
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -462,21 +462,17 @@ Process(JSContext *cx, JSObject *obj_, c
          */
         startline = lineno;
         size_t len = 0; /* initialize to avoid warnings */
         do {
             ScheduleWatchdog(cx->runtime, -1);
             gCanceled = false;
             errno = 0;
 
-            char *line;
-            {
-                JSAutoSuspendRequest suspended(cx);
-                line = GetLine(file, startline == lineno ? "js> " : "");
-            }
+            char *line = GetLine(file, startline == lineno ? "js> " : "");
             if (!line) {
                 if (errno) {
                     JS_ReportError(cx, strerror(errno));
                     free(buffer);
                     goto cleanup;
                 }
                 hitEOF = true;
                 break;
@@ -732,48 +728,45 @@ Load(JSContext *cx, unsigned argc, jsval
     return true;
 }
 
 class AutoNewContext
 {
   private:
     JSContext *oldcx;
     JSContext *newcx;
-    Maybe<JSAutoSuspendRequest> suspension;
     Maybe<JSAutoRequest> newRequest;
 
     AutoNewContext(const AutoNewContext &) MOZ_DELETE;
 
   public:
     AutoNewContext() : oldcx(NULL), newcx(NULL) {}
 
     bool enter(JSContext *cx) {
         JS_ASSERT(!JS_IsExceptionPending(cx));
         oldcx = cx;
         newcx = NewContext(JS_GetRuntime(cx));
         if (!newcx)
             return false;
         JS_SetOptions(newcx, JS_GetOptions(newcx) | JSOPTION_DONT_REPORT_UNCAUGHT);
         JS_SetGlobalObject(newcx, JS_GetGlobalForScopeChain(cx));
 
-        suspension.construct(cx);
         newRequest.construct(newcx);
         return true;
     }
 
     JSContext *get() { return newcx; }
 
     ~AutoNewContext() {
         if (newcx) {
             RootedValue exc(oldcx);
             bool throwing = JS_IsExceptionPending(newcx);
             if (throwing)
                 JS_GetPendingException(newcx, exc.address());
             newRequest.destroy();
-            suspension.destroy();
             if (throwing)
                 JS_SetPendingException(oldcx, exc);
             DestroyContext(newcx, false);
         }
     }
 };
 
 static JSBool
@@ -2702,33 +2695,28 @@ Sleep_fn(JSContext *cx, unsigned argc, j
         if (!(t_secs <= MAX_TIMEOUT_INTERVAL)) {
             JS_ReportError(cx, "Excessive sleep interval");
             return false;
         }
         t_ticks = (t_secs <= 0.0)
                   ? 0
                   : int64_t(PRMJ_USEC_PER_SEC * t_secs);
     }
-    if (t_ticks == 0) {
-        JS_YieldRequest(cx);
-    } else {
-        JSAutoSuspendRequest suspended(cx);
-        PR_Lock(gWatchdogLock);
-        int64_t to_wakeup = PRMJ_Now() + t_ticks;
-        for (;;) {
-            PR_WaitCondVar(gSleepWakeup, t_ticks);
-            if (gCanceled)
-                break;
-            int64_t now = PRMJ_Now();
-            if (!IsBefore(now, to_wakeup))
-                break;
-            t_ticks = to_wakeup - now;
-        }
-        PR_Unlock(gWatchdogLock);
+    PR_Lock(gWatchdogLock);
+    int64_t to_wakeup = PRMJ_Now() + t_ticks;
+    for (;;) {
+        PR_WaitCondVar(gSleepWakeup, t_ticks);
+        if (gCanceled)
+            break;
+        int64_t now = PRMJ_Now();
+        if (!IsBefore(now, to_wakeup))
+            break;
+        t_ticks = to_wakeup - now;
     }
+    PR_Unlock(gWatchdogLock);
     return !gCanceled;
 }
 
 static bool
 InitWatchdog(JSRuntime *rt)
 {
     JS_ASSERT(!gWatchdogThread);
     gWatchdogLock = PR_NewLock();
--- a/js/xpconnect/src/XPCJSContextStack.cpp
+++ b/js/xpconnect/src/XPCJSContextStack.cpp
@@ -39,29 +39,21 @@ XPCJSContextStack::Pop()
 
     mStack.RemoveElementAt(idx);
     if (idx == 0)
         return cx;
 
     --idx; // Advance to new top of the stack
 
     XPCJSContextInfo &e = mStack[idx];
-    NS_ASSERTION(!e.suspendDepth || e.cx, "Shouldn't have suspendDepth without a cx!");
-    if (e.cx) {
-        if (e.suspendDepth) {
-            JS_ResumeRequest(e.cx, e.suspendDepth);
-            e.suspendDepth = 0;
-        }
-
-        if (e.savedFrameChain) {
-            // Pop() can be called outside any request for e.cx.
-            JSAutoRequest ar(e.cx);
-            JS_RestoreFrameChain(e.cx);
-            e.savedFrameChain = false;
-        }
+    if (e.cx && e.savedFrameChain) {
+        // Pop() can be called outside any request for e.cx.
+        JSAutoRequest ar(e.cx);
+        JS_RestoreFrameChain(e.cx);
+        e.savedFrameChain = false;
     }
     return cx;
 }
 
 static nsIPrincipal*
 GetPrincipalFromCx(JSContext *cx)
 {
     nsIScriptContextPrincipal* scp = GetScriptContextPrincipalFromJSContext(cx);
@@ -100,19 +92,16 @@ XPCJSContextStack::Push(JSContext *cx)
 
         {
             // Push() can be called outside any request for e.cx.
             JSAutoRequest ar(e.cx);
             if (!JS_SaveFrameChain(e.cx))
                 return false;
             e.savedFrameChain = true;
         }
-
-        if (!cx)
-            e.suspendDepth = JS_SuspendRequest(e.cx);
     }
 
     mStack.AppendElement(cx);
     return true;
 }
 
 #ifdef DEBUG
 bool
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -497,17 +497,17 @@ nsXPConnect::BeginCycleCollection(nsCycl
     return NS_OK;
 }
 
 bool
 nsXPConnect::NotifyLeaveMainThread()
 {
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "Off main thread");
     JSRuntime *rt = mRuntime->GetJSRuntime();
-    if (JS_IsInRequest(rt) || JS_IsInSuspendedRequest(rt))
+    if (JS_IsInRequest(rt))
         return false;
     JS_ClearRuntimeThread(rt);
     return true;
 }
 
 void
 nsXPConnect::NotifyEnterCycleCollectionThread()
 {
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3638,26 +3638,22 @@ private:
 
 
 /***************************************************************************/
 // XPCJSContextStack is not actually an xpcom object, but xpcom calls are
 // delegated to it as an implementation detail.
 struct XPCJSContextInfo {
     XPCJSContextInfo(JSContext* aCx) :
         cx(aCx),
-        savedFrameChain(false),
-        suspendDepth(0)
+        savedFrameChain(false)
     {}
     JSContext* cx;
 
     // Whether the frame chain was saved
     bool savedFrameChain;
-
-    // Greater than 0 if a request was suspended.
-    unsigned suspendDepth;
 };
 
 class XPCJSContextStack
 {
 public:
     XPCJSContextStack()
       : mSafeJSContext(NULL)
       , mOwnSafeJSContext(NULL)