bool ScriptInterface::LoadGlobalScripts() { // Ignore this failure in tests if (!g_VFS) return false; // Load and execute *.js in the global scripts directory VfsPaths pathnames; vfs::GetPathnames(g_VFS, L"globalscripts/", L"*.js", pathnames); for (const VfsPath& path : pathnames) if (!LoadGlobalScriptFile(path)) { LOGERROR("LoadGlobalScripts: Failed to load script %s", path.string8()); return false; } JSAutoRequest rq(m->m_cx); JS::RootedValue proto(m->m_cx); JS::RootedObject global(m->m_cx, m->m_glob); if (JS_GetProperty(m->m_cx, global, "Vector2Dprototype", &proto)) m->m_ScriptValCache[CACHE_VECTOR2DPROTO] = DefPersistentRooted<JS::Value>(GetJSRuntime(), proto); if (JS_GetProperty(m->m_cx, global, "Vector3Dprototype", &proto)) m->m_ScriptValCache[CACHE_VECTOR3DPROTO] = DefPersistentRooted<JS::Value>(GetJSRuntime(), proto); return true; }
void ScriptInterface::DumpHeap() { #if MOZJS_DEBUG_ABI JS_DumpHeap(GetJSRuntime(), stderr, NULL, JSTRACE_OBJECT, NULL, (size_t)-1, NULL); #endif fprintf(stderr, "# Bytes allocated: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES)); JS_GC(GetJSRuntime()); fprintf(stderr, "# Bytes allocated after GC: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES)); }
void XPCJSRuntime::UnsetContextGlobals() { if(!mClearedGlobalObjects.ops) return; RestoreContextGlobals(); JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { if(nsXPConnect::GetXPConnect()->GetRequestDepth(acx) == 0) { JS_ClearNewbornRoots(acx); if(acx->globalObject) { JSDHashEntryHdr* entry = JS_DHashTableOperate(&mClearedGlobalObjects, acx, JS_DHASH_ADD); ClearedGlobalObject* clearedGlobal = reinterpret_cast<ClearedGlobalObject*>(entry); if(clearedGlobal) { clearedGlobal->mContext = acx; clearedGlobal->mGlobalObject = acx->globalObject; acx->globalObject = nsnull; } } } } }
void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc) { if(mClearedGlobalObjects.ops) { JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { JSDHashEntryHdr* entry = JS_DHashTableOperate(&mClearedGlobalObjects, acx, JS_DHASH_LOOKUP); if(JS_DHASH_ENTRY_IS_BUSY(entry)) { ClearedGlobalObject* clearedGlobal = reinterpret_cast<ClearedGlobalObject*>(entry); JS_CALL_OBJECT_TRACER(trc, clearedGlobal->mGlobalObject, "global object"); } } } XPCWrappedNativeScope::TraceJS(trc, this); for(XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) static_cast<XPCTraceableVariant*>(e)->TraceJS(trc); for(XPCRootSetElem *e = mWrappedJSRoots; e ; e = e->GetNextRoot()) static_cast<nsXPCWrappedJS*>(e)->TraceJS(trc); if(mJSHolders.ops) JS_DHashTableEnumerate(&mJSHolders, TraceJSHolder, trc); }
void XPCJSRuntime::RootContextGlobals() { JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { if(JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL)) { JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL); --mUnrootedGlobalCount; } } NS_ASSERTION(mUnrootedGlobalCount == 0, "bad state"); }
void XPCJSRuntime::ClearWeakRoots() { JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { if(XPCPerThreadData::IsMainThread(acx) && nsXPConnect::GetXPConnect()->GetRequestDepth(acx) == 0) { JS_ClearNewbornRoots(acx); } } }
void XPCJSRuntime::RestoreContextGlobals() { if(!mClearedGlobalObjects.ops || mClearedGlobalObjects.entryCount == 0) return; JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { JSDHashEntryHdr* entry = JS_DHashTableOperate(&mClearedGlobalObjects, acx, JS_DHASH_LOOKUP); if(JS_DHASH_ENTRY_IS_BUSY(entry)) { ClearedGlobalObject* clearedGlobal = reinterpret_cast<ClearedGlobalObject*>(entry); acx->globalObject = clearedGlobal->mGlobalObject; } } JS_DHashTableEnumerate(&mClearedGlobalObjects, RemoveContextGlobal, nsnull); }
void XPCJSRuntime::UnrootContextGlobals() { mUnrootedGlobalCount = 0; JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { NS_ASSERTION(!JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL), "unrooted global should be set only during CC"); if(XPCPerThreadData::IsMainThread(acx) && nsXPConnect::GetXPConnect()->GetRequestDepth(acx) == 0) { JS_ClearNewbornRoots(acx); if(acx->globalObject) { JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL); ++mUnrootedGlobalCount; } } } }
void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc) { JSContext *iter = nsnull, *acx; while ((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { JS_ASSERT(JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL)); if (acx->globalObject) JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "global object"); } XPCWrappedNativeScope::TraceJS(trc, this); for(XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) static_cast<XPCTraceableVariant*>(e)->TraceJS(trc); for(XPCRootSetElem *e = mWrappedJSRoots; e ; e = e->GetNextRoot()) static_cast<nsXPCWrappedJS*>(e)->TraceJS(trc); if(mJSHolders.ops) JS_DHashTableEnumerate(&mJSHolders, TraceJSHolder, trc); }
void XPCJSRuntime::AddXPConnectRoots(JSContext* cx, nsCycleCollectionTraversalCallback &cb) { // For all JS objects that are held by native objects but aren't held // through rooting or locking, we need to add all the native objects that // hold them so that the JS objects are colored correctly in the cycle // collector. This includes JSContexts that don't have outstanding requests, // because their global object wasn't marked by the JS GC. All other JS // roots were marked by the JS GC and will be colored correctly in the cycle // collector. JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { #ifndef DEBUG_CC // Only skip JSContexts with outstanding requests if DEBUG_CC is not // defined, else we do want to know about all JSContexts to get better // graphs and explanations. if(nsXPConnect::GetXPConnect()->GetRequestDepth(acx) != 0) continue; #endif cb.NoteRoot(nsIProgrammingLanguage::CPLUSPLUS, acx, nsXPConnect::JSContextParticipant()); } XPCWrappedNativeScope::SuspectAllWrappers(this, cx, cb); for(XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) cb.NoteXPCOMRoot(static_cast<XPCTraceableVariant*>(e)); for(XPCRootSetElem *e = mWrappedJSRoots; e ; e = e->GetNextRoot()) { nsIXPConnectWrappedJS *wrappedJS = static_cast<nsXPCWrappedJS*>(e); cb.NoteXPCOMRoot(wrappedJS); } if(mJSHolders.ops) JS_DHashTableEnumerate(&mJSHolders, NoteJSHolder, &cb); }
void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc, JSBool rootGlobals) { if(mUnrootedGlobalCount != 0) { JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { if(JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL)) { NS_ASSERTION(nsXPConnect::GetXPConnect()->GetRequestDepth(acx) == 0, "active cx must be always rooted"); NS_ASSERTION(acx->globalObject, "bad state"); JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "global object"); if(rootGlobals) { NS_ASSERTION(mUnrootedGlobalCount != 0, "bad state"); NS_ASSERTION(trc == acx->runtime->gcMarkingTracer, "bad tracer"); JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL); --mUnrootedGlobalCount; } } } } XPCWrappedNativeScope::TraceJS(trc, this); for(XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) static_cast<XPCTraceableVariant*>(e)->TraceJS(trc); for(XPCRootSetElem *e = mWrappedJSRoots; e ; e = e->GetNextRoot()) static_cast<nsXPCWrappedJS*>(e)->TraceJS(trc); if(mJSHolders.ops) JS_DHashTableEnumerate(&mJSHolders, TraceJSHolder, trc); }