Bug 722594 - Remove xpc_CreateMTGlobalObject and mMTCompartmentMap (r=mrbkap)

--HG--
extra : rebase_source : 6dd76009eb8029499efcbe6bbb0b74d58000612c
This commit is contained in:
Luke Wagner 2012-02-01 13:36:51 -08:00
parent 542a670fec
commit 55d9645111
4 changed files with 20 additions and 133 deletions

View File

@ -271,28 +271,14 @@ CompartmentCallback(JSContext *cx, JSCompartment *compartment, uintN op)
if (!priv)
return true;
if (xpc::PtrAndPrincipalHashKey *key = priv->key) {
XPCCompartmentMap &map = self->GetCompartmentMap();
xpc::PtrAndPrincipalHashKey *key = priv->key;
XPCCompartmentMap &map = self->GetCompartmentMap();
#ifdef DEBUG
{
JSCompartment *current = NULL;
NS_ASSERTION(map.Get(key, &current), "no compartment?");
NS_ASSERTION(current == compartment, "compartment mismatch");
}
JSCompartment *current = NULL;
NS_ASSERTION(map.Get(key, &current), "no compartment?");
NS_ASSERTION(current == compartment, "compartment mismatch");
#endif
map.Remove(key);
} else {
nsISupports *ptr = priv->ptr;
XPCMTCompartmentMap &map = self->GetMTCompartmentMap();
#ifdef DEBUG
{
JSCompartment *current;
NS_ASSERTION(map.Get(ptr, &current), "no compartment?");
NS_ASSERTION(current == compartment, "compartment mismatch");
}
#endif
map.Remove(ptr);
}
map.Remove(key);
return true;
}
@ -474,9 +460,7 @@ CheckParticipatesInCycleCollection(PRUint32 aLangID, void *aThing,
closure->cycleCollectionEnabled =
aLangID == nsIProgrammingLanguage::JAVASCRIPT &&
AddToCCKind(js_GetGCThingTraceKind(aThing)) &&
xpc::ParticipatesInCycleCollection(closure->cx,
static_cast<js::gc::Cell*>(aThing));
AddToCCKind(js_GetGCThingTraceKind(aThing));
}
static JSDHashOperator
@ -508,14 +492,9 @@ XPCJSRuntime::SuspectWrappedNative(JSContext *cx, XPCWrappedNative *wrapper,
NS_ASSERTION(NS_IsMainThread() || NS_IsCycleCollectorThread(),
"Suspecting wrapped natives from non-CC thread");
// Only suspect wrappedJSObjects that are in a compartment that
// participates in cycle collection.
JSObject* obj = wrapper->GetFlatJSObjectPreserveColor();
if (!xpc::ParticipatesInCycleCollection(cx, js::gc::AsCell(obj)))
return;
// Only record objects that might be part of a cycle as roots, unless
// the callback wants all traces (a debug feature).
JSObject* obj = wrapper->GetFlatJSObjectPreserveColor();
if (xpc_IsGrayGCThing(obj) || cb.WantAllTraces())
cb.NoteRoot(nsIProgrammingLanguage::JAVASCRIPT, obj,
nsXPConnect::GetXPConnect());
@ -598,11 +577,6 @@ XPCJSRuntime::AddXPConnectRoots(JSContext* cx,
continue;
}
// Only suspect wrappedJSObjects that are in a compartment that
// participates in cycle collection.
if (!xpc::ParticipatesInCycleCollection(cx, js::gc::AsCell(obj)))
continue;
cb.NoteXPCOMRoot(static_cast<nsIXPConnectWrappedJS *>(wrappedJS));
}
@ -1998,7 +1972,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
mJSHolders.ops = nsnull;
mCompartmentMap.Init();
mMTCompartmentMap.Init();
// Install a JavaScript 'debugger' keyword handler in debug builds only
#ifdef DEBUG

View File

