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
+}