Bug 408539 - Storing XPCContext inside JSContext

This commit is contained in:
Igor Bukanov 2008-10-11 19:35:39 +02:00
Родитель df4023c881
Коммит 697a20f3ae
31 изменённых файлов: 235 добавлений и 655 удалений

Просмотреть файл

@ -1202,11 +1202,6 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE)
mDefaultJSOptions = JSOPTION_PRIVATE_IS_NSISUPPORTS | JSOPTION_ANONFUNFIX; mDefaultJSOptions = JSOPTION_PRIVATE_IS_NSISUPPORTS | JSOPTION_ANONFUNFIX;
// Let xpconnect resync its JSContext tracker. We do this before creating
// a new JSContext just in case the heap manager recycles the JSContext
// struct.
nsContentUtils::XPConnect()->SyncJSContexts();
mContext = ::JS_NewContext(aRuntime, gStackSize); mContext = ::JS_NewContext(aRuntime, gStackSize);
if (mContext) { if (mContext) {
::JS_SetContextPrivate(mContext, static_cast<nsIScriptContext *>(this)); ::JS_SetContextPrivate(mContext, static_cast<nsIScriptContext *>(this));

Просмотреть файл

@ -580,11 +580,6 @@ NS_IMETHODIMP nsJSSh::Init()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Let xpconnect resync its JSContext tracker. We do this before creating
// a new JSContext just in case the heap manager recycles the JSContext
// struct.
xpc->SyncJSContexts();
nsCOMPtr<nsIJSRuntimeService> rtsvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); nsCOMPtr<nsIJSRuntimeService> rtsvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
// get the JSRuntime from the runtime svc // get the JSRuntime from the runtime svc
if (!rtsvc) { if (!rtsvc) {
@ -667,7 +662,6 @@ NS_IMETHODIMP nsJSSh::Cleanup()
} }
JS_DestroyContext(mJSContext); JS_DestroyContext(mJSContext);
xpc->SyncJSContexts();
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -338,7 +338,7 @@ struct JSRuntime {
JSCList trapList; JSCList trapList;
JSCList watchPointList; JSCList watchPointList;
/* Client opaque pointer */ /* Client opaque pointers */
void *data; void *data;
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
@ -851,8 +851,9 @@ struct JSContext {
/* Interpreter activation count. */ /* Interpreter activation count. */
uintN interpLevel; uintN interpLevel;
/* Client opaque pointer */ /* Client opaque pointers. */
void *data; void *data;
void *data2;
/* GC and thread-safe state. */ /* GC and thread-safe state. */
JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */ JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */

Просмотреть файл

@ -530,11 +530,7 @@ interface nsIXPConnect : nsISupports
in nsIStackFrame aCaller); in nsIStackFrame aCaller);
/** /**
* XPConnect builds internal objects that parallel, and are one-to-one with, * Deprecated do-nothing function.
* the JSContexts in the JSRuntime. It builds these objects as needed.
* This method tells XPConnect to resynchronize its representations with the
* list of JSContexts currently 'alive' in the JSRuntime. This allows it
* to cleanup any representations of JSContexts that are no longer valid.
*/ */
void syncJSContexts(); void syncJSContexts();

Просмотреть файл

@ -1303,9 +1303,15 @@ nsXPCFunctionThisTranslator::TranslateThis(nsISupports *aInitialThis,
#endif #endif
// ContextCallback calls are chained
static JSContextCallback gOldJSContextCallback;
static JSBool static JSBool
ContextCallback(JSContext *cx, uintN contextOp) ContextCallback(JSContext *cx, uintN contextOp)
{ {
if (gOldJSContextCallback && !gOldJSContextCallback(cx, contextOp))
return JS_FALSE;
if (contextOp == JSCONTEXT_NEW) { if (contextOp == JSCONTEXT_NEW) {
JS_SetErrorReporter(cx, my_ErrorReporter); JS_SetErrorReporter(cx, my_ErrorReporter);
JS_SetVersion(cx, JSVERSION_LATEST); JS_SetVersion(cx, JSVERSION_LATEST);
@ -1357,7 +1363,7 @@ main(int argc, char **argv, char **envp)
return 1; return 1;
} }
JS_SetContextCallback(rt, ContextCallback); gOldJSContextCallback = JS_SetContextCallback(rt, ContextCallback);
cx = JS_NewContext(rt, 8192); cx = JS_NewContext(rt, 8192);
if (!cx) { if (!cx) {
@ -1480,7 +1486,6 @@ main(int argc, char **argv, char **envp)
cxstack = nsnull; cxstack = nsnull;
JS_GC(cx); JS_GC(cx);
JS_DestroyContext(cx); JS_DestroyContext(cx);
xpc->SyncJSContexts();
} // this scopes the nsCOMPtrs } // this scopes the nsCOMPtrs
// no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
rv = NS_ShutdownXPCOM( NULL ); rv = NS_ShutdownXPCOM( NULL );

Просмотреть файл

@ -187,7 +187,7 @@ XPC_XOW_WrapperMoved(JSContext *cx, XPCWrappedNative *innerObj,
XPCWrappedNativeScope *newScope) XPCWrappedNativeScope *newScope)
{ {
typedef WrappedNative2WrapperMap::Link Link; typedef WrappedNative2WrapperMap::Link Link;
XPCJSRuntime *rt = nsXPConnect::GetRuntime(); XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
WrappedNative2WrapperMap *map = innerObj->GetScope()->GetWrapperMap(); WrappedNative2WrapperMap *map = innerObj->GetScope()->GetWrapperMap();
Link *link; Link *link;
@ -471,7 +471,7 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
return JS_TRUE; return JS_TRUE;
} }
XPCJSRuntime *rt = nsXPConnect::GetRuntime(); XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
XPCCallContext ccx(NATIVE_CALLER, cx); XPCCallContext ccx(NATIVE_CALLER, cx);
NS_ENSURE_TRUE(ccx.IsValid(), JS_FALSE); NS_ENSURE_TRUE(ccx.IsValid(), JS_FALSE);

Просмотреть файл

@ -201,9 +201,9 @@ private:
inline inline
xpcFunctionDefiner::xpcFunctionDefiner(JSContext * aJSContext) : xpcFunctionDefiner::xpcFunctionDefiner(JSContext * aJSContext) :
m_Runtime(nsXPConnect::GetRuntime()), m_JSContext(aJSContext) m_Runtime(nsXPConnect::GetRuntimeInstance()), m_JSContext(aJSContext)
{ {
NS_ASSERTION(m_Runtime, "nsXPConnect::GetRuntime() returned null"); NS_ASSERTION(m_Runtime, "nsXPConnect::GetRuntimeInstance() returned null");
NS_ASSERTION(aJSContext, "xpcFunctionDefiner constructor passed a null context"); NS_ASSERTION(aJSContext, "xpcFunctionDefiner constructor passed a null context");
} }

Просмотреть файл

@ -660,7 +660,7 @@ XPC_NW_Finalize(JSContext *cx, JSObject *obj)
{ {
// We must not use obj's private data here since it's likely that it // We must not use obj's private data here since it's likely that it
// has already been finalized. // has already been finalized.
XPCJSRuntime *rt = nsXPConnect::GetRuntime(); XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
{ {
// scoped lock // scoped lock

Просмотреть файл

@ -739,9 +739,7 @@ XPCWrapper::NativeToString(JSContext *cx, XPCWrappedNative *wrappedNative,
{ {
// Check whether toString was overridden in any object along // Check whether toString was overridden in any object along
// the wrapped native's object's prototype chain. // the wrapped native's object's prototype chain.
XPCJSRuntime *rt = nsXPConnect::GetRuntime(); XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
if (!rt)
return JS_FALSE;
jsid id = rt->GetStringID(XPCJSRuntime::IDX_TO_STRING); jsid id = rt->GetStringID(XPCJSRuntime::IDX_TO_STRING);
jsval idAsVal; jsval idAsVal;

Просмотреть файл

@ -53,10 +53,11 @@
#include "nsThreadUtilsInternal.h" #include "nsThreadUtilsInternal.h"
#include "dom_quickstubs.h" #include "dom_quickstubs.h"
NS_IMPL_THREADSAFE_ISUPPORTS3(nsXPConnect, NS_IMPL_THREADSAFE_ISUPPORTS4(nsXPConnect,
nsIXPConnect, nsIXPConnect,
nsISupportsWeakReference, nsISupportsWeakReference,
nsIThreadObserver) nsIThreadObserver,
nsIJSRuntimeService)
nsXPConnect* nsXPConnect::gSelf = nsnull; nsXPConnect* nsXPConnect::gSelf = nsnull;
JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE; JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE;
@ -86,9 +87,7 @@ nsXPConnect::nsXPConnect()
mCycleCollectionContext(nsnull), mCycleCollectionContext(nsnull),
mCycleCollecting(PR_FALSE) mCycleCollecting(PR_FALSE)
{ {
// Ignore the result. If the runtime service is not ready to rumble mRuntime = XPCJSRuntime::newXPCJSRuntime(this);
// then we'll set this up later as needed.
CreateRuntime();
CallGetService(XPC_CONTEXT_STACK_CONTRACTID, &mContextStack); CallGetService(XPC_CONTEXT_STACK_CONTRACTID, &mContextStack);
@ -182,7 +181,8 @@ nsXPConnect::GetXPConnect()
if(!gSelf) if(!gSelf)
return nsnull; return nsnull;
if(!gSelf->mInterfaceInfoManager || if(!gSelf->mRuntime ||
!gSelf->mInterfaceInfoManager ||
!gSelf->mContextStack) !gSelf->mContextStack)
{ {
// ctor failed to create an acceptable instance // ctor failed to create an acceptable instance
@ -298,38 +298,11 @@ nsXPConnect::GetContextStack(nsIThreadJSContextStack** stack,
// static // static
XPCJSRuntime* XPCJSRuntime*
nsXPConnect::GetRuntime(nsXPConnect* xpc /*= nsnull*/) nsXPConnect::GetRuntimeInstance()
{ {
if(!xpc && !(xpc = GetXPConnect())) nsXPConnect* xpc = GetXPConnect();
return nsnull; NS_ASSERTION(xpc, "Must not be called if XPC failed to initialize");
return xpc->GetRuntime();
return xpc->EnsureRuntime() ? xpc->mRuntime : nsnull;
}
// static
nsIJSRuntimeService*
nsXPConnect::GetJSRuntimeService(nsXPConnect* xpc /* = nsnull */)
{
XPCJSRuntime* rt = GetRuntime(xpc);
return rt ? rt->GetJSRuntimeService() : nsnull;
}
// static
XPCContext*
nsXPConnect::GetContext(JSContext* cx, nsXPConnect* xpc /*= nsnull*/)
{
NS_PRECONDITION(cx,"bad param");
XPCJSRuntime* rt = GetRuntime(xpc);
if(!rt)
return nsnull;
if(rt->GetJSRuntime() != JS_GetRuntime(cx))
{
NS_WARNING("XPConnect was passed aJSContext from a foreign JSRuntime!");
return nsnull;
}
return rt->GetXPCContext(cx);
} }
// static // static
@ -342,20 +315,6 @@ nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
return found; return found;
} }
JSBool
nsXPConnect::CreateRuntime()
{
NS_ASSERTION(!mRuntime,"CreateRuntime called but mRuntime already init'd");
nsresult rv;
nsCOMPtr<nsIJSRuntimeService> rtsvc =
do_GetService(XPC_RUNTIME_CONTRACTID, &rv);
if(NS_SUCCEEDED(rv) && rtsvc)
{
mRuntime = XPCJSRuntime::newXPCJSRuntime(this, rtsvc);
}
return nsnull != mRuntime;
}
/***************************************************************************/ /***************************************************************************/
typedef PRBool (*InfoTester)(nsIInterfaceInfoManager* manager, const void* data, typedef PRBool (*InfoTester)(nsIInterfaceInfoManager* manager, const void* data,
@ -443,7 +402,7 @@ XPCCycleCollectGCCallback(JSContext *cx, JSGCStatus status)
// Mark JS objects that are held by XPCOM objects that are in cycles // Mark JS objects that are held by XPCOM objects that are in cycles
// that will not be collected. // that will not be collected.
nsXPConnect::GetRuntime()-> nsXPConnect::GetRuntimeInstance()->
TraceXPConnectRoots(cx->runtime->gcMarkingTracer); TraceXPConnectRoots(cx->runtime->gcMarkingTracer);
} }
else if(status == JSGC_END) else if(status == JSGC_END)
@ -453,13 +412,13 @@ XPCCycleCollectGCCallback(JSContext *cx, JSGCStatus status)
gInCollection = PR_FALSE; gInCollection = PR_FALSE;
gCollected = nsCycleCollector_finishCollection(); gCollected = nsCycleCollector_finishCollection();
} }
nsXPConnect::GetRuntime()->RestoreContextGlobals(); nsXPConnect::GetRuntimeInstance()->RestoreContextGlobals();
} }
PRBool ok = gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE; PRBool ok = gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE;
if(status == JSGC_BEGIN) if(status == JSGC_BEGIN)
nsXPConnect::GetRuntime()->UnsetContextGlobals(); nsXPConnect::GetRuntimeInstance()->UnsetContextGlobals();
return ok; return ok;
} }
@ -606,7 +565,7 @@ nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
nsXPConnect::GetRuntime()->UnsetContextGlobals(); GetRuntime()->UnsetContextGlobals();
PRBool alreadyCollecting = mCycleCollecting; PRBool alreadyCollecting = mCycleCollecting;
mCycleCollecting = PR_TRUE; mCycleCollecting = PR_TRUE;
@ -653,7 +612,7 @@ nsXPConnect::FinishCycleCollection()
mCycleCollectionContext = nsnull; mCycleCollectionContext = nsnull;
mExplainCycleCollectionContext = nsnull; mExplainCycleCollectionContext = nsnull;
nsXPConnect::GetRuntime()->RestoreContextGlobals(); GetRuntime()->RestoreContextGlobals();
} }
#endif #endif
@ -1017,11 +976,10 @@ public:
cb.DescribeNode(RefCounted, refCount); cb.DescribeNode(RefCounted, refCount);
#endif #endif
void* globalObject; void* globalObject = (cx->globalObject)
if(cx->globalObject) ? cx->globalObject
globalObject = cx->globalObject; : nsXPConnect::GetRuntimeInstance()->
else GetUnsetContextGlobal(cx);
globalObject = nsXPConnect::GetRuntime()->GetUnsetContextGlobal(cx);
cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, globalObject); cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, globalObject);
@ -1444,7 +1402,7 @@ nsXPConnect::ReparentScopeAwareWrappers(JSContext *aJSContext,
nsVoidArray wrappersToMove; nsVoidArray wrappersToMove;
{ // scoped lock { // scoped lock
XPCAutoLock lock(oldScope->GetRuntime()->GetMapLock()); XPCAutoLock lock(GetRuntime()->GetMapLock());
Native2WrappedNativeMap *map = oldScope->GetWrappedNativeMap(); Native2WrappedNativeMap *map = oldScope->GetWrappedNativeMap();
wrappersToMove.SizeTo(map->Count()); wrappersToMove.SizeTo(map->Count());
map->Enumerate(MoveableWrapperFinder, &wrappersToMove); map->Enumerate(MoveableWrapperFinder, &wrappersToMove);
@ -1700,13 +1658,10 @@ nsXPConnect::SetPendingException(nsIException * aPendingException)
return NS_OK; return NS_OK;
} }
/* void syncJSContexts (); */
NS_IMETHODIMP NS_IMETHODIMP
nsXPConnect::SyncJSContexts(void) nsXPConnect::SyncJSContexts(void)
{ {
XPCJSRuntime* rt = GetRuntime(this); // Do-nothing compatibility function
if(rt)
rt->SyncXPCContextList();
return NS_OK; return NS_OK;
} }
@ -1716,10 +1671,7 @@ nsXPConnect::SetFunctionThisTranslator(const nsIID & aIID,
nsIXPCFunctionThisTranslator *aTranslator, nsIXPCFunctionThisTranslator *aTranslator,
nsIXPCFunctionThisTranslator **_retval) nsIXPCFunctionThisTranslator **_retval)
{ {
XPCJSRuntime* rt = GetRuntime(this); XPCJSRuntime* rt = GetRuntime();
if(!rt)
return NS_ERROR_UNEXPECTED;
nsIXPCFunctionThisTranslator* old; nsIXPCFunctionThisTranslator* old;
IID2ThisTranslatorMap* map = rt->GetThisTranslatorMap(); IID2ThisTranslatorMap* map = rt->GetThisTranslatorMap();
@ -1741,10 +1693,7 @@ NS_IMETHODIMP
nsXPConnect::GetFunctionThisTranslator(const nsIID & aIID, nsXPConnect::GetFunctionThisTranslator(const nsIID & aIID,
nsIXPCFunctionThisTranslator **_retval) nsIXPCFunctionThisTranslator **_retval)
{ {
XPCJSRuntime* rt = GetRuntime(this); XPCJSRuntime* rt = GetRuntime();
if(!rt)
return NS_ERROR_UNEXPECTED;
nsIXPCFunctionThisTranslator* old; nsIXPCFunctionThisTranslator* old;
IID2ThisTranslatorMap* map = rt->GetThisTranslatorMap(); IID2ThisTranslatorMap* map = rt->GetThisTranslatorMap();
@ -1824,7 +1773,7 @@ nsXPConnect::RestoreWrappedNativePrototype(JSContext * aJSContext,
return UnexpectedFailure(NS_ERROR_INVALID_ARG); return UnexpectedFailure(NS_ERROR_INVALID_ARG);
ClassInfo2WrappedNativeProtoMap* map = scope->GetWrappedNativeProtoMap(); ClassInfo2WrappedNativeProtoMap* map = scope->GetWrappedNativeProtoMap();
XPCLock* lock = scope->GetRuntime()->GetMapLock(); XPCLock* lock = GetRuntime()->GetMapLock();
{ // scoped lock { // scoped lock
XPCAutoLock al(lock); XPCAutoLock al(lock);
@ -2012,8 +1961,7 @@ nsXPConnect::UpdateXOWs(JSContext* aJSContext,
Link* list; Link* list;
{ {
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); XPCAutoLock al(GetRuntime()->GetMapLock());
XPCAutoLock al(rt->GetMapLock());
list = map->FindLink(wn->GetFlatJSObject()); list = map->FindLink(wn->GetFlatJSObject());
} }
@ -2079,7 +2027,6 @@ nsXPConnect::ReleaseJSContext(JSContext * aJSContext, PRBool noGC)
JS_DestroyContextNoGC(aJSContext); JS_DestroyContextNoGC(aJSContext);
else else
JS_DestroyContext(aJSContext); JS_DestroyContext(aJSContext);
SyncJSContexts();
return NS_OK; return NS_OK;
} }
@ -2258,15 +2205,7 @@ nsXPConnect::FlagSystemFilenamePrefix(const char *aFilenamePrefix,
{ {
NS_PRECONDITION(aFilenamePrefix, "bad param"); NS_PRECONDITION(aFilenamePrefix, "bad param");
nsIJSRuntimeService* rtsvc = nsXPConnect::GetJSRuntimeService(); JSRuntime* rt = GetRuntime()->GetJSRuntime();;
if(!rtsvc)
return NS_ERROR_NOT_INITIALIZED;
JSRuntime* rt;
nsresult rv = rtsvc->GetRuntime(&rt);
if(NS_FAILED(rv))
return rv;
uint32 flags = JSFILENAME_SYSTEM; uint32 flags = JSFILENAME_SYSTEM;
if(aWantNativeWrappers) if(aWantNativeWrappers)
flags |= JSFILENAME_PROTECTED; flags |= JSFILENAME_PROTECTED;
@ -2334,6 +2273,42 @@ nsXPConnect::DefineDOMQuickStubs(JSContext * cx,
interfaceCount, interfaceArray); interfaceCount, interfaceArray);
} }
/* attribute JSRuntime runtime; */
NS_IMETHODIMP
nsXPConnect::GetRuntime(JSRuntime **runtime)
{
if(!runtime)
return NS_ERROR_NULL_POINTER;
*runtime = GetRuntime()->GetJSRuntime();
return NS_OK;
}
/* attribute nsIXPCScriptable backstagePass; */
NS_IMETHODIMP
nsXPConnect::GetBackstagePass(nsIXPCScriptable **bsp)
{
if(!mBackstagePass) {
#ifndef XPCONNECT_STANDALONE
nsCOMPtr<nsIPrincipal> sysprin;
nsCOMPtr<nsIScriptSecurityManager> secman =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
if(!secman)
return NS_ERROR_NOT_AVAILABLE;
if(NS_FAILED(secman->GetSystemPrincipal(getter_AddRefs(sysprin))))
return NS_ERROR_NOT_AVAILABLE;
mBackstagePass = new BackstagePass(sysprin);
#else
mBackstagePass = new BackstagePass();
#endif
if(!mBackstagePass)
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*bsp = mBackstagePass);
return NS_OK;
}
/* These are here to be callable from a debugger */ /* These are here to be callable from a debugger */
JS_BEGIN_EXTERN_C JS_BEGIN_EXTERN_C
JS_EXPORT_API(void) DumpJSStack() JS_EXPORT_API(void) DumpJSStack()

Просмотреть файл

@ -124,20 +124,7 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
mContextPopRequired = JS_TRUE; mContextPopRequired = JS_TRUE;
} }
// Try to get the JSContext -> XPCContext mapping from the cache. mXPCContext = XPCContext::GetXPCContext(mJSContext);
// FWIW... quicky tests show this hitting ~ 95% of the time.
// That is a *lot* of locking we can skip in nsXPConnect::GetContext.
mXPCContext = mThreadData->GetRecentXPCContext(mJSContext);
if(!mXPCContext)
{
if(!(mXPCContext = nsXPConnect::GetContext(mJSContext, mXPC)))
return;
// Fill the cache.
mThreadData->SetRecentContext(mJSContext, mXPCContext);
}
mPrevCallerLanguage = mXPCContext->SetCallingLangType(mCallerLanguage); mPrevCallerLanguage = mXPCContext->SetCallingLangType(mCallerLanguage);
// hook into call context chain for our thread // hook into call context chain for our thread
@ -352,7 +339,6 @@ XPCCallContext::~XPCCallContext()
"JSContext still in threadjscontextstack!"); "JSContext still in threadjscontextstack!");
JS_DestroyContext(mJSContext); JS_DestroyContext(mJSContext);
mXPC->SyncJSContexts();
} }
else else
{ {

Просмотреть файл

@ -3897,7 +3897,7 @@ nsXPCComponents::NewResolve(nsIXPConnectWrappedNative *wrapper,
jsval id, PRUint32 flags, jsval id, PRUint32 flags,
JSObject * *objp, PRBool *_retval) JSObject * *objp, PRBool *_retval)
{ {
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(!rt) if(!rt)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -3928,7 +3928,7 @@ nsXPCComponents::GetProperty(nsIXPConnectWrappedNative *wrapper,
JSContext * cx, JSObject * obj, JSContext * cx, JSObject * obj,
jsval id, jsval * vp, PRBool *_retval) jsval id, jsval * vp, PRBool *_retval)
{ {
XPCContext* xpcc = nsXPConnect::GetContext(cx); XPCContext* xpcc = XPCContext::GetXPCContext(cx);
if(!xpcc) if(!xpcc)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -3963,7 +3963,7 @@ nsXPCComponents::SetProperty(nsIXPConnectWrappedNative *wrapper,
JSContext * cx, JSObject * obj, jsval id, JSContext * cx, JSObject * obj, jsval id,
jsval * vp, PRBool *_retval) jsval * vp, PRBool *_retval)
{ {
XPCContext* xpcc = nsXPConnect::GetContext(cx); XPCContext* xpcc = XPCContext::GetXPCContext(cx);
if(!xpcc) if(!xpcc)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

Просмотреть файл

@ -44,19 +44,6 @@
/***************************************************************************/ /***************************************************************************/
// static
XPCContext*
XPCContext::newXPCContext(XPCJSRuntime* aRuntime,
JSContext* aJSContext)
{
NS_PRECONDITION(aRuntime,"bad param");
NS_PRECONDITION(aJSContext,"bad param");
NS_ASSERTION(JS_GetRuntime(aJSContext) == aRuntime->GetJSRuntime(),
"XPConnect can not be used on multiple JSRuntimes!");
return new XPCContext(aRuntime, aJSContext);
}
XPCContext::XPCContext(XPCJSRuntime* aRuntime, XPCContext::XPCContext(XPCJSRuntime* aRuntime,
JSContext* aJSContext) JSContext* aJSContext)
: mRuntime(aRuntime), : mRuntime(aRuntime),
@ -66,19 +53,23 @@ XPCContext::XPCContext(XPCJSRuntime* aRuntime,
mSecurityManager(nsnull), mSecurityManager(nsnull),
mException(nsnull), mException(nsnull),
mCallingLangType(LANG_UNKNOWN), mCallingLangType(LANG_UNKNOWN),
mSecurityManagerFlags(0), mSecurityManagerFlags(0)
mMarked((JSPackedBool) JS_FALSE)
{ {
MOZ_COUNT_CTOR(XPCContext); MOZ_COUNT_CTOR(XPCContext);
PR_INIT_CLIST(&mScopes); PR_INIT_CLIST(&mScopes);
for(const char** p = XPC_ARG_FORMATTER_FORMAT_STRINGS; *p; p++) for(const char** p = XPC_ARG_FORMATTER_FORMAT_STRINGS; *p; p++)
JS_AddArgumentFormatter(mJSContext, *p, XPC_JSArgumentFormatter); JS_AddArgumentFormatter(mJSContext, *p, XPC_JSArgumentFormatter);
NS_ASSERTION(!mJSContext->data2, "Must be null");
mJSContext->data2 = this;
} }
XPCContext::~XPCContext() XPCContext::~XPCContext()
{ {
MOZ_COUNT_DTOR(XPCContext); MOZ_COUNT_DTOR(XPCContext);
NS_ASSERTION(mJSContext->data2 == this, "Must match this");
mJSContext->data2 = nsnull;
NS_IF_RELEASE(mException); NS_IF_RELEASE(mException);
NS_IF_RELEASE(mSecurityManager); NS_IF_RELEASE(mSecurityManager);

Просмотреть файл

@ -1469,20 +1469,16 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx,
found) found)
{ {
// lets try to build a wrapper around the JSObject // lets try to build a wrapper around the JSObject
XPCContext* xpcc; nsXPCWrappedJS* jswrapper;
if(nsnull != (xpcc = nsXPConnect::GetContext(cx))) nsresult rv =
{ nsXPCWrappedJS::GetNewOrUsed(ccx, obj,
nsXPCWrappedJS* jswrapper; NS_GET_IID(nsIException),
nsresult rv = nsnull, &jswrapper);
nsXPCWrappedJS::GetNewOrUsed(ccx, obj, if(NS_FAILED(rv))
NS_GET_IID(nsIException), return rv;
nsnull, &jswrapper); *exceptn = reinterpret_cast<nsIException*>
if(NS_FAILED(rv)) (jswrapper);
return rv; return NS_OK;
*exceptn = reinterpret_cast<nsIException*>
(jswrapper);
return NS_OK;
}
} }

Просмотреть файл

@ -167,7 +167,7 @@ void
nsXPCException::SetThrownJSVal(jsval v) nsXPCException::SetThrownJSVal(jsval v)
{ {
mThrownJSVal = JSVAL_IS_TRACEABLE(v) mThrownJSVal = JSVAL_IS_TRACEABLE(v)
? new XPCTraceableVariant(nsXPConnect::GetRuntime(), v) ? new XPCTraceableVariant(nsXPConnect::GetRuntimeInstance(), v)
: new XPCVariant(v); : new XPCVariant(v);
} }

Просмотреть файл

@ -74,7 +74,6 @@ class XPCJSObjectHolder;
class JSObject2WrappedJSMap; class JSObject2WrappedJSMap;
class Native2WrappedNativeMap; class Native2WrappedNativeMap;
class IID2WrappedJSClassMap; class IID2WrappedJSClassMap;
class JSContext2XPCContextMap;
class IID2NativeInterfaceMap; class IID2NativeInterfaceMap;
class ClassInfo2NativeSetMap; class ClassInfo2NativeSetMap;
class ClassInfo2WrappedNativeProtoMap; class ClassInfo2WrappedNativeProtoMap;

Просмотреть файл

@ -731,11 +731,7 @@ xpc_NewSystemInheritingJSObject(JSContext *cx, JSClass *clasp, JSObject *proto,
inline jsval inline jsval
GetRTStringByIndex(JSContext *cx, uintN index) GetRTStringByIndex(JSContext *cx, uintN index)
{ {
XPCJSRuntime *rt = nsXPConnect::GetRuntime(); XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
if (!rt)
return JSVAL_VOID;
return ID_TO_VALUE(rt->GetStringID(index)); return ID_TO_VALUE(rt->GetStringID(index));
} }

Просмотреть файл

@ -795,7 +795,7 @@ nsJSCID::CreateInstance(nsISupports **_retval)
// Do the security check if necessary // Do the security check if necessary
XPCContext* xpcc = nsXPConnect::GetContext(cx); XPCContext* xpcc = XPCContext::GetXPCContext(cx);
nsIXPCSecurityManager* sm; nsIXPCSecurityManager* sm;
sm = xpcc->GetAppropriateSecurityManager( sm = xpcc->GetAppropriateSecurityManager(
@ -868,7 +868,7 @@ nsJSCID::GetService(nsISupports **_retval)
// Do the security check if necessary // Do the security check if necessary
XPCContext* xpcc = nsXPConnect::GetContext(cx); XPCContext* xpcc = XPCContext::GetXPCContext(cx);
nsIXPCSecurityManager* sm; nsIXPCSecurityManager* sm;
sm = xpcc->GetAppropriateSecurityManager( sm = xpcc->GetAppropriateSecurityManager(
@ -914,7 +914,7 @@ nsJSCID::Construct(nsIXPConnectWrappedNative *wrapper,
PRUint32 argc, jsval * argv, jsval * vp, PRUint32 argc, jsval * argv, jsval * vp,
PRBool *_retval) PRBool *_retval)
{ {
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(!rt) if(!rt)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

Просмотреть файл

@ -70,12 +70,6 @@ const char* XPCJSRuntime::mStrings[] = {
/***************************************************************************/ /***************************************************************************/
// ContextCallback calls are chained
static JSContextCallback gOldJSContextCallback;
// GCCallback calls are chained
static JSGCCallback gOldJSGCCallback;
// data holder class for the enumerator callback below // data holder class for the enumerator callback below
struct JSDyingJSObjectData struct JSDyingJSObjectData
{ {
@ -233,24 +227,20 @@ DetachedWrappedNativeProtoMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
static JSBool static JSBool
ContextCallback(JSContext *cx, uintN operation) ContextCallback(JSContext *cx, uintN operation)
{ {
XPCJSRuntime* self = nsXPConnect::GetRuntime(); XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
if (self) if(self)
{ {
if (operation == JSCONTEXT_NEW) if(operation == JSCONTEXT_NEW)
{ {
// Set the limits on the native and script stack space. if(!self->OnJSContextNew(cx))
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx); return JS_FALSE;
if(tls) }
{ else if(operation == JSCONTEXT_DESTROY)
JS_SetThreadStackLimit(cx, tls->GetStackLimit()); {
} delete XPCContext::GetXPCContext(cx);
JS_SetScriptStackQuota(cx, 100*1024*1024);
} }
} }
return JS_TRUE;
return gOldJSContextCallback
? gOldJSContextCallback(cx, operation)
: JS_TRUE;
} }
struct ObjectHolder : public JSDHashEntryHdr struct ObjectHolder : public JSDHashEntryHdr
@ -521,7 +511,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
{ {
nsVoidArray* dyingWrappedJSArray; nsVoidArray* dyingWrappedJSArray;
XPCJSRuntime* self = nsXPConnect::GetRuntime(); XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
if(self) if(self)
{ {
switch(status) switch(status)
@ -827,8 +817,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
} }
} }
// always chain to old GCCallback if non-null. return JS_TRUE;
return gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE;
} }
/***************************************************************************/ /***************************************************************************/
@ -890,13 +879,6 @@ XPCJSRuntime::~XPCJSRuntime()
#endif #endif
// clean up and destroy maps... // clean up and destroy maps...
if(mContextMap)
{
PurgeXPCContextList();
delete mContextMap;
}
if(mWrappedJSMap) if(mWrappedJSMap)
{ {
#ifdef XPC_DUMP_AT_SHUTDOWN #ifdef XPC_DUMP_AT_SHUTDOWN
@ -950,7 +932,6 @@ XPCJSRuntime::~XPCJSRuntime()
if(mMapLock) if(mMapLock)
XPCAutoLock::DestroyLock(mMapLock); XPCAutoLock::DestroyLock(mMapLock);
NS_IF_RELEASE(mJSRuntimeService);
if(mThisTranslatorMap) if(mThisTranslatorMap)
{ {
@ -1019,9 +1000,6 @@ XPCJSRuntime::~XPCJSRuntime()
XPCConvert::RemoveXPCOMUCStringFinalizer(); XPCConvert::RemoveXPCOMUCStringFinalizer();
gOldJSGCCallback = NULL;
gOldJSContextCallback = NULL;
if(mJSHolders.ops) if(mJSHolders.ops)
{ {
JS_DHashTableFinish(&mJSHolders); JS_DHashTableFinish(&mJSHolders);
@ -1032,14 +1010,22 @@ XPCJSRuntime::~XPCJSRuntime()
JS_DHashTableFinish(&mClearedGlobalObjects); JS_DHashTableFinish(&mClearedGlobalObjects);
mClearedGlobalObjects.ops = nsnull; mClearedGlobalObjects.ops = nsnull;
} }
if(mJSRuntime)
{
JS_DestroyRuntime(mJSRuntime);
JS_ShutDown();
#ifdef DEBUG_shaver_off
fprintf(stderr, "nJRSI: destroyed runtime %p\n", (void *)mJSRuntime);
#endif
}
XPCPerThreadData::ShutDown();
} }
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect, XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
nsIJSRuntimeService* aJSRuntimeService)
: mXPConnect(aXPConnect), : mXPConnect(aXPConnect),
mJSRuntime(nsnull), mJSRuntime(nsnull),
mJSRuntimeService(aJSRuntimeService),
mContextMap(JSContext2XPCContextMap::newMap(XPC_CONTEXT_MAP_SIZE)),
mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)), mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)),
mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_SIZE)), mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_SIZE)),
mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_SIZE)), mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_SIZE)),
@ -1068,18 +1054,35 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect,
// these jsids filled in later when we have a JSContext to work with. // these jsids filled in later when we have a JSContext to work with.
mStrIDs[0] = 0; mStrIDs[0] = 0;
if(mJSRuntimeService) // Call XPCPerThreadData::GetData to initialize
{ // XPCPerThreadData::gTLSIndex before initializing
NS_ADDREF(mJSRuntimeService); // JSRuntime::threadTPIndex in JS_NewRuntime.
mJSRuntimeService->GetRuntime(&mJSRuntime); //
} // XPConnect uses a thread local storage (XPCPerThreadData) indexed by
// XPCPerThreadData::gTLSIndex, and SpiderMonkey GC uses a thread local
// storage indexed by JSRuntime::threadTPIndex.
//
// The destructor for XPCPerThreadData::gTLSIndex may access
// thread local storage indexed by JSRuntime::threadTPIndex.
// Thus, the destructor for JSRuntime::threadTPIndex must be called
// later than the one for XPCPerThreadData::gTLSIndex.
//
// We rely on the implementation of NSPR that calls destructors at
// the same order of calling PR_NewThreadPrivateIndex.
XPCPerThreadData::GetData(nsnull);
NS_ASSERTION(!gOldJSGCCallback, "XPCJSRuntime created more than once"); mJSRuntime = JS_NewRuntime(32L * 1024L * 1024L); // pref ?
if(mJSRuntime) if(mJSRuntime)
{ {
gOldJSContextCallback = JS_SetContextCallback(mJSRuntime, // Unconstrain the runtime's threshold on nominal heap size, to avoid
ContextCallback); // triggering GC too often if operating continuously near an arbitrary
gOldJSGCCallback = JS_SetGCCallbackRT(mJSRuntime, GCCallback); // finite threshold (0xffffffff is infinity for uint32 parameters).
// This leaves the maximum-JS_malloc-bytes threshold still in effect
// to cause period, and we hope hygienic, last-ditch GCs from within
// the GC's allocator.
JS_SetGCParameter(mJSRuntime, JSGC_MAX_BYTES, 0xffffffff);
JS_SetContextCallback(mJSRuntime, ContextCallback);
JS_SetGCCallbackRT(mJSRuntime, GCCallback);
JS_SetExtraGCRoots(mJSRuntime, TraceJS, this); JS_SetExtraGCRoots(mJSRuntime, TraceJS, this);
} }
@ -1099,20 +1102,14 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect,
// static // static
XPCJSRuntime* XPCJSRuntime*
XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect, XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect)
nsIJSRuntimeService* aJSRuntimeService)
{ {
NS_PRECONDITION(aXPConnect,"bad param"); NS_PRECONDITION(aXPConnect,"bad param");
NS_PRECONDITION(aJSRuntimeService,"bad param");
XPCJSRuntime* self; XPCJSRuntime* self = new XPCJSRuntime(aXPConnect);
self = new XPCJSRuntime(aXPConnect,
aJSRuntimeService);
if(self && if(self &&
self->GetJSRuntime() && self->GetJSRuntime() &&
self->GetContextMap() &&
self->GetWrappedJSMap() && self->GetWrappedJSMap() &&
self->GetWrappedJSClassMap() && self->GetWrappedJSClassMap() &&
self->GetIID2NativeInterfaceMap() && self->GetIID2NativeInterfaceMap() &&
@ -1130,125 +1127,39 @@ XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect,
return nsnull; return nsnull;
} }
XPCContext* JSBool
XPCJSRuntime::GetXPCContext(JSContext* cx) XPCJSRuntime::OnJSContextNew(JSContext *cx)
{ {
XPCContext* xpcc; // if it is our first context then we need to generate our string ids
JSBool ok = JS_TRUE;
// find it in the map. if(!mStrIDs[0])
{ // scoped lock
XPCAutoLock lock(GetMapLock());
xpcc = mContextMap->Find(cx);
}
// else resync with the JSRuntime's JSContext list and see if it is found
if(!xpcc)
xpcc = SyncXPCContextList(cx);
return xpcc;
}
static JSDHashOperator
SweepContextsCB(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32 number, void *arg)
{
XPCContext* xpcc = ((JSContext2XPCContextMap::Entry*)hdr)->value;
if(xpcc->IsMarked())
{ {
xpcc->Unmark(); JSAutoRequest ar(cx);
return JS_DHASH_NEXT; for(uintN i = 0; i < IDX_TOTAL_COUNT; i++)
{
JSString* str = JS_InternString(cx, mStrings[i]);
if(!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &mStrIDs[i]))
{
mStrIDs[0] = 0;
ok = JS_FALSE;
break;
}
mStrJSVals[i] = STRING_TO_JSVAL(str);
}
} }
if (!ok)
// this XPCContext represents a dead JSContext - delete it return JS_FALSE;
delete xpcc;
return JS_DHASH_REMOVE;
}
XPCContext*
XPCJSRuntime::SyncXPCContextList(JSContext* cx /* = nsnull */)
{
// hold the map lock through this whole thing
XPCAutoLock lock(GetMapLock());
XPCContext* found = nsnull;
// add XPCContexts that represent any JSContexts we have not seen before
JSContext *cur, *iter = nsnull;
while(nsnull != (cur = JS_ContextIterator(mJSRuntime, &iter)))
{
XPCContext* xpcc = mContextMap->Find(cur);
if(!xpcc)
{
xpcc = XPCContext::newXPCContext(this, cur);
if(xpcc)
mContextMap->Add(xpcc);
}
if(xpcc)
{
xpcc->Mark();
}
// if it is our first context then we need to generate our string ids
if(!mStrIDs[0])
{
JSAutoRequest ar(cur);
GenerateStringIDs(cur);
}
if(cx && cx == cur)
found = xpcc;
}
// get rid of any XPCContexts that represent dead JSContexts
mContextMap->Enumerate(SweepContextsCB, 0);
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx); XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
if(tls) if(!tls)
{ return JS_FALSE;
if(found)
tls->SetRecentContext(cx, found);
else
tls->ClearRecentContext();
}
return found; XPCContext* xpc = new XPCContext(this, cx);
} if (!xpc)
return JS_FALSE;
JS_SetThreadStackLimit(cx, tls->GetStackLimit());
static JSDHashOperator JS_SetScriptStackQuota(cx, 100*1024*1024);
PurgeContextsCB(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32 number, void *arg)
{
delete ((JSContext2XPCContextMap::Entry*)hdr)->value;
return JS_DHASH_REMOVE;
}
void
XPCJSRuntime::PurgeXPCContextList()
{
// hold the map lock through this whole thing
XPCAutoLock lock(GetMapLock());
// get rid of all XPCContexts
mContextMap->Enumerate(PurgeContextsCB, nsnull);
}
JSBool
XPCJSRuntime::GenerateStringIDs(JSContext* cx)
{
NS_PRECONDITION(!mStrIDs[0],"string ids generated twice!");
for(uintN i = 0; i < IDX_TOTAL_COUNT; i++)
{
JSString* str = JS_InternString(cx, mStrings[i]);
if(!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &mStrIDs[i]))
{
mStrIDs[0] = 0;
return JS_FALSE;
}
mStrJSVals[i] = STRING_TO_JSVAL(str);
}
return JS_TRUE; return JS_TRUE;
} }
@ -1271,13 +1182,6 @@ XPCJSRuntime::DeferredRelease(nsISupports* obj)
#ifdef DEBUG #ifdef DEBUG
static JSDHashOperator static JSDHashOperator
ContextMapDumpEnumerator(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32 number, void *arg)
{
((JSContext2XPCContextMap::Entry*)hdr)->value->DebugDump(*(PRInt16*)arg);
return JS_DHASH_NEXT;
}
static JSDHashOperator
WrappedJSClassMapDumpEnumerator(JSDHashTable *table, JSDHashEntryHdr *hdr, WrappedJSClassMapDumpEnumerator(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32 number, void *arg) uint32 number, void *arg)
{ {
@ -1310,19 +1214,23 @@ XPCJSRuntime::DebugDump(PRInt16 depth)
XPC_LOG_ALWAYS(("mXPConnect @ %x", mXPConnect)); XPC_LOG_ALWAYS(("mXPConnect @ %x", mXPConnect));
XPC_LOG_ALWAYS(("mJSRuntime @ %x", mJSRuntime)); XPC_LOG_ALWAYS(("mJSRuntime @ %x", mJSRuntime));
XPC_LOG_ALWAYS(("mMapLock @ %x", mMapLock)); XPC_LOG_ALWAYS(("mMapLock @ %x", mMapLock));
XPC_LOG_ALWAYS(("mJSRuntimeService @ %x", mJSRuntimeService));
XPC_LOG_ALWAYS(("mWrappedJSToReleaseArray @ %x with %d wrappers(s)", \ XPC_LOG_ALWAYS(("mWrappedJSToReleaseArray @ %x with %d wrappers(s)", \
&mWrappedJSToReleaseArray, &mWrappedJSToReleaseArray,
mWrappedJSToReleaseArray.Count())); mWrappedJSToReleaseArray.Count()));
XPC_LOG_ALWAYS(("mContextMap @ %x with %d context(s)", \ int cxCount = 0;
mContextMap, mContextMap ? mContextMap->Count() : 0)); JSContext* iter = nsnull;
// iterate contexts... while(JS_ContextIterator(mJSRuntime, &iter))
if(depth && mContextMap && mContextMap->Count()) ++cxCount;
XPC_LOG_ALWAYS(("%d JS context(s)", cxCount));
iter = nsnull;
while(JS_ContextIterator(mJSRuntime, &iter))
{ {
XPCContext *xpc = XPCContext::GetXPCContext(iter);
XPC_LOG_INDENT(); XPC_LOG_INDENT();
mContextMap->Enumerate(ContextMapDumpEnumerator, &depth); xpc->DebugDump(depth);
XPC_LOG_OUTDENT(); XPC_LOG_OUTDENT();
} }

Просмотреть файл

@ -120,33 +120,6 @@ HashNativeKey(JSDHashTable *table, const void *key)
return h; return h;
} }
/***************************************************************************/
// implement JSContext2XPCContextMap...
// static
JSContext2XPCContextMap*
JSContext2XPCContextMap::newMap(int size)
{
JSContext2XPCContextMap* map = new JSContext2XPCContextMap(size);
if(map && map->mTable)
return map;
delete map;
return nsnull;
}
JSContext2XPCContextMap::JSContext2XPCContextMap(int size)
{
mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
sizeof(Entry), size);
}
JSContext2XPCContextMap::~JSContext2XPCContextMap()
{
if(mTable)
JS_DHashTableDestroy(mTable);
}
/***************************************************************************/ /***************************************************************************/
// implement JSObject2WrappedJSMap... // implement JSObject2WrappedJSMap...

