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;
// 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);
if (mContext) {
::JS_SetContextPrivate(mContext, static_cast<nsIScriptContext *>(this));

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

@ -580,11 +580,6 @@ NS_IMETHODIMP nsJSSh::Init()
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");
// get the JSRuntime from the runtime svc
if (!rtsvc) {
@ -667,7 +662,6 @@ NS_IMETHODIMP nsJSSh::Cleanup()
}
JS_DestroyContext(mJSContext);
xpc->SyncJSContexts();
return NS_OK;
}

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

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

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

@ -530,11 +530,7 @@ interface nsIXPConnect : nsISupports
in nsIStackFrame aCaller);
/**
* XPConnect builds internal objects that parallel, and are one-to-one with,
* 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.
* Deprecated do-nothing function.
*/
void syncJSContexts();

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

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

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

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

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

@ -201,9 +201,9 @@ private:
inline
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");
}

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

@ -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
// has already been finalized.
XPCJSRuntime *rt = nsXPConnect::GetRuntime();
XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
{
// scoped lock

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

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

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

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

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

@ -124,20 +124,7 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
mContextPopRequired = JS_TRUE;
}
// Try to get the JSContext -> XPCContext mapping from the cache.
// 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);
}
mXPCContext = XPCContext::GetXPCContext(mJSContext);
mPrevCallerLanguage = mXPCContext->SetCallingLangType(mCallerLanguage);
// hook into call context chain for our thread
@ -352,7 +339,6 @@ XPCCallContext::~XPCCallContext()
"JSContext still in threadjscontextstack!");
JS_DestroyContext(mJSContext);
mXPC->SyncJSContexts();
}
else
{

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

@ -3897,7 +3897,7 @@ nsXPCComponents::NewResolve(nsIXPConnectWrappedNative *wrapper,
jsval id, PRUint32 flags,
JSObject * *objp, PRBool *_retval)
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(!rt)
return NS_ERROR_FAILURE;
@ -3928,7 +3928,7 @@ nsXPCComponents::GetProperty(nsIXPConnectWrappedNative *wrapper,
JSContext * cx, JSObject * obj,
jsval id, jsval * vp, PRBool *_retval)
{
XPCContext* xpcc = nsXPConnect::GetContext(cx);
XPCContext* xpcc = XPCContext::GetXPCContext(cx);
if(!xpcc)
return NS_ERROR_FAILURE;
@ -3963,7 +3963,7 @@ nsXPCComponents::SetProperty(nsIXPConnectWrappedNative *wrapper,
JSContext * cx, JSObject * obj, jsval id,
jsval * vp, PRBool *_retval)
{
XPCContext* xpcc = nsXPConnect::GetContext(cx);
XPCContext* xpcc = XPCContext::GetXPCContext(cx);
if(!xpcc)
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,
JSContext* aJSContext)
: mRuntime(aRuntime),
@ -66,19 +53,23 @@ XPCContext::XPCContext(XPCJSRuntime* aRuntime,
mSecurityManager(nsnull),
mException(nsnull),
mCallingLangType(LANG_UNKNOWN),
mSecurityManagerFlags(0),
mMarked((JSPackedBool) JS_FALSE)
mSecurityManagerFlags(0)
{
MOZ_COUNT_CTOR(XPCContext);
PR_INIT_CLIST(&mScopes);
for(const char** p = XPC_ARG_FORMATTER_FORMAT_STRINGS; *p; p++)
JS_AddArgumentFormatter(mJSContext, *p, XPC_JSArgumentFormatter);
NS_ASSERTION(!mJSContext->data2, "Must be null");
mJSContext->data2 = this;
}
XPCContext::~XPCContext()
{
MOZ_COUNT_DTOR(XPCContext);
NS_ASSERTION(mJSContext->data2 == this, "Must match this");
mJSContext->data2 = nsnull;
NS_IF_RELEASE(mException);
NS_IF_RELEASE(mSecurityManager);

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

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

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

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

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

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

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

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

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

@ -795,7 +795,7 @@ nsJSCID::CreateInstance(nsISupports **_retval)
// Do the security check if necessary
XPCContext* xpcc = nsXPConnect::GetContext(cx);
XPCContext* xpcc = XPCContext::GetXPCContext(cx);
nsIXPCSecurityManager* sm;
sm = xpcc->GetAppropriateSecurityManager(
@ -868,7 +868,7 @@ nsJSCID::GetService(nsISupports **_retval)
// Do the security check if necessary
XPCContext* xpcc = nsXPConnect::GetContext(cx);
XPCContext* xpcc = XPCContext::GetXPCContext(cx);
nsIXPCSecurityManager* sm;
sm = xpcc->GetAppropriateSecurityManager(
@ -914,7 +914,7 @@ nsJSCID::Construct(nsIXPConnectWrappedNative *wrapper,
PRUint32 argc, jsval * argv, jsval * vp,
PRBool *_retval)
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(!rt)
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
struct JSDyingJSObjectData
{
@ -233,24 +227,20 @@ DetachedWrappedNativeProtoMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
static JSBool
ContextCallback(JSContext *cx, uintN operation)
{
XPCJSRuntime* self = nsXPConnect::GetRuntime();
if (self)
XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
if(self)
{
if (operation == JSCONTEXT_NEW)
if(operation == JSCONTEXT_NEW)
{
// Set the limits on the native and script stack space.
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
if(tls)
{
JS_SetThreadStackLimit(cx, tls->GetStackLimit());
}
JS_SetScriptStackQuota(cx, 100*1024*1024);
if(!self->OnJSContextNew(cx))
return JS_FALSE;
}
else if(operation == JSCONTEXT_DESTROY)
{
delete XPCContext::GetXPCContext(cx);
}
}
return gOldJSContextCallback
? gOldJSContextCallback(cx, operation)
: JS_TRUE;
return JS_TRUE;
}
struct ObjectHolder : public JSDHashEntryHdr
@ -521,7 +511,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
{
nsVoidArray* dyingWrappedJSArray;
XPCJSRuntime* self = nsXPConnect::GetRuntime();
XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
if(self)
{
switch(status)
@ -827,8 +817,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
}
}
// always chain to old GCCallback if non-null.
return gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE;
return JS_TRUE;
}
/***************************************************************************/
@ -890,13 +879,6 @@ XPCJSRuntime::~XPCJSRuntime()
#endif
// clean up and destroy maps...
if(mContextMap)
{
PurgeXPCContextList();
delete mContextMap;
}
if(mWrappedJSMap)
{
#ifdef XPC_DUMP_AT_SHUTDOWN
@ -950,7 +932,6 @@ XPCJSRuntime::~XPCJSRuntime()
if(mMapLock)
XPCAutoLock::DestroyLock(mMapLock);
NS_IF_RELEASE(mJSRuntimeService);
if(mThisTranslatorMap)
{
@ -1019,9 +1000,6 @@ XPCJSRuntime::~XPCJSRuntime()
XPCConvert::RemoveXPCOMUCStringFinalizer();
gOldJSGCCallback = NULL;
gOldJSContextCallback = NULL;
if(mJSHolders.ops)
{
JS_DHashTableFinish(&mJSHolders);
@ -1032,14 +1010,22 @@ XPCJSRuntime::~XPCJSRuntime()
JS_DHashTableFinish(&mClearedGlobalObjects);
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,
nsIJSRuntimeService* aJSRuntimeService)
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
: mXPConnect(aXPConnect),
mJSRuntime(nsnull),
mJSRuntimeService(aJSRuntimeService),
mContextMap(JSContext2XPCContextMap::newMap(XPC_CONTEXT_MAP_SIZE)),
mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)),
mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_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.
mStrIDs[0] = 0;
if(mJSRuntimeService)
{
NS_ADDREF(mJSRuntimeService);
mJSRuntimeService->GetRuntime(&mJSRuntime);
}
// 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);
NS_ASSERTION(!gOldJSGCCallback, "XPCJSRuntime created more than once");
mJSRuntime = JS_NewRuntime(32L * 1024L * 1024L); // pref ?
if(mJSRuntime)
{
gOldJSContextCallback = JS_SetContextCallback(mJSRuntime,
ContextCallback);
gOldJSGCCallback = JS_SetGCCallbackRT(mJSRuntime, GCCallback);
// 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(mJSRuntime, JSGC_MAX_BYTES, 0xffffffff);
JS_SetContextCallback(mJSRuntime, ContextCallback);
JS_SetGCCallbackRT(mJSRuntime, GCCallback);
JS_SetExtraGCRoots(mJSRuntime, TraceJS, this);
}
@ -1099,20 +1102,14 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect,
// static
XPCJSRuntime*
XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect,
nsIJSRuntimeService* aJSRuntimeService)
XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect)
{
NS_PRECONDITION(aXPConnect,"bad param");
NS_PRECONDITION(aJSRuntimeService,"bad param");
XPCJSRuntime* self;
self = new XPCJSRuntime(aXPConnect,
aJSRuntimeService);
XPCJSRuntime* self = new XPCJSRuntime(aXPConnect);
if(self &&
self->GetJSRuntime() &&
self->GetContextMap() &&
self->GetWrappedJSMap() &&
self->GetWrappedJSClassMap() &&
self->GetIID2NativeInterfaceMap() &&
@ -1130,125 +1127,39 @@ XPCJSRuntime::newXPCJSRuntime(nsXPConnect* aXPConnect,
return nsnull;
}
XPCContext*
XPCJSRuntime::GetXPCContext(JSContext* cx)
JSBool
XPCJSRuntime::OnJSContextNew(JSContext *cx)
{
XPCContext* xpcc;
// find it in the map.
{ // 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())
// if it is our first context then we need to generate our string ids
JSBool ok = JS_TRUE;
if(!mStrIDs[0])
{
xpcc->Unmark();
return JS_DHASH_NEXT;
JSAutoRequest ar(cx);
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);
}
}
// this XPCContext represents a dead JSContext - delete it
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);
if (!ok)
return JS_FALSE;
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
if(tls)
{
if(found)
tls->SetRecentContext(cx, found);
else
tls->ClearRecentContext();
}
if(!tls)
return JS_FALSE;
return found;
}
XPCContext* xpc = new XPCContext(this, cx);
if (!xpc)
return JS_FALSE;
static JSDHashOperator
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);
}
JS_SetThreadStackLimit(cx, tls->GetStackLimit());
JS_SetScriptStackQuota(cx, 100*1024*1024);
return JS_TRUE;
}
@ -1271,13 +1182,6 @@ XPCJSRuntime::DeferredRelease(nsISupports* obj)
#ifdef DEBUG
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,
uint32 number, void *arg)
{
@ -1310,19 +1214,23 @@ XPCJSRuntime::DebugDump(PRInt16 depth)
XPC_LOG_ALWAYS(("mXPConnect @ %x", mXPConnect));
XPC_LOG_ALWAYS(("mJSRuntime @ %x", mJSRuntime));
XPC_LOG_ALWAYS(("mMapLock @ %x", mMapLock));
XPC_LOG_ALWAYS(("mJSRuntimeService @ %x", mJSRuntimeService));
XPC_LOG_ALWAYS(("mWrappedJSToReleaseArray @ %x with %d wrappers(s)", \
&mWrappedJSToReleaseArray,
mWrappedJSToReleaseArray.Count()));
XPC_LOG_ALWAYS(("mContextMap @ %x with %d context(s)", \
mContextMap, mContextMap ? mContextMap->Count() : 0));
// iterate contexts...
if(depth && mContextMap && mContextMap->Count())
int cxCount = 0;
JSContext* iter = nsnull;
while(JS_ContextIterator(mJSRuntime, &iter))
++cxCount;
XPC_LOG_ALWAYS(("%d JS context(s)", cxCount));
iter = nsnull;
while(JS_ContextIterator(mJSRuntime, &iter))
{
XPCContext *xpc = XPCContext::GetXPCContext(iter);
XPC_LOG_INDENT();
mContextMap->Enumerate(ContextMapDumpEnumerator, &depth);
xpc->DebugDump(depth);
XPC_LOG_OUTDENT();
}

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

@ -120,33 +120,6 @@ HashNativeKey(JSDHashTable *table, const void *key)
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...

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

@ -53,60 +53,6 @@
// no virtuals in the maps - all the common stuff inlined
// 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

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

@ -67,7 +67,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCException)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCJSContextStackIterator)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect, nsXPConnect::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(nsXPCComponents_Interfaces)
@ -86,7 +85,7 @@ static const nsModuleComponentInfo components[] = {
{nsnull, NS_XPCONNECT_CID, XPC_XPCONNECT_CONTRACTID, nsIXPConnectConstructor },
{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_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 },
{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)},
@ -115,7 +114,6 @@ xpcModuleCtor(nsIModule* self)
nsXPCException::InitStatics();
XPCWrappedNativeScope::InitStatics();
XPCPerThreadData::InitStatics();
nsJSRuntimeServiceImpl::InitStatics();
nsXPCThreadJSContextStackImpl::InitStatics();
#ifdef XPC_IDISPATCH_SUPPORT
@ -131,7 +129,6 @@ xpcModuleDtor(nsIModule* self)
// Release our singletons
nsXPConnect::ReleaseXPConnectSingleton();
nsXPCThreadJSContextStackImpl::FreeSingleton();
nsJSRuntimeServiceImpl::FreeSingleton();
xpc_DestroyJSxIDClassObjects();
#ifdef XPC_IDISPATCH_SUPPORT
nsDispatchSupport::FreeSingleton();

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

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

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