@ -177,7 +177,7 @@ static JSClass global_class = {
XPCONNECT_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, SafeGlobalResolve, JS_ConvertStub, SafeFinalize,
JSCLASS_NO_OPTIONAL_MEMBERS
NULL, NULL, NULL, NULL, NULL, NULL, TraceXPCGlobal
};
// We just use the same reporter as the component loader
@ -223,13 +223,10 @@ XPCJSContextStack::GetSafeJSContext()
JS_SetErrorReporter(mSafeJSContext, mozJSLoaderErrorReporter);
// Because we can run off the main thread, we create an MT
// global object. Our principal is the unique key.
JSCompartment *compartment;
nsresult rv = xpc_CreateMTGlobalObject(mSafeJSContext,
&global_class,
principal, &glob,
&compartment);
nsresult rv = xpc_CreateGlobalObject(mSafeJSContext, &global_class,
principal, principal, false,
&glob, &compartment);
if (NS_FAILED(rv))
glob = nsnull;

View File

@ -1209,8 +1209,7 @@ xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp,
if (!map.Get(&key, compartment)) {
xpc::PtrAndPrincipalHashKey *priv_key =
new xpc::PtrAndPrincipalHashKey(ptr, principal);
xpc::CompartmentPrivate *priv =
new xpc::CompartmentPrivate(priv_key, wantXrays, NS_IsMainThread());
xpc::CompartmentPrivate *priv = new xpc::CompartmentPrivate(priv_key, wantXrays);
if (!CreateNewCompartment(cx, clasp, principal, priv,
global, compartment)) {
return UnexpectedFailure(NS_ERROR_FAILURE);
@ -1239,39 +1238,6 @@ xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp,
return NS_OK;
}
nsresult
xpc_CreateMTGlobalObject(JSContext *cx, JSClass *clasp,
nsISupports *ptr, JSObject **global,
JSCompartment **compartment)
{
// NB: We can be either on or off the main thread here.
XPCMTCompartmentMap& map = nsXPConnect::GetRuntimeInstance()->GetMTCompartmentMap();
if (!map.Get(ptr, compartment)) {
// We allow the pointer to be a principal, in which case it becomes
// the principal for the newly created compartment. The caller is
// responsible for ensuring that doing this doesn't violate
// threadsafety assumptions.
nsCOMPtr<nsIPrincipal> principal(do_QueryInterface(ptr));
xpc::CompartmentPrivate *priv =
new xpc::CompartmentPrivate(ptr, false, NS_IsMainThread());
if (!CreateNewCompartment(cx, clasp, principal, priv, global,
compartment)) {
return UnexpectedFailure(NS_ERROR_UNEXPECTED);
}
map.Put(ptr, *compartment);
} else {
js::AutoSwitchCompartment sc(cx, *compartment);
JSObject *tempGlobal = JS_NewGlobalObject(cx, clasp);
if (!tempGlobal)
return UnexpectedFailure(NS_ERROR_FAILURE);
*global = tempGlobal;
}
return NS_OK;
}
NS_IMETHODIMP
nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
nsISupports *aCOMObj,
@ -1284,7 +1250,7 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
NS_ASSERTION(aJSContext, "bad param");
NS_ASSERTION(aCOMObj, "bad param");
NS_ASSERTION(_retval, "bad param");
NS_ASSERTION(aExtraPtr || aPrincipal, "must be able to find a compartment");
NS_ASSERTION(aPrincipal, "must be able to find a compartment");
// XXX This is not pretty. We make a temporary global object and
// init it with all the Components object junk just so we have a
@ -1296,13 +1262,8 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
JSCompartment* compartment;
JSObject* tempGlobal;
nsresult rv = aPrincipal
? xpc_CreateGlobalObject(ccx, &xpcTempGlobalClass, aPrincipal,
aExtraPtr, false, &tempGlobal,
&compartment)
: xpc_CreateMTGlobalObject(ccx, &xpcTempGlobalClass,
aExtraPtr, &tempGlobal,
&compartment);
nsresult rv = xpc_CreateGlobalObject(ccx, &xpcTempGlobalClass, aPrincipal,
aExtraPtr, false, &tempGlobal, &compartment);
NS_ENSURE_SUCCESS(rv, rv);
JSAutoEnterCompartment ac;
@ -2585,11 +2546,8 @@ nsXPConnect::CheckForDebugMode(JSRuntime *rt) {
continue;
}
/* ParticipatesInCycleCollection means "on the main thread" */
if (xpc::CompartmentParticipatesInCycleCollection(cx, comp)) {
if (!JS_SetDebugModeForCompartment(cx, comp, gDesiredDebugMode))
goto fail;
}
if (!JS_SetDebugModeForCompartment(cx, comp, gDesiredDebugMode))
goto fail;
}
}