Просмотреть файл

@ -53,60 +53,6 @@
// no virtuals in the maps - all the common stuff inlined // no virtuals in the maps - all the common stuff inlined
// templates could be used to good effect here. // templates could be used to good effect here.
class JSContext2XPCContextMap
{
public:
struct Entry : public JSDHashEntryHdr
{
JSContext* key;
XPCContext* value;
};
static JSContext2XPCContextMap* newMap(int size);
inline XPCContext* Find(JSContext* cx)
{
NS_PRECONDITION(cx,"bad param");
Entry* entry = (Entry*)
JS_DHashTableOperate(mTable, cx, JS_DHASH_LOOKUP);
if(JS_DHASH_ENTRY_IS_FREE(entry))
return nsnull;
return entry->value;
}
inline XPCContext* Add(XPCContext* xpcc)
{
NS_PRECONDITION(xpcc,"bad param");
JSContext* cx = xpcc->GetJSContext();
Entry* entry = (Entry*)
JS_DHashTableOperate(mTable, cx, JS_DHASH_ADD);
if(!entry)
return nsnull;
if(entry->key)
return entry->value;
entry->key = cx;
entry->value = xpcc;
return xpcc;
}
inline void Remove(XPCContext* xpcc)
{
NS_PRECONDITION(xpcc,"bad param");
JS_DHashTableOperate(mTable, xpcc->GetJSContext(), JS_DHASH_REMOVE);
}
inline uint32 Count() {return mTable->entryCount;}
inline uint32 Enumerate(JSDHashEnumerator f, void *arg)
{return JS_DHashTableEnumerate(mTable, f, arg);}
~JSContext2XPCContextMap();
private:
JSContext2XPCContextMap(); // no implementation
JSContext2XPCContextMap(int size);
private:
JSDHashTable *mTable;
};
/*************************/ /*************************/
class JSObject2WrappedJSMap class JSObject2WrappedJSMap

