vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp in johnson-2.0.0.pre0 vs vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp in johnson-2.0.0.pre1

- old
+ new

@@ -136,17 +136,21 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(XPCCallContext& ccx, JSObject* aGlobal) : mRuntime(ccx.GetRuntime()), mWrappedNativeMap(Native2WrappedNativeMap::newMap(XPC_NATIVE_MAP_SIZE)), mWrappedNativeProtoMap(ClassInfo2WrappedNativeProtoMap::newMap(XPC_NATIVE_PROTO_MAP_SIZE)), + mMainThreadWrappedNativeProtoMap(ClassInfo2WrappedNativeProtoMap::newMap(XPC_NATIVE_PROTO_MAP_SIZE)), mWrapperMap(WrappedNative2WrapperMap::newMap(XPC_WRAPPER_MAP_SIZE)), mComponents(nsnull), mNext(nsnull), mGlobalJSObject(nsnull), mPrototypeJSObject(nsnull), mPrototypeJSFunction(nsnull), mPrototypeNoHelper(nsnull) +#ifndef XPCONNECT_STANDALONE + , mScriptObjectPrincipal(nsnull) +#endif { // add ourselves to the scopes list { // scoped lock XPCAutoLock lock(mRuntime->GetMapLock()); @@ -192,28 +196,28 @@ // Dummy JS class to let wrappers w/o an xpc prototype share // scopes. By doing this we avoid allocating a new scope for every // wrapper on creation of the wrapper, and most wrappers won't need // their own scope at all for the lifetime of the wrapper. -// JSCLASS_HAS_PRIVATE is key here (even though there's never anything +// WRAPPER_SLOTS is key here (even though there's never anything // in the private data slot in these prototypes), as the number of // reserved slots in this class needs to match that of the wrappers // for the JS engine to share scopes. JSClass XPC_WN_NoHelper_Proto_JSClass = { "XPC_WN_NoHelper_Proto_JSClass",// name; - JSCLASS_HAS_PRIVATE, // flags; + WRAPPER_SLOTS, // flags; /* Mandatory non-null function pointer members. */ JS_PropertyStub, // addProperty; JS_PropertyStub, // delProperty; JS_PropertyStub, // getProperty; JS_PropertyStub, // setProperty; JS_EnumerateStub, // enumerate; JS_ResolveStub, // resolve; JS_ConvertStub, // convert; - JS_FinalizeStub, // finalize; + nsnull, // finalize; /* Optionally non-null members start here. */ XPC_WN_Proto_GetObjectOps, // getObjectOps; nsnull, // checkAccess; nsnull, // call; @@ -243,18 +247,20 @@ // Our global has an nsISupports native pointer. Let's // see whether it's what we want. nsISupports* priv = (nsISupports*)xpc_GetJSPrivate(aGlobal); nsCOMPtr<nsIXPConnectWrappedNative> native = do_QueryInterface(priv); + nsCOMPtr<nsIScriptObjectPrincipal> sop; if(native) { - mScriptObjectPrincipal = do_QueryWrappedNative(native); + sop = do_QueryWrappedNative(native); } - if(!mScriptObjectPrincipal) + if(!sop) { - mScriptObjectPrincipal = do_QueryInterface(priv); + sop = do_QueryInterface(priv); } + mScriptObjectPrincipal = sop; } #endif // Lookup 'globalObject.Object.prototype' for our wrapper's proto { @@ -312,10 +318,16 @@ { NS_ASSERTION(0 == mWrappedNativeProtoMap->Count(), "scope has non-empty map"); delete mWrappedNativeProtoMap; } + if(mMainThreadWrappedNativeProtoMap) + { + NS_ASSERTION(0 == mMainThreadWrappedNativeProtoMap->Count(), "scope has non-empty map"); + delete mMainThreadWrappedNativeProtoMap; + } + if(mWrapperMap) { NS_ASSERTION(0 == mWrapperMap->Count(), "scope has non-empty map"); delete mWrapperMap; } @@ -398,15 +410,15 @@ if(wrapper->IsValid()) { NS_ASSERTION(NS_IsMainThread(), "Suspecting wrapped natives from non-main thread"); -#ifndef DEBUG_CC - // Only record objects that might be part of a cycle as roots. - if(!JS_IsAboutToBeFinalized(closure->cx, wrapper->GetFlatJSObject())) + // Only record objects that might be part of a cycle as roots, unless + // the callback wants all traces (a debug feature). + if(!(closure->cb.WantAllTraces()) && + !JS_IsAboutToBeFinalized(closure->cx, wrapper->GetFlatJSObject())) return JS_DHASH_NEXT; -#endif closure->cb.NoteRoot(nsIProgrammingLanguage::JAVASCRIPT, wrapper->GetFlatJSObject(), nsXPConnect::GetXPConnect()); } @@ -450,11 +462,13 @@ XPCWrappedNativeScope* next = cur->mNext; if(cur->mGlobalJSObject && JS_IsAboutToBeFinalized(cx, cur->mGlobalJSObject)) { cur->mGlobalJSObject = nsnull; - +#ifndef XPCONNECT_STANDALONE + cur->mScriptObjectPrincipal = nsnull; +#endif // Move this scope from the live list to the dying list. if(prev) prev->mNext = next; else gScopes = next; @@ -523,10 +537,11 @@ { for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { cur->mWrappedNativeMap->Enumerate(WrappedNativeMarker, nsnull); cur->mWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMarker, nsnull); + cur->mMainThreadWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMarker, nsnull); } DEBUG_TrackScopeTraversal(); } @@ -555,10 +570,12 @@ { cur->mWrappedNativeMap->Enumerate( ASSERT_WrappedNativeSetNotMarked, nsnull); cur->mWrappedNativeProtoMap->Enumerate( ASSERT_WrappedNativeProtoSetNotMarked, nsnull); + cur->mMainThreadWrappedNativeProtoMap->Enumerate( + ASSERT_WrappedNativeProtoSetNotMarked, nsnull); } } #endif static JSDHashOperator @@ -669,10 +686,12 @@ // Walk the protos first. Wrapper shutdown can leave dangling // proto pointers in the proto map. cur->mWrappedNativeProtoMap-> Enumerate(WrappedNativeProtoShutdownEnumerator, &data); + cur->mMainThreadWrappedNativeProtoMap-> + Enumerate(WrappedNativeProtoShutdownEnumerator, &data); cur->mWrappedNativeMap-> Enumerate(WrappedNativeShutdownEnumerator, &data); } // Now it is safe to kill all the scopes. @@ -700,10 +719,13 @@ GetScopeOfObject(JSObject* obj) { nsISupports* supports; JSClass* clazz = STOBJ_GET_CLASS(obj); + if(IS_SLIM_WRAPPER_CLASS(clazz)) + return GetSlimWrapperProto(obj)->GetScope(); + if(!IS_WRAPPER_CLASS(clazz) || !(supports = (nsISupports*) xpc_GetJSPrivate(obj))) { #ifdef DEBUG { @@ -858,10 +880,11 @@ XPCAutoLock lock(ccx.GetRuntime()->GetMapLock()); for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { cur->mWrappedNativeProtoMap->Enumerate(WNProtoSecPolicyClearer, nsnull); + cur->mMainThreadWrappedNativeProtoMap->Enumerate(WNProtoSecPolicyClearer, nsnull); cur->mWrappedNativeMap->Enumerate(WNSecPolicyClearer, nsnull); } DEBUG_TrackScopeTraversal(); @@ -887,10 +910,12 @@ { XPCAutoLock al(mRuntime->GetMapLock()); mWrappedNativeProtoMap->Enumerate(WNProtoRemover, GetRuntime()->GetDetachedWrappedNativeProtoMap()); + mMainThreadWrappedNativeProtoMap->Enumerate(WNProtoRemover, + GetRuntime()->GetDetachedWrappedNativeProtoMap()); } /***************************************************************************/ // static @@ -967,25 +992,19 @@ { XPC_LOG_INDENT(); mWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMapDumpEnumerator, &depth); XPC_LOG_OUTDENT(); } - XPC_LOG_OUTDENT(); -#endif -} -#ifndef XPCONNECT_STANDALONE -// static -void -XPCWrappedNativeScope::TraverseScopes(XPCCallContext& ccx) -{ - // Hold the lock throughout. - XPCAutoLock lock(ccx.GetRuntime()->GetMapLock()); - - for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) - if(cur->mGlobalJSObject && cur->mScriptObjectPrincipal) + XPC_LOG_ALWAYS(("mMainThreadWrappedNativeProtoMap @ %x with %d protos(s)", \ + mMainThreadWrappedNativeProtoMap, \ + mMainThreadWrappedNativeProtoMap ? mMainThreadWrappedNativeProtoMap->Count() : 0)); + // iterate contexts... + if(depth && mMainThreadWrappedNativeProtoMap && mMainThreadWrappedNativeProtoMap->Count()) { - ccx.GetXPConnect()->RecordTraversal(cur->mGlobalJSObject, - cur->mScriptObjectPrincipal); + XPC_LOG_INDENT(); + mMainThreadWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMapDumpEnumerator, &depth); + XPC_LOG_OUTDENT(); } -} + XPC_LOG_OUTDENT(); #endif +}