View File

@ -299,14 +299,6 @@ class PtrAndPrincipalHashKey : public PLDHashEntryHdr
}
// NB: nsDataHashtableMT is usually not very useful as all it does is lock
// around each individual operation performed on it. That would imply, that
// the pattern: if (!map.Get(key)) map.Put(key, value); is not safe as another
// thread could race to insert key into map. However, in our case, only one
// thread at any time could attempt to insert |key| into |map|, so it works
// well enough for our uses.
typedef nsDataHashtableMT<nsISupportsHashKey, JSCompartment *> XPCMTCompartmentMap;
// This map is only used on the main thread.
typedef nsDataHashtable<xpc::PtrAndPrincipalHashKey, JSCompartment *> XPCCompartmentMap;
@ -696,8 +688,6 @@ public:
XPCCompartmentMap& GetCompartmentMap()
{return mCompartmentMap;}
XPCMTCompartmentMap& GetMTCompartmentMap()
{return mMTCompartmentMap;}
XPCLock* GetMapLock() const {return mMapLock;}
@ -836,7 +826,6 @@ private:
XPCWrappedNativeProtoMap* mDetachedWrappedNativeProtoMap;
XPCNativeWrapperMap* mExplicitNativeWrapperMap;
XPCCompartmentMap mCompartmentMap;
XPCMTCompartmentMap mMTCompartmentMap;
XPCLock* mMapLock;
PRThread* mThreadRunningGC;
nsTArray<nsXPCWrappedJS*> mWrappedJSToReleaseArray;
@ -4415,31 +4404,17 @@ namespace xpc {
struct CompartmentPrivate
{
CompartmentPrivate(PtrAndPrincipalHashKey *key, bool wantXrays, bool cycleCollectionEnabled)
CompartmentPrivate(PtrAndPrincipalHashKey *key, bool wantXrays)
: key(key),
ptr(nsnull),
wantXrays(wantXrays),
cycleCollectionEnabled(cycleCollectionEnabled)
{
MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
}
CompartmentPrivate(nsISupports *ptr, bool wantXrays, bool cycleCollectionEnabled)
: key(nsnull),
ptr(ptr),
wantXrays(wantXrays),
cycleCollectionEnabled(cycleCollectionEnabled)
wantXrays(wantXrays)
{
MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
}
~CompartmentPrivate();
// NB: key and ptr are mutually exclusive.
nsAutoPtr<PtrAndPrincipalHashKey> key;
nsCOMPtr<nsISupports> ptr;
bool wantXrays;
bool cycleCollectionEnabled;
nsAutoPtr<JSObject2JSObjectMap> waiverWrapperMap;
// NB: we don't want this map to hold a strong reference to the wrapper.
nsAutoPtr<nsDataHashtable<nsPtrHashKey<XPCWrappedNative>, JSObject *> > expandoMap;
@ -4496,22 +4471,6 @@ struct CompartmentPrivate
}
};
inline bool
CompartmentParticipatesInCycleCollection(JSContext *cx, JSCompartment *compartment)
{
CompartmentPrivate *priv =
static_cast<CompartmentPrivate *>(JS_GetCompartmentPrivate(cx, compartment));
NS_ASSERTION(priv, "This should never be null!");
return priv->cycleCollectionEnabled;
}
inline bool
ParticipatesInCycleCollection(JSContext *cx, js::gc::Cell *cell)
{
return CompartmentParticipatesInCycleCollection(cx, cell->compartment());
}
}
/***************************************************************************/