Просмотреть файл

@ -67,7 +67,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCException)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCJSContextStackIterator) NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCJSContextStackIterator)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect, nsXPConnect::GetSingleton) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect, nsXPConnect::GetSingleton)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIJSContextStack, nsXPCThreadJSContextStackImpl::GetSingleton) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIJSContextStack, nsXPCThreadJSContextStackImpl::GetSingleton)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIJSRuntimeService, nsJSRuntimeServiceImpl::GetSingleton)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptError) NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptError)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCComponents_Interfaces) NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCComponents_Interfaces)
@ -86,7 +85,7 @@ static const nsModuleComponentInfo components[] = {
{nsnull, NS_XPCONNECT_CID, XPC_XPCONNECT_CONTRACTID, nsIXPConnectConstructor }, {nsnull, NS_XPCONNECT_CID, XPC_XPCONNECT_CONTRACTID, nsIXPConnectConstructor },
{nsnull, NS_XPC_THREAD_JSCONTEXT_STACK_CID, XPC_CONTEXT_STACK_CONTRACTID, nsIJSContextStackConstructor }, {nsnull, NS_XPC_THREAD_JSCONTEXT_STACK_CID, XPC_CONTEXT_STACK_CONTRACTID, nsIJSContextStackConstructor },
{nsnull, NS_XPCEXCEPTION_CID, XPC_EXCEPTION_CONTRACTID, nsXPCExceptionConstructor, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(nsXPCException), nsnull, &NS_CLASSINFO_NAME(nsXPCException), nsIClassInfo::DOM_OBJECT }, {nsnull, NS_XPCEXCEPTION_CID, XPC_EXCEPTION_CONTRACTID, nsXPCExceptionConstructor, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(nsXPCException), nsnull, &NS_CLASSINFO_NAME(nsXPCException), nsIClassInfo::DOM_OBJECT },
{nsnull, NS_JS_RUNTIME_SERVICE_CID, XPC_RUNTIME_CONTRACTID, nsIJSRuntimeServiceConstructor}, {nsnull, NS_JS_RUNTIME_SERVICE_CID, XPC_RUNTIME_CONTRACTID, nsIXPConnectConstructor},
{NS_SCRIPTERROR_CLASSNAME, NS_SCRIPTERROR_CID, NS_SCRIPTERROR_CONTRACTID, nsScriptErrorConstructor }, {NS_SCRIPTERROR_CLASSNAME, NS_SCRIPTERROR_CID, NS_SCRIPTERROR_CONTRACTID, nsScriptErrorConstructor },
{nsnull, SCRIPTABLE_INTERFACES_CID, NS_SCRIPTABLE_INTERFACES_CONTRACTID, nsXPCComponents_InterfacesConstructor, 0, 0, 0, 0, 0, 0, nsIClassInfo::THREADSAFE }, {nsnull, SCRIPTABLE_INTERFACES_CID, NS_SCRIPTABLE_INTERFACES_CONTRACTID, nsXPCComponents_InterfacesConstructor, 0, 0, 0, 0, 0, 0, nsIClassInfo::THREADSAFE },
{nsnull, XPCVARIANT_CID, XPCVARIANT_CONTRACTID, nsnull, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(XPCVariant), nsnull, &NS_CLASSINFO_NAME(XPCVariant)}, {nsnull, XPCVARIANT_CID, XPCVARIANT_CONTRACTID, nsnull, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(XPCVariant), nsnull, &NS_CLASSINFO_NAME(XPCVariant)},
@ -115,7 +114,6 @@ xpcModuleCtor(nsIModule* self)
nsXPCException::InitStatics(); nsXPCException::InitStatics();
XPCWrappedNativeScope::InitStatics(); XPCWrappedNativeScope::InitStatics();
XPCPerThreadData::InitStatics(); XPCPerThreadData::InitStatics();
nsJSRuntimeServiceImpl::InitStatics();
nsXPCThreadJSContextStackImpl::InitStatics(); nsXPCThreadJSContextStackImpl::InitStatics();
#ifdef XPC_IDISPATCH_SUPPORT #ifdef XPC_IDISPATCH_SUPPORT
@ -131,7 +129,6 @@ xpcModuleDtor(nsIModule* self)
// Release our singletons // Release our singletons
nsXPConnect::ReleaseXPConnectSingleton(); nsXPConnect::ReleaseXPConnectSingleton();
nsXPCThreadJSContextStackImpl::FreeSingleton(); nsXPCThreadJSContextStackImpl::FreeSingleton();
nsJSRuntimeServiceImpl::FreeSingleton();
xpc_DestroyJSxIDClassObjects(); xpc_DestroyJSxIDClassObjects();
#ifdef XPC_IDISPATCH_SUPPORT #ifdef XPC_IDISPATCH_SUPPORT
nsDispatchSupport::FreeSingleton(); nsDispatchSupport::FreeSingleton();

Просмотреть файл

@ -442,25 +442,30 @@ private:
const PRBool OBJ_IS_GLOBAL = PR_TRUE; const PRBool OBJ_IS_GLOBAL = PR_TRUE;
const PRBool OBJ_IS_NOT_GLOBAL = PR_FALSE; const PRBool OBJ_IS_NOT_GLOBAL = PR_FALSE;
#define NS_JS_RUNTIME_SERVICE_CID \
{0xb5e65b52, 0x1dd1, 0x11b2, \
{ 0xae, 0x8f, 0xf0, 0x92, 0x8e, 0xd8, 0x84, 0x82 }}
class nsXPConnect : public nsIXPConnect, class nsXPConnect : public nsIXPConnect,
public nsIThreadObserver, public nsIThreadObserver,
public nsSupportsWeakReference, public nsSupportsWeakReference,
public nsCycleCollectionJSRuntime, public nsCycleCollectionJSRuntime,
public nsCycleCollectionParticipant public nsCycleCollectionParticipant,
public nsIJSRuntimeService
{ {
public: public:
// all the interface method declarations... // all the interface method declarations...
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIXPCONNECT NS_DECL_NSIXPCONNECT
NS_DECL_NSITHREADOBSERVER NS_DECL_NSITHREADOBSERVER
NS_DECL_NSIJSRUNTIMESERVICE
// non-interface implementation // non-interface implementation
public: public:
// These get non-addref'd pointers // These get non-addref'd pointers
static nsXPConnect* GetXPConnect(); static nsXPConnect* GetXPConnect();
static XPCJSRuntime* GetRuntime(nsXPConnect* xpc = nsnull); static XPCJSRuntime* GetRuntimeInstance();
static XPCContext* GetContext(JSContext* cx, nsXPConnect* xpc = nsnull); XPCJSRuntime* GetRuntime() {return mRuntime;}
static nsIJSRuntimeService* GetJSRuntimeService(nsXPConnect* xpc = nsnull);
// Gets addref'd pointer // Gets addref'd pointer
static nsresult GetInterfaceInfoManager(nsIInterfaceInfoSuperManager** iim, static nsresult GetInterfaceInfoManager(nsIInterfaceInfoSuperManager** iim,
@ -545,9 +550,6 @@ protected:
nsXPConnect(); nsXPConnect();
private: private:
JSBool EnsureRuntime() {return mRuntime ? JS_TRUE : CreateRuntime();}
JSBool CreateRuntime();
static PRThread* FindMainThread(); static PRThread* FindMainThread();
private: private:
@ -577,6 +579,8 @@ private:
typedef nsBaseHashtable<nsVoidPtrHashKey, nsISupports*, nsISupports*> ScopeSet; typedef nsBaseHashtable<nsVoidPtrHashKey, nsISupports*, nsISupports*> ScopeSet;
ScopeSet mScopes; ScopeSet mScopes;
#endif #endif
nsCOMPtr<nsIXPCScriptable> mBackstagePass;
static PRUint32 gReportAllJSExceptions; static PRUint32 gReportAllJSExceptions;
}; };
@ -617,14 +621,11 @@ private:
class XPCJSRuntime class XPCJSRuntime
{ {
public: public:
static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect, static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect);
nsIJSRuntimeService* aJSRuntimeService);
JSRuntime* GetJSRuntime() const {return mJSRuntime;} JSRuntime* GetJSRuntime() const {return mJSRuntime;}
nsXPConnect* GetXPConnect() const {return mXPConnect;} nsXPConnect* GetXPConnect() const {return mXPConnect;}
nsIJSRuntimeService* GetJSRuntimeService() const {return mJSRuntimeService;}
JSObject2WrappedJSMap* GetWrappedJSMap() const JSObject2WrappedJSMap* GetWrappedJSMap() const
{return mWrappedJSMap;} {return mWrappedJSMap;}
@ -657,8 +658,7 @@ public:
XPCLock* GetMapLock() const {return mMapLock;} XPCLock* GetMapLock() const {return mMapLock;}
XPCContext* GetXPCContext(JSContext* cx); JSBool OnJSContextNew(JSContext* cx);
XPCContext* SyncXPCContextList(JSContext* cx = nsnull);
JSBool DeferredRelease(nsISupports* obj); JSBool DeferredRelease(nsISupports* obj);
@ -752,16 +752,9 @@ private:
public: public:
#endif #endif
// For use by XPCWrappedNativeScope.
JSContext2XPCContextMap* GetContextMap() const {return mContextMap;}
private: private:
XPCJSRuntime(); // no implementation XPCJSRuntime(); // no implementation
XPCJSRuntime(nsXPConnect* aXPConnect, XPCJSRuntime(nsXPConnect* aXPConnect);
nsIJSRuntimeService* aJSRuntimeService);
JSBool GenerateStringIDs(JSContext* cx);
void PurgeXPCContextList();
private: private:
static const char* mStrings[IDX_TOTAL_COUNT]; static const char* mStrings[IDX_TOTAL_COUNT];
@ -770,8 +763,6 @@ private:
nsXPConnect* mXPConnect; nsXPConnect* mXPConnect;
JSRuntime* mJSRuntime; JSRuntime* mJSRuntime;
nsIJSRuntimeService* mJSRuntimeService; // hold this to hold the JSRuntime
JSContext2XPCContextMap* mContextMap;
JSObject2WrappedJSMap* mWrappedJSMap; JSObject2WrappedJSMap* mWrappedJSMap;
IID2WrappedJSClassMap* mWrappedJSClassMap; IID2WrappedJSClassMap* mWrappedJSClassMap;
IID2NativeInterfaceMap* mIID2NativeInterfaceMap; IID2NativeInterfaceMap* mIID2NativeInterfaceMap;
@ -802,20 +793,19 @@ private:
// no virtuals // no virtuals
class XPCContext class XPCContext
{ {
friend class XPCJSRuntime;
public: public:
static XPCContext* newXPCContext(XPCJSRuntime* aRuntime, static XPCContext* GetXPCContext(JSContext* aJSContext)
JSContext* aJSContext); {
NS_ASSERTION(aJSContext->data2, "should already have XPCContext");
return static_cast<XPCContext *>(aJSContext->data2);
}
XPCJSRuntime* GetRuntime() const {return mRuntime;} XPCJSRuntime* GetRuntime() const {return mRuntime;}
JSContext* GetJSContext() const {return mJSContext;} JSContext* GetJSContext() const {return mJSContext;}
enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE}; enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE};
// Mark functions used by SyncXPCContextList
void Mark() {mMarked = (JSPackedBool) JS_TRUE;}
void Unmark() {mMarked = (JSPackedBool) JS_FALSE;}
JSBool IsMarked() const {return (JSBool) mMarked;}
LangType GetCallingLangType() const LangType GetCallingLangType() const
{ {
return mCallingLangType; return mCallingLangType;
@ -899,6 +889,8 @@ private:
XPCContext(); // no implementation XPCContext(); // no implementation
XPCContext(XPCJSRuntime* aRuntime, JSContext* aJSContext); XPCContext(XPCJSRuntime* aRuntime, JSContext* aJSContext);
static XPCContext* newXPCContext(XPCJSRuntime* aRuntime,
JSContext* aJSContext);
private: private:
XPCJSRuntime* mRuntime; XPCJSRuntime* mRuntime;
JSContext* mJSContext; JSContext* mJSContext;
@ -908,7 +900,6 @@ private:
nsIException* mException; nsIException* mException;
LangType mCallingLangType; LangType mCallingLangType;
PRUint16 mSecurityManagerFlags; PRUint16 mSecurityManagerFlags;
JSPackedBool mMarked;
// A linked list of scopes to notify when we are destroyed. // A linked list of scopes to notify when we are destroyed.
PRCList mScopes; PRCList mScopes;
@ -3050,9 +3041,6 @@ public:
const nsTArray<XPCJSContextInfo>* GetStack() const nsTArray<XPCJSContextInfo>* GetStack()
{ return &mStack; } { return &mStack; }
private:
void SyncJSContexts();
private: private:
nsAutoTArray<XPCJSContextInfo, 16> mStack; nsAutoTArray<XPCJSContextInfo, 16> mStack;
JSContext* mSafeJSContext; JSContext* mSafeJSContext;
@ -3180,15 +3168,6 @@ public:
// Must be called with the threads locked. // Must be called with the threads locked.
static XPCPerThreadData* IterateThreads(XPCPerThreadData** iteratorp); static XPCPerThreadData* IterateThreads(XPCPerThreadData** iteratorp);
XPCContext* GetRecentXPCContext(JSContext* cx) const
{return cx == mMostRecentJSContext ? mMostRecentXPCContext : nsnull;}
void SetRecentContext(JSContext* cx, XPCContext* xpcc)
{mMostRecentJSContext = cx; mMostRecentXPCContext = xpcc;}
void ClearRecentContext()
{mMostRecentJSContext = nsnull; mMostRecentXPCContext = nsnull;}
AutoMarkingPtr** GetAutoRootsAdr() {return &mAutoRoots;} AutoMarkingPtr** GetAutoRootsAdr() {return &mAutoRoots;}
void TraceJS(JSTracer* trc); void TraceJS(JSTracer* trc);
@ -3223,9 +3202,6 @@ private:
jsval mResolveName; jsval mResolveName;
XPCWrappedNative* mResolvingWrapper; XPCWrappedNative* mResolvingWrapper;
JSContext* mMostRecentJSContext;
XPCContext* mMostRecentXPCContext;
nsIExceptionManager* mExceptionManager; nsIExceptionManager* mExceptionManager;
nsIException* mException; nsIException* mException;
JSBool mExceptionManagerNotAvailable; JSBool mExceptionManagerNotAvailable;
@ -3285,10 +3261,6 @@ private:
}; };
/***************************************************************************/ /***************************************************************************/
#define NS_JS_RUNTIME_SERVICE_CID \
{0xb5e65b52, 0x1dd1, 0x11b2, \
{ 0xae, 0x8f, 0xf0, 0x92, 0x8e, 0xd8, 0x84, 0x82 }}
#ifndef XPCONNECT_STANDALONE #ifndef XPCONNECT_STANDALONE
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
@ -3353,7 +3325,6 @@ class nsJSRuntimeServiceImpl : public nsIJSRuntimeService,
static void InitStatics() { gJSRuntimeService = nsnull; } static void InitStatics() { gJSRuntimeService = nsnull; }
protected: protected:
JSRuntime *mRuntime;
static nsJSRuntimeServiceImpl* gJSRuntimeService; static nsJSRuntimeServiceImpl* gJSRuntimeService;
nsCOMPtr<nsIXPCScriptable> mBackstagePass; nsCOMPtr<nsIXPCScriptable> mBackstagePass;
}; };

Просмотреть файл

@ -178,126 +178,3 @@ BackstagePass::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{ {
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
/*
* This object holds state that we don't want to lose!
*
* The plan is that once created this object never goes away. We do an
* intentional extra addref at construction to keep it around even if no one
* is using it.
*/
nsJSRuntimeServiceImpl::nsJSRuntimeServiceImpl() :
mRuntime(0)
{
}
nsJSRuntimeServiceImpl::~nsJSRuntimeServiceImpl() {
if(mRuntime)
{
JS_DestroyRuntime(mRuntime);
JS_ShutDown();
#ifdef DEBUG_shaver_off
fprintf(stderr, "nJRSI: destroyed runtime %p\n", (void *)mRuntime);
#endif
}
XPCPerThreadData::ShutDown();
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsJSRuntimeServiceImpl,
nsIJSRuntimeService,
nsISupportsWeakReference)
nsJSRuntimeServiceImpl*
nsJSRuntimeServiceImpl::gJSRuntimeService = nsnull;
nsJSRuntimeServiceImpl*
nsJSRuntimeServiceImpl::GetSingleton()
{
if(!gJSRuntimeService)
{
gJSRuntimeService = new nsJSRuntimeServiceImpl();
// hold an extra reference to lock it down
NS_IF_ADDREF(gJSRuntimeService);
}
NS_IF_ADDREF(gJSRuntimeService);
return gJSRuntimeService;
}
void
nsJSRuntimeServiceImpl::FreeSingleton()
{
NS_IF_RELEASE(gJSRuntimeService);
}
const uint32 gGCSize = 32L * 1024L * 1024L; /* pref? */
/* attribute JSRuntime runtime; */
NS_IMETHODIMP
nsJSRuntimeServiceImpl::GetRuntime(JSRuntime **runtime)
{
if(!runtime)
return NS_ERROR_NULL_POINTER;
if(!mRuntime)
{
// Call XPCPerThreadData::GetData to initialize
// XPCPerThreadData::gTLSIndex before initializing
// JSRuntime::threadTPIndex in JS_NewRuntime.
//
// XPConnect uses a thread local storage (XPCPerThreadData) indexed by
// XPCPerThreadData::gTLSIndex, and SpiderMonkey GC uses a thread local
// storage indexed by JSRuntime::threadTPIndex.
//
// The destructor for XPCPerThreadData::gTLSIndex may access
// thread local storage indexed by JSRuntime::threadTPIndex.
// Thus, the destructor for JSRuntime::threadTPIndex must be called
// later than the one for XPCPerThreadData::gTLSIndex.
//
// We rely on the implementation of NSPR that calls destructors at
// the same order of calling PR_NewThreadPrivateIndex.
XPCPerThreadData::GetData(nsnull);
mRuntime = JS_NewRuntime(gGCSize);
if(!mRuntime)
return NS_ERROR_OUT_OF_MEMORY;
// Unconstrain the runtime's threshold on nominal heap size, to avoid
// triggering GC too often if operating continuously near an arbitrary
// finite threshold (0xffffffff is infinity for uint32 parameters).
// This leaves the maximum-JS_malloc-bytes threshold still in effect
// to cause period, and we hope hygienic, last-ditch GCs from within
// the GC's allocator.
JS_SetGCParameter(mRuntime, JSGC_MAX_BYTES, 0xffffffff);
}
*runtime = mRuntime;
return NS_OK;
}
/* attribute nsIXPCScriptable backstagePass; */
NS_IMETHODIMP
nsJSRuntimeServiceImpl::GetBackstagePass(nsIXPCScriptable **bsp)
{
if(!mBackstagePass) {
#ifndef XPCONNECT_STANDALONE
nsCOMPtr<nsIPrincipal> sysprin;
nsCOMPtr<nsIScriptSecurityManager> secman =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
if(!secman)
return NS_ERROR_NOT_AVAILABLE;
if(NS_FAILED(secman->GetSystemPrincipal(getter_AddRefs(sysprin))))
return NS_ERROR_NOT_AVAILABLE;
mBackstagePass = new BackstagePass(sysprin);
#else
mBackstagePass = new BackstagePass();
#endif
if(!mBackstagePass)
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*bsp = mBackstagePass);
return NS_OK;
}

Просмотреть файл

@ -60,18 +60,9 @@ XPCJSContextStack::~XPCJSContextStack()
JS_SetContextThread(mOwnSafeJSContext); JS_SetContextThread(mOwnSafeJSContext);
JS_DestroyContext(mOwnSafeJSContext); JS_DestroyContext(mOwnSafeJSContext);
mOwnSafeJSContext = nsnull; mOwnSafeJSContext = nsnull;
SyncJSContexts();
} }
} }
void
XPCJSContextStack::SyncJSContexts()
{
nsXPConnect* xpc = nsXPConnect::GetXPConnect();
if(xpc)
xpc->SyncJSContexts();
}
/* readonly attribute PRInt32 count; */ /* readonly attribute PRInt32 count; */
NS_IMETHODIMP NS_IMETHODIMP
XPCJSContextStack::GetCount(PRInt32 *aCount) XPCJSContextStack::GetCount(PRInt32 *aCount)
@ -274,7 +265,6 @@ XPCJSContextStack::SetSafeJSContext(JSContext * aSafeJSContext)
{ {
JS_DestroyContextNoGC(mOwnSafeJSContext); JS_DestroyContextNoGC(mOwnSafeJSContext);
mOwnSafeJSContext = nsnull; mOwnSafeJSContext = nsnull;
SyncJSContexts();
} }
mSafeJSContext = aSafeJSContext; mSafeJSContext = aSafeJSContext;
@ -466,8 +456,6 @@ XPCPerThreadData::XPCPerThreadData()
mCallContext(nsnull), mCallContext(nsnull),
mResolveName(0), mResolveName(0),
mResolvingWrapper(nsnull), mResolvingWrapper(nsnull),
mMostRecentJSContext(nsnull),
mMostRecentXPCContext(nsnull),
mExceptionManager(nsnull), mExceptionManager(nsnull),
mException(nsnull), mException(nsnull),
mExceptionManagerNotAvailable(JS_FALSE), mExceptionManagerNotAvailable(JS_FALSE),

