зеркало из https://github.com/mozilla/pjs.git
Fixing bug 412698. Make XPConnect cache the per thread data for the main thread and use the cache when running on the main thread to save on time getting at the per thread data. r=dbradley@gmail.com, sr=brendan@mozilla.org
This commit is contained in:
Родитель
26a66a2208
Коммит
0e7f93e216
|
@ -1613,7 +1613,7 @@ nsXPConnect::GetCurrentNativeCallContext(nsAXPCNativeCallContext * *aCurrentNati
|
|||
{
|
||||
NS_ASSERTION(aCurrentNativeCallContext, "bad param");
|
||||
|
||||
XPCPerThreadData* data = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
|
||||
if(data)
|
||||
{
|
||||
*aCurrentNativeCallContext = data->GetCallContext();
|
||||
|
@ -1630,7 +1630,7 @@ nsXPConnect::GetPendingException(nsIException * *aPendingException)
|
|||
{
|
||||
NS_ASSERTION(aPendingException, "bad param");
|
||||
|
||||
XPCPerThreadData* data = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
|
||||
if(!data)
|
||||
{
|
||||
*aPendingException = nsnull;
|
||||
|
@ -1643,7 +1643,7 @@ nsXPConnect::GetPendingException(nsIException * *aPendingException)
|
|||
NS_IMETHODIMP
|
||||
nsXPConnect::SetPendingException(nsIException * aPendingException)
|
||||
{
|
||||
XPCPerThreadData* data = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
|
||||
if(!data)
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -1993,7 +1993,7 @@ NS_IMETHODIMP
|
|||
nsXPConnect::ReleaseJSContext(JSContext * aJSContext, PRBool noGC)
|
||||
{
|
||||
NS_ASSERTION(aJSContext, "bad param");
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData(aJSContext);
|
||||
if(tls)
|
||||
{
|
||||
XPCCallContext* ccx = nsnull;
|
||||
|
|
|
@ -77,7 +77,9 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
|||
|
||||
NS_ADDREF(mXPC);
|
||||
|
||||
if(!(mThreadData = XPCPerThreadData::GetData()))
|
||||
mThreadData = XPCPerThreadData::GetData(mJSContext);
|
||||
|
||||
if(!mThreadData)
|
||||
return;
|
||||
|
||||
XPCJSContextStack* stack = mThreadData->GetJSContextStack();
|
||||
|
@ -357,7 +359,7 @@ XPCCallContext::~XPCCallContext()
|
|||
// Don't clear newborns if JS frames (compilation or execution)
|
||||
// are active! Doing so violates ancient invariants in the JS
|
||||
// engine, and it's not necessary to fix JS component leaks.
|
||||
if (!mJSContext->fp)
|
||||
if(!mJSContext->fp)
|
||||
JS_ClearNewbornRoots(mJSContext);
|
||||
}
|
||||
}
|
||||
|
@ -389,7 +391,8 @@ XPCCallContext::NewStringWrapper(PRUnichar *str, PRUint32 len)
|
|||
{
|
||||
StringWrapperEntry& ent = se[i];
|
||||
|
||||
if (!ent.mInUse) {
|
||||
if(!ent.mInUse)
|
||||
{
|
||||
ent.mInUse = PR_TRUE;
|
||||
|
||||
// Construct the string using placement new.
|
||||
|
@ -413,7 +416,7 @@ XPCCallContext::DeleteString(nsAString *string)
|
|||
for(i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
|
||||
{
|
||||
StringWrapperEntry& ent = se[i];
|
||||
if (string == &ent.mString)
|
||||
if(string == &ent.mString)
|
||||
{
|
||||
// One of our internal strings is no longer in use, mark
|
||||
// it as such and destroy the string.
|
||||
|
|
|
@ -3506,7 +3506,7 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
XPCPerThreadData *data = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData *data = XPCPerThreadData::GetData(cx);
|
||||
XPCJSContextStack *stack = nsnull;
|
||||
if (data && (stack = data->GetJSContextStack())) {
|
||||
if (NS_FAILED(stack->Push(sandcx->GetJSContext()))) {
|
||||
|
|
|
@ -238,7 +238,7 @@ ContextCallback(JSContext *cx, uintN operation)
|
|||
{
|
||||
if (operation == JSCONTEXT_NEW)
|
||||
{
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
|
||||
if(tls)
|
||||
{
|
||||
JS_SetThreadStackLimit(cx, tls->GetStackLimit());
|
||||
|
@ -1201,7 +1201,7 @@ XPCJSRuntime::SyncXPCContextList(JSContext* cx /* = nsnull */)
|
|||
// get rid of any XPCContexts that represent dead JSContexts
|
||||
mContextMap->Enumerate(SweepContextsCB, 0);
|
||||
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
|
||||
if(tls)
|
||||
{
|
||||
if(found)
|
||||
|
|
|
@ -3041,7 +3041,19 @@ class XPCPerThreadData
|
|||
{
|
||||
public:
|
||||
// Get the instance of this object for the current thread
|
||||
static XPCPerThreadData* GetData();
|
||||
static inline XPCPerThreadData* GetData(JSContext *cx)
|
||||
{
|
||||
if(cx)
|
||||
{
|
||||
NS_ASSERTION(cx->thread, "Uh, JS context w/o a thread?");
|
||||
|
||||
if(cx->thread == sMainJSThread)
|
||||
return sMainThreadData;
|
||||
}
|
||||
|
||||
return GetDataImpl(cx);
|
||||
}
|
||||
|
||||
static void CleanupAllThreads();
|
||||
|
||||
~XPCPerThreadData();
|
||||
|
@ -3143,8 +3155,12 @@ public:
|
|||
{mWrappedNativeThreadsafetyReportDepth = 0;}
|
||||
#endif
|
||||
|
||||
static void ShutDown()
|
||||
{sMainJSThread = nsnull; sMainThreadData = nsnull;}
|
||||
|
||||
private:
|
||||
XPCPerThreadData();
|
||||
static XPCPerThreadData* GetDataImpl(JSContext *cx);
|
||||
|
||||
private:
|
||||
XPCJSContextStack* mJSContextStack;
|
||||
|
@ -3171,6 +3187,13 @@ private:
|
|||
static PRLock* gLock;
|
||||
static XPCPerThreadData* gThreads;
|
||||
static PRUintn gTLSIndex;
|
||||
|
||||
// Cached value of cx->thread on the main thread.
|
||||
static void *sMainJSThread;
|
||||
|
||||
// Cached per thread data for the main thread. Only safe to access
|
||||
// if cx->thread == sMainJSThread.
|
||||
static XPCPerThreadData *sMainThreadData;
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
|
@ -3199,8 +3222,8 @@ public:
|
|||
virtual ~nsXPCThreadJSContextStackImpl();
|
||||
|
||||
private:
|
||||
XPCJSContextStack* GetStackForCurrentThread()
|
||||
{XPCPerThreadData* data = XPCPerThreadData::GetData();
|
||||
XPCJSContextStack* GetStackForCurrentThread(JSContext *cx = nsnull)
|
||||
{XPCPerThreadData* data = XPCPerThreadData::GetData(cx);
|
||||
return data ? data->GetJSContextStack() : nsnull;}
|
||||
|
||||
static nsXPCThreadJSContextStackImpl* gXPCThreadJSContextStack;
|
||||
|
|
|
@ -201,6 +201,8 @@ nsJSRuntimeServiceImpl::~nsJSRuntimeServiceImpl() {
|
|||
fprintf(stderr, "nJRSI: destroyed runtime %p\n", (void *)mRuntime);
|
||||
#endif
|
||||
}
|
||||
|
||||
XPCPerThreadData::ShutDown();
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsJSRuntimeServiceImpl,
|
||||
|
@ -257,7 +259,7 @@ nsJSRuntimeServiceImpl::GetRuntime(JSRuntime **runtime)
|
|||
//
|
||||
// We rely on the implementation of NSPR that calls destructors at
|
||||
// the same order of calling PR_NewThreadPrivateIndex.
|
||||
XPCPerThreadData::GetData();
|
||||
XPCPerThreadData::GetData(nsnull);
|
||||
|
||||
mRuntime = JS_NewRuntime(gGCSize);
|
||||
if(!mRuntime)
|
||||
|
|
|
@ -384,7 +384,7 @@ nsXPCThreadJSContextStackImpl::Pop(JSContext * *_retval)
|
|||
NS_IMETHODIMP
|
||||
nsXPCThreadJSContextStackImpl::Push(JSContext * cx)
|
||||
{
|
||||
XPCJSContextStack* myStack = GetStackForCurrentThread();
|
||||
XPCJSContextStack* myStack = GetStackForCurrentThread(cx);
|
||||
|
||||
if(!myStack)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -413,7 +413,7 @@ nsXPCThreadJSContextStackImpl::GetSafeJSContext(JSContext * *aSafeJSContext)
|
|||
NS_IMETHODIMP
|
||||
nsXPCThreadJSContextStackImpl::SetSafeJSContext(JSContext * aSafeJSContext)
|
||||
{
|
||||
XPCJSContextStack* myStack = GetStackForCurrentThread();
|
||||
XPCJSContextStack* myStack = GetStackForCurrentThread(aSafeJSContext);
|
||||
|
||||
if(!myStack)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -423,9 +423,11 @@ nsXPCThreadJSContextStackImpl::SetSafeJSContext(JSContext * aSafeJSContext)
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
PRUintn XPCPerThreadData::gTLSIndex = BAD_TLS_INDEX;
|
||||
PRLock* XPCPerThreadData::gLock = nsnull;
|
||||
XPCPerThreadData* XPCPerThreadData::gThreads = nsnull;
|
||||
PRUintn XPCPerThreadData::gTLSIndex = BAD_TLS_INDEX;
|
||||
PRLock* XPCPerThreadData::gLock = nsnull;
|
||||
XPCPerThreadData* XPCPerThreadData::gThreads = nsnull;
|
||||
XPCPerThreadData *XPCPerThreadData::sMainThreadData = nsnull;
|
||||
void * XPCPerThreadData::sMainJSThread = nsnull;
|
||||
|
||||
static jsuword
|
||||
GetThreadStackLimit()
|
||||
|
@ -559,7 +561,7 @@ void XPCPerThreadData::MarkAutoRootsAfterJSFinalize()
|
|||
|
||||
// static
|
||||
XPCPerThreadData*
|
||||
XPCPerThreadData::GetData()
|
||||
XPCPerThreadData::GetDataImpl(JSContext *cx)
|
||||
{
|
||||
XPCPerThreadData* data;
|
||||
|
||||
|
@ -604,6 +606,14 @@ XPCPerThreadData::GetData()
|
|||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
if(cx && !sMainJSThread && NS_IsMainThread())
|
||||
{
|
||||
sMainJSThread = cx->thread;
|
||||
|
||||
sMainThreadData = data;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ XPCThrower::BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz)
|
|||
nsCOMPtr<nsIException> finalException;
|
||||
nsCOMPtr<nsIException> defaultException;
|
||||
nsXPCException::NewException(sz, rv, nsnull, nsnull, getter_AddRefs(defaultException));
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData();
|
||||
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
|
||||
if(tls)
|
||||
{
|
||||
nsIExceptionManager * exceptionManager = tls->GetExceptionManager();
|
||||
|
|
Загрузка…
Ссылка в новой задаче