diff --git a/mozilla/dom/src/base/nsJSEnvironment.cpp b/mozilla/dom/src/base/nsJSEnvironment.cpp index ff9346e5654..d16ae469c91 100644 --- a/mozilla/dom/src/base/nsJSEnvironment.cpp +++ b/mozilla/dom/src/base/nsJSEnvironment.cpp @@ -880,37 +880,6 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data) return 0; } -static jsuword -GetThreadStackLimit() -{ - // Store the thread stack limit in a static local to ensure that all - // contexts get the same stack limit (they're all on the same thread - // anyways), and this also helps prevent returning a stack limit - // that is beyond the end of the stack if this method is called way - // deep on the stack. - - static jsuword sThreadStackLimit; - - if (sThreadStackLimit == 0) { - int stackDummy; - jsuword currentStackAddr = (jsuword)&stackDummy; - - const jsuword kStackSize = 0x80000; // 512k - -#if JS_STACK_GROWTH_DIRECTION < 0 - sThreadStackLimit = (currentStackAddr > kStackSize) - ? currentStackAddr - kStackSize - : 0; -#else - sThreadStackLimit = (currentStackAddr + kStackSize > currentStackAddr) - ? currentStackAddr + kStackSize - : (jsuword) -1; -#endif - } - - return sThreadStackLimit; -} - nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE) { @@ -932,8 +901,6 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE) if (mContext) { ::JS_SetContextPrivate(mContext, NS_STATIC_CAST(nsIScriptContext *, this)); - ::JS_SetThreadStackLimit(mContext, GetThreadStackLimit()); - // Make sure the new context gets the default context options ::JS_SetOptions(mContext, mDefaultJSOptions); diff --git a/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp b/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp index dd4fb55f217..98409d1f027 100644 --- a/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp @@ -68,6 +68,9 @@ const char* XPCJSRuntime::mStrings[] = { /***************************************************************************/ +// ContextCallback calls are chained +static JSContextCallback gOldJSContextCallback; + // GCCallback calls are chained static JSGCCallback gOldJSGCCallback; @@ -224,6 +227,28 @@ DetachedWrappedNativeProtoMarker(JSDHashTable *table, JSDHashEntryHdr *hdr, return JS_DHASH_NEXT; } +// GCCallback calls are chained +JS_STATIC_DLL_CALLBACK(JSBool) +ContextCallback(JSContext *cx, uintN operation) +{ + XPCJSRuntime* self = nsXPConnect::GetRuntime(); + if (self) + { + if (operation == JSCONTEXT_NEW) + { + XPCPerThreadData* tls = XPCPerThreadData::GetData(); + if(tls) + { + JS_SetThreadStackLimit(cx, tls->GetStackLimit()); + } + } + } + + return gOldJSContextCallback + ? gOldJSContextCallback(cx, operation) + : JS_TRUE; +} + // static JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) { @@ -768,6 +793,7 @@ XPCJSRuntime::~XPCJSRuntime() XPCConvert::RemoveXPCOMUCStringFinalizer(); gOldJSGCCallback = NULL; + gOldJSContextCallback = NULL; } XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect, @@ -811,7 +837,11 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect, NS_ASSERTION(!gOldJSGCCallback, "XPCJSRuntime created more than once"); if(mJSRuntime) + { + gOldJSContextCallback = JS_SetContextCallback(mJSRuntime, + ContextCallback); gOldJSGCCallback = JS_SetGCCallbackRT(mJSRuntime, GCCallback); + } // Install a JavaScript 'debugger' keyword handler in debug builds only #ifdef DEBUG diff --git a/mozilla/js/src/xpconnect/src/xpcprivate.h b/mozilla/js/src/xpconnect/src/xpcprivate.h index 16b476227f4..d828118ee29 100644 --- a/mozilla/js/src/xpconnect/src/xpcprivate.h +++ b/mozilla/js/src/xpconnect/src/xpcprivate.h @@ -2893,6 +2893,8 @@ public: void MarkAutoRootsBeforeJSFinalize(JSContext* cx); void MarkAutoRootsAfterJSFinalize(); + jsuword GetStackLimit() const { return mStackLimit; } + static void InitStatics() { gLock = nsnull; gThreads = nsnull; gTLSIndex = BAD_TLS_INDEX; } @@ -2921,6 +2923,8 @@ private: JSBool mExceptionManagerNotAvailable; AutoMarkingPtr* mAutoRoots; + jsuword mStackLimit; + #ifdef XPC_CHECK_WRAPPER_THREADSAFETY JSUint32 mWrappedNativeThreadsafetyReportDepth; #endif diff --git a/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp b/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp index 70c2cfa93cd..7dbe263f750 100644 --- a/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp +++ b/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp @@ -404,6 +404,27 @@ PRUintn XPCPerThreadData::gTLSIndex = BAD_TLS_INDEX; PRLock* XPCPerThreadData::gLock = nsnull; XPCPerThreadData* XPCPerThreadData::gThreads = nsnull; +static jsuword +GetThreadStackLimit() +{ + int stackDummy; + jsuword stackLimit, currentStackAddr = (jsuword)&stackDummy; + + const jsuword kStackSize = 0x80000; // 512k + +#if JS_STACK_GROWTH_DIRECTION < 0 + stackLimit = (currentStackAddr > kStackSize) + ? currentStackAddr - kStackSize + : 0; +#else + stackLimit = (currentStackAddr + kStackSize > currentStackAddr) + ? currentStackAddr + kStackSize + : (jsuword) -1; +#endif + + return stackLimit; +} + XPCPerThreadData::XPCPerThreadData() : mJSContextStack(new XPCJSContextStack()), mNextThread(nsnull), @@ -415,7 +436,8 @@ XPCPerThreadData::XPCPerThreadData() mExceptionManager(nsnull), mException(nsnull), mExceptionManagerNotAvailable(JS_FALSE), - mAutoRoots(nsnull) + mAutoRoots(nsnull), + mStackLimit(GetThreadStackLimit()) #ifdef XPC_CHECK_WRAPPER_THREADSAFETY , mWrappedNativeThreadsafetyReportDepth(0) #endif