Просмотреть файл

@ -71,7 +71,7 @@ XPCTraceableVariant::~XPCTraceableVariant()
nsVariant::Cleanup(&mData); nsVariant::Cleanup(&mData);
if(!JSVAL_IS_NULL(mJSVal)) if(!JSVAL_IS_NULL(mJSVal))
RemoveFromRootSet(nsXPConnect::GetRuntime()->GetJSRuntime()); RemoveFromRootSet(nsXPConnect::GetRuntimeInstance()->GetJSRuntime());
} }
void XPCTraceableVariant::TraceJS(JSTracer* trc) void XPCTraceableVariant::TraceJS(JSTracer* trc)
@ -108,7 +108,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant)
if(JSVAL_IS_TRACEABLE(tmp->mJSVal)) if(JSVAL_IS_TRACEABLE(tmp->mJSVal))
{ {
XPCTraceableVariant *v = static_cast<XPCTraceableVariant*>(tmp); XPCTraceableVariant *v = static_cast<XPCTraceableVariant*>(tmp);
v->RemoveFromRootSet(nsXPConnect::GetRuntime()->GetJSRuntime()); v->RemoveFromRootSet(nsXPConnect::GetRuntimeInstance()->GetJSRuntime());
} }
tmp->mJSVal = JSVAL_NULL; tmp->mJSVal = JSVAL_NULL;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END

