diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp index ae20148a7107..f94c56b78aec 100644 --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -1785,7 +1785,8 @@ nsXPConnect::RestoreWrappedNativePrototype(JSContext * aJSContext, if(si && si->GetFlags().DontSharePrototype()) return UnexpectedFailure(NS_ERROR_INVALID_ARG); - ClassInfo2WrappedNativeProtoMap* map = scope->GetWrappedNativeProtoMap(); + ClassInfo2WrappedNativeProtoMap* map = + scope->GetWrappedNativeProtoMap(proto->ClassIsMainThreadOnly()); XPCLock* lock = GetRuntime()->GetMapLock(); { // scoped lock diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index d0060f33846c..5dad1589c53e 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -1234,7 +1234,10 @@ public: GetWrapperMap() const {return mWrapperMap;} ClassInfo2WrappedNativeProtoMap* - GetWrappedNativeProtoMap() const {return mWrappedNativeProtoMap;} + GetWrappedNativeProtoMap(JSBool aMainThreadOnly) const + {return aMainThreadOnly ? + mMainThreadWrappedNativeProtoMap : + mWrappedNativeProtoMap;} nsXPCComponents* GetComponents() const {return mComponents;} @@ -1340,6 +1343,7 @@ private: XPCJSRuntime* mRuntime; Native2WrappedNativeMap* mWrappedNativeMap; ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap; + ClassInfo2WrappedNativeProtoMap* mMainThreadWrappedNativeProtoMap; WrappedNative2WrapperMap* mWrapperMap; nsXPCComponents* mComponents; XPCWrappedNativeScope* mNext; diff --git a/js/src/xpconnect/src/xpcwrappednativeproto.cpp b/js/src/xpconnect/src/xpcwrappednativeproto.cpp index 28bc4bb1d25d..948a96d0d491 100644 --- a/js/src/xpconnect/src/xpcwrappednativeproto.cpp +++ b/js/src/xpconnect/src/xpcwrappednativeproto.cpp @@ -167,7 +167,7 @@ XPCWrappedNativeProto::JSProtoObjectFinalized(JSContext *cx, JSObject *obj) { // Only remove this proto from the map if it is the one in the map. ClassInfo2WrappedNativeProtoMap* map = - GetScope()->GetWrappedNativeProtoMap(); + GetScope()->GetWrappedNativeProtoMap(ClassIsMainThreadOnly()); if(map->Find(mClassInfo) == this) map->Remove(mClassInfo); } @@ -244,8 +244,9 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCCallContext& ccx, if(shared) { - map = Scope->GetWrappedNativeProtoMap(); - lock = Scope->GetRuntime()->GetMapLock(); + JSBool mainThreadOnly = !!(ciFlags & nsIClassInfo::MAIN_THREAD_ONLY); + map = Scope->GetWrappedNativeProtoMap(mainThreadOnly); + lock = mainThreadOnly ? nsnull : Scope->GetRuntime()->GetMapLock(); { // scoped lock XPCAutoLock al(lock); proto = map->Find(ClassInfo); diff --git a/js/src/xpconnect/src/xpcwrappednativescope.cpp b/js/src/xpconnect/src/xpcwrappednativescope.cpp index c33e67aac5e9..c9d6cc8325f9 100644 --- a/js/src/xpconnect/src/xpcwrappednativescope.cpp +++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp @@ -138,6 +138,7 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(XPCCallContext& ccx, : 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), @@ -319,6 +320,12 @@ XPCWrappedNativeScope::~XPCWrappedNativeScope() 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"); @@ -532,6 +539,7 @@ XPCWrappedNativeScope::MarkAllWrappedNativesAndProtos() { cur->mWrappedNativeMap->Enumerate(WrappedNativeMarker, nsnull); cur->mWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMarker, nsnull); + cur->mMainThreadWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMarker, nsnull); } DEBUG_TrackScopeTraversal(); @@ -564,6 +572,8 @@ XPCWrappedNativeScope::ASSERT_NoInterfaceSetsAreMarked() ASSERT_WrappedNativeSetNotMarked, nsnull); cur->mWrappedNativeProtoMap->Enumerate( ASSERT_WrappedNativeProtoSetNotMarked, nsnull); + cur->mMainThreadWrappedNativeProtoMap->Enumerate( + ASSERT_WrappedNativeProtoSetNotMarked, nsnull); } } #endif @@ -678,6 +688,8 @@ XPCWrappedNativeScope::SystemIsBeingShutDown(JSContext* cx) // proto pointers in the proto map. cur->mWrappedNativeProtoMap-> Enumerate(WrappedNativeProtoShutdownEnumerator, &data); + cur->mMainThreadWrappedNativeProtoMap-> + Enumerate(WrappedNativeProtoShutdownEnumerator, &data); cur->mWrappedNativeMap-> Enumerate(WrappedNativeShutdownEnumerator, &data); } @@ -867,6 +879,7 @@ XPCWrappedNativeScope::ClearAllWrappedNativeSecurityPolicies(XPCCallContext& ccx for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { cur->mWrappedNativeProtoMap->Enumerate(WNProtoSecPolicyClearer, nsnull); + cur->mMainThreadWrappedNativeProtoMap->Enumerate(WNProtoSecPolicyClearer, nsnull); cur->mWrappedNativeMap->Enumerate(WNSecPolicyClearer, nsnull); } @@ -896,6 +909,8 @@ XPCWrappedNativeScope::RemoveWrappedNativeProtos() mWrappedNativeProtoMap->Enumerate(WNProtoRemover, GetRuntime()->GetDetachedWrappedNativeProtoMap()); + mMainThreadWrappedNativeProtoMap->Enumerate(WNProtoRemover, + GetRuntime()->GetDetachedWrappedNativeProtoMap()); } /***************************************************************************/ @@ -976,6 +991,17 @@ XPCWrappedNativeScope::DebugDump(PRInt16 depth) mWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMapDumpEnumerator, &depth); XPC_LOG_OUTDENT(); } + + XPC_LOG_ALWAYS(("mMainThreadWrappedNativeProtoMap @ %x with %d protos(s)", \ + mMainThreadWrappedNativeProtoMap, \ + mMainThreadWrappedNativeProtoMap ? mMainThreadWrappedNativeProtoMap->Count() : 0)); + // iterate contexts... + if(depth && mMainThreadWrappedNativeProtoMap && mMainThreadWrappedNativeProtoMap->Count()) + { + XPC_LOG_INDENT(); + mMainThreadWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMapDumpEnumerator, &depth); + XPC_LOG_OUTDENT(); + } XPC_LOG_OUTDENT(); #endif }