@ -178,126 +178,3 @@ BackstagePass::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
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_DestroyContext(mOwnSafeJSContext);
mOwnSafeJSContext = nsnull;
SyncJSContexts();
}
}
void
XPCJSContextStack::SyncJSContexts()
{
nsXPConnect* xpc = nsXPConnect::GetXPConnect();
if(xpc)
xpc->SyncJSContexts();
}
/* readonly attribute PRInt32 count; */
NS_IMETHODIMP
XPCJSContextStack::GetCount(PRInt32 *aCount)
@ -274,7 +265,6 @@ XPCJSContextStack::SetSafeJSContext(JSContext * aSafeJSContext)
{
JS_DestroyContextNoGC(mOwnSafeJSContext);
mOwnSafeJSContext = nsnull;
SyncJSContexts();
}
mSafeJSContext = aSafeJSContext;
@ -466,8 +456,6 @@ XPCPerThreadData::XPCPerThreadData()
mCallContext(nsnull),
mResolveName(0),
mResolvingWrapper(nsnull),
mMostRecentJSContext(nsnull),
mMostRecentXPCContext(nsnull),
mExceptionManager(nsnull),
mException(nsnull),
mExceptionManagerNotAvailable(JS_FALSE),

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

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

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

@ -93,7 +93,7 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsXPCWrappedJS)
if(tmp->mRoot && !tmp->mRoot->HasWeakReferences() && tmp->IsValid())
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if(rt)
{
if(tmp->mRoot == tmp)
@ -229,7 +229,8 @@ nsXPCWrappedJS::Release(void)
// 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
XPCAutoLock lock(nsXPConnect::GetRuntime()->GetMapLock());
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
XPCAutoLock lock(rt->GetMapLock());
do_decrement:
@ -244,7 +245,7 @@ do_decrement:
if(1 == cnt)
{
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
// weak reference, then this extra ref is not needed and we can let
@ -457,15 +458,12 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
ClearWeakReferences();
// Remove this root wrapper from the map
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
if(rt)
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
if(map)
{
JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
if(map)
{
XPCAutoLock lock(rt->GetMapLock());
map->Remove(this);
}
XPCAutoLock lock(rt->GetMapLock());
map->Remove(this);
}
}
Unlink();
@ -495,8 +493,8 @@ nsXPCWrappedJS::Unlink()
NS_IF_RELEASE(mClass);
if (mOuter)
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
if (rt && rt->GetThreadRunningGC())
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
if (rt->GetThreadRunningGC())
{
rt->DeferredRelease(mOuter);
mOuter = nsnull;

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

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

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

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

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

@ -159,9 +159,7 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(XPCCallContext& ccx,
gScopes = this;
// Grab the XPCContext associated with our context.
mContext = mRuntime->GetContextMap()->Find(ccx.GetJSContext());
NS_ASSERTION(mContext, "Context map is not synchronized");
mContext = XPCContext::GetXPCContext(ccx.GetJSContext());
mContext->AddScope(this);
}
@ -493,9 +491,7 @@ XPCWrappedNativeScope::FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt)
void
XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC(JSContext* cx)
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
if(!rt)
return;
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
// FIXME The lock may not be necessary since we are inside
// 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_DestroyContext(jscontext);
xpc->SyncJSContexts();
xpc->DebugDump(4);
cxstack = nsnull; // release service held by nsCOMPtr