Просмотреть файл

@ -93,7 +93,7 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsXPCWrappedJS) NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsXPCWrappedJS)
if(tmp->mRoot && !tmp->mRoot->HasWeakReferences() && tmp->IsValid()) if(tmp->mRoot && !tmp->mRoot->HasWeakReferences() && tmp->IsValid())
{ {
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(rt) if(rt)
{ {
if(tmp->mRoot == tmp) if(tmp->mRoot == tmp)
@ -229,7 +229,8 @@ nsXPCWrappedJS::Release(void)
// need to take the map lock here to prevent GetNewOrUsed from trying // need to take the map lock here to prevent GetNewOrUsed from trying
// to reuse a wrapper on one thread while it's being destroyed on another // to reuse a wrapper on one thread while it's being destroyed on another
XPCAutoLock lock(nsXPConnect::GetRuntime()->GetMapLock()); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
XPCAutoLock lock(rt->GetMapLock());
do_decrement: do_decrement:
@ -244,7 +245,7 @@ do_decrement:
if(1 == cnt) if(1 == cnt)
{ {
if(IsValid()) if(IsValid())
RemoveFromRootSet(nsXPConnect::GetRuntime()->GetJSRuntime()); RemoveFromRootSet(rt->GetJSRuntime());
// If we are not the root wrapper or if we are not being used from a // If we are not the root wrapper or if we are not being used from a
// weak reference, then this extra ref is not needed and we can let // weak reference, then this extra ref is not needed and we can let
@ -457,15 +458,12 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
ClearWeakReferences(); ClearWeakReferences();
// Remove this root wrapper from the map // Remove this root wrapper from the map
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(rt) JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
if(map)
{ {
JSObject2WrappedJSMap* map = rt->GetWrappedJSMap(); XPCAutoLock lock(rt->GetMapLock());
if(map) map->Remove(this);
{
XPCAutoLock lock(rt->GetMapLock());
map->Remove(this);
}
} }
} }
Unlink(); Unlink();
@ -495,8 +493,8 @@ nsXPCWrappedJS::Unlink()
NS_IF_RELEASE(mClass); NS_IF_RELEASE(mClass);
if (mOuter) if (mOuter)
{ {
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if (rt && rt->GetThreadRunningGC()) if (rt->GetThreadRunningGC())
{ {
rt->DeferredRelease(mOuter); rt->DeferredRelease(mOuter);
mOuter = nsnull; mOuter = nsnull;

Просмотреть файл

@ -191,10 +191,7 @@ static void DEBUG_TrackNewWrapper(XPCWrappedNative* wrapper)
static void DEBUG_TrackDeleteWrapper(XPCWrappedNative* wrapper) static void DEBUG_TrackDeleteWrapper(XPCWrappedNative* wrapper)
{ {
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
if(nsXPConnect::GetRuntime()) nsXPConnect::GetRuntimeInstance()->DEBUG_RemoveWrappedNative(wrapper);
nsXPConnect::GetRuntime()->DEBUG_RemoveWrappedNative(wrapper);
else
NS_ERROR("failed to remove wrapper");
#endif #endif
#ifdef XPC_TRACK_WRAPPER_STATS #ifdef XPC_TRACK_WRAPPER_STATS
DEBUG_TotalLiveWrappedNativeCount--; DEBUG_TotalLiveWrappedNativeCount--;
@ -3397,7 +3394,7 @@ XPCJSObjectHolder::XPCJSObjectHolder(XPCCallContext& ccx, JSObject* obj)
XPCJSObjectHolder::~XPCJSObjectHolder() XPCJSObjectHolder::~XPCJSObjectHolder()
{ {
RemoveFromRootSet(nsXPConnect::GetRuntime()->GetJSRuntime()); RemoveFromRootSet(nsXPConnect::GetRuntimeInstance()->GetJSRuntime());
} }
void void

Просмотреть файл

@ -745,11 +745,9 @@ out:
void void
XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo) XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo)
{ {
XPCJSRuntime* rt; XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
ClassInfo2NativeSetMap* map; ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap();
if(map)
if(nsnull != (rt = nsXPConnect::GetRuntime()) &&
nsnull != (map = rt->GetClassInfo2NativeSetMap()))
{ // scoped lock { // scoped lock
XPCAutoLock lock(rt->GetMapLock()); XPCAutoLock lock(rt->GetMapLock());
map->Remove(classInfo); map->Remove(classInfo);

Просмотреть файл

@ -159,9 +159,7 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(XPCCallContext& ccx,
gScopes = this; gScopes = this;
// Grab the XPCContext associated with our context. // Grab the XPCContext associated with our context.
mContext = mRuntime->GetContextMap()->Find(ccx.GetJSContext()); mContext = XPCContext::GetXPCContext(ccx.GetJSContext());
NS_ASSERTION(mContext, "Context map is not synchronized");
mContext->AddScope(this); mContext->AddScope(this);
} }
@ -493,9 +491,7 @@ XPCWrappedNativeScope::FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt)
void void
XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC(JSContext* cx) XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC(JSContext* cx)
{ {
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(!rt)
return;
// FIXME The lock may not be necessary since we are inside // FIXME The lock may not be necessary since we are inside
// JSGC_FINALIZE_END callback and at this point GC still serializes access // JSGC_FINALIZE_END callback and at this point GC still serializes access

Просмотреть файл

@ -771,7 +771,6 @@ int main()
JS_GC(jscontext); JS_GC(jscontext);
JS_GC(jscontext); JS_GC(jscontext);
JS_DestroyContext(jscontext); JS_DestroyContext(jscontext);
xpc->SyncJSContexts();
xpc->DebugDump(4); xpc->DebugDump(4);
cxstack = nsnull; // release service held by nsCOMPtr cxstack = nsnull; // release service held by nsCOMPtr