mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
Bug 983399 - Make mozComponentLoader work with moving GC; r=sfink
--HG-- extra : rebase_source : d5d04949c97be80bdf2212f82493686bd4a6cb28
This commit is contained in:
parent
a4d8236090
commit
02c8e710e7
@ -309,7 +309,6 @@ mozJSComponentLoader::mozJSComponentLoader()
|
||||
mModules(32),
|
||||
mImports(32),
|
||||
mInProgressImports(32),
|
||||
mThisObjects(32),
|
||||
mInitialized(false),
|
||||
mReuseLoaderGlobal(false)
|
||||
{
|
||||
@ -342,6 +341,36 @@ NS_IMPL_ISUPPORTS3(mozJSComponentLoader,
|
||||
xpcIJSModuleLoader,
|
||||
nsIObserver)
|
||||
|
||||
static void
|
||||
TraceComponentLoader(JSTracer* trc, void* data)
|
||||
{
|
||||
auto loader = mozJSComponentLoader::Get();
|
||||
if (loader) {
|
||||
MOZ_ASSERT(data == loader);
|
||||
loader->Trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mozJSComponentLoader::Trace(JSTracer *trc)
|
||||
{
|
||||
if (!mInitialized || !mThisObjects.initialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mReuseLoaderGlobal) {
|
||||
MOZ_ASSERT(mThisObjects.empty());
|
||||
return;
|
||||
}
|
||||
|
||||
for (ThisObjectsMap::Range r = mThisObjects.all(); !r.empty(); r.popFront()) {
|
||||
JS_CallScriptTracer(trc, const_cast<JSScript**>(&r.front().key()),
|
||||
"mozJSComponentLoader::mThisObjects key");
|
||||
JS_CallHeapObjectTracer(trc, &r.front().value(),
|
||||
"mozJSComponentLoader::mThisObjects value");
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
mozJSComponentLoader::ReallyInit()
|
||||
{
|
||||
@ -366,6 +395,12 @@ mozJSComponentLoader::ReallyInit()
|
||||
NS_FAILED(rv = mRuntimeService->GetRuntime(&mRuntime)))
|
||||
return rv;
|
||||
|
||||
if (!mThisObjects.init(32))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (!JS_AddExtraGCRootsTracer(mRuntime, TraceComponentLoader, this))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Create our compilation context.
|
||||
mContext = JS_NewContext(mRuntime, 256);
|
||||
if (!mContext)
|
||||
@ -415,7 +450,7 @@ mozJSComponentLoader::LoadModule(FileLocation &aFile)
|
||||
if (mModules.Get(spec, &mod))
|
||||
return mod;
|
||||
|
||||
nsAutoPtr<ModuleEntry> entry(new ModuleEntry);
|
||||
nsAutoPtr<ModuleEntry> entry(new ModuleEntry(mContext));
|
||||
|
||||
JSAutoRequest ar(mContext);
|
||||
RootedValue dummy(mContext);
|
||||
@ -524,7 +559,10 @@ mozJSComponentLoader::FindTargetObject(JSContext* aCx,
|
||||
JSScript* script =
|
||||
js::GetOutermostEnclosingFunctionOfScriptedCaller(aCx);
|
||||
if (script) {
|
||||
targetObject = mThisObjects.Get(script);
|
||||
ThisObjectsMap::Ptr p = mThisObjects.lookup(script);
|
||||
if (p.found()) {
|
||||
targetObject = p->value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -562,11 +600,13 @@ mozJSComponentLoader::FindTargetObject(JSContext* aCx,
|
||||
void
|
||||
mozJSComponentLoader::NoteSubScript(HandleScript aScript, HandleObject aThisObject)
|
||||
{
|
||||
if (!mInitialized && NS_FAILED(ReallyInit())) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
if (!mInitialized && NS_FAILED(ReallyInit())) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
mThisObjects.Put(aScript, aThisObject);
|
||||
if (mReuseLoaderGlobal && !mThisObjects.put(aScript, aThisObject)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ size_t
|
||||
@ -595,7 +635,7 @@ mozJSComponentLoader::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
|
||||
amount += mModules.SizeOfExcludingThis(DataEntrySizeOfExcludingThis, aMallocSizeOf);
|
||||
amount += mImports.SizeOfExcludingThis(ClassEntrySizeOfExcludingThis, aMallocSizeOf);
|
||||
amount += mInProgressImports.SizeOfExcludingThis(DataEntrySizeOfExcludingThis, aMallocSizeOf);
|
||||
amount += mThisObjects.SizeOfExcludingThis(nullptr, aMallocSizeOf);
|
||||
amount += mThisObjects.sizeOfExcludingThis(aMallocSizeOf);
|
||||
|
||||
return amount;
|
||||
}
|
||||
@ -740,8 +780,8 @@ mozJSComponentLoader::PrepareObjectForLocation(JSCLContextHelper& aCx,
|
||||
nsresult
|
||||
mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
||||
nsIURI *aURI,
|
||||
JSObject **aObject,
|
||||
JSScript **aTableScript,
|
||||
JS::MutableHandle<JSObject*> aObject,
|
||||
JS::MutableHandle<JSScript*> aTableScript,
|
||||
char **aLocation,
|
||||
bool aPropagateExceptions,
|
||||
MutableHandleValue aException)
|
||||
@ -988,7 +1028,7 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
||||
|
||||
// Assign aObject here so that it's available to recursive imports.
|
||||
// See bug 384168.
|
||||
*aObject = obj;
|
||||
aObject.set(obj);
|
||||
|
||||
RootedScript tableScript(cx, script);
|
||||
if (!tableScript) {
|
||||
@ -996,12 +1036,14 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
||||
MOZ_ASSERT(tableScript);
|
||||
}
|
||||
|
||||
*aTableScript = tableScript;
|
||||
aTableScript.set(tableScript);
|
||||
|
||||
// tableScript stays in the table until shutdown. To avoid it being
|
||||
// collected and another script getting the same address, we root
|
||||
// tableScript lower down in this function.
|
||||
mThisObjects.Put(tableScript, obj);
|
||||
if (mReuseLoaderGlobal && !mThisObjects.put(tableScript, JS::Heap<JSObject*>(obj))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
bool ok = false;
|
||||
|
||||
{
|
||||
@ -1021,23 +1063,21 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
||||
JS_GetPendingException(cx, aException);
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
*aObject = nullptr;
|
||||
*aTableScript = nullptr;
|
||||
mThisObjects.Remove(tableScript);
|
||||
aObject.set(nullptr);
|
||||
aTableScript.set(nullptr);
|
||||
mThisObjects.remove(tableScript);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* Freed when we remove from the table. */
|
||||
*aLocation = ToNewCString(nativePath);
|
||||
if (!*aLocation) {
|
||||
*aObject = nullptr;
|
||||
*aTableScript = nullptr;
|
||||
mThisObjects.Remove(tableScript);
|
||||
aObject.set(nullptr);
|
||||
aTableScript.set(nullptr);
|
||||
mThisObjects.remove(tableScript);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
JS_AddNamedObjectRoot(cx, aObject, *aLocation);
|
||||
JS_AddNamedScriptRoot(cx, aTableScript, *aLocation);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1070,7 +1110,7 @@ mozJSComponentLoader::UnloadModules()
|
||||
|
||||
mInProgressImports.Clear();
|
||||
mImports.Clear();
|
||||
mThisObjects.Clear();
|
||||
mThisObjects.clear();
|
||||
|
||||
mModules.Enumerate(ClearModules, nullptr);
|
||||
|
||||
@ -1219,7 +1259,7 @@ mozJSComponentLoader::ImportInto(const nsACString &aLocation,
|
||||
ModuleEntry* mod;
|
||||
nsAutoPtr<ModuleEntry> newEntry;
|
||||
if (!mImports.Get(key, &mod) && !mInProgressImports.Get(key, &mod)) {
|
||||
newEntry = new ModuleEntry;
|
||||
newEntry = new ModuleEntry(callercx);
|
||||
if (!newEntry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mInProgressImports.Put(key, newEntry);
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "jsapi.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
#include "xpcIJSGetFactory.h"
|
||||
|
||||
@ -59,6 +61,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
void Trace(JSTracer *trc);
|
||||
|
||||
protected:
|
||||
static mozJSComponentLoader* sSelf;
|
||||
|
||||
@ -73,8 +77,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
|
||||
nsresult ObjectForLocation(nsIFile* aComponentFile,
|
||||
nsIURI *aComponent,
|
||||
JSObject **aObject,
|
||||
JSScript **aTableScript,
|
||||
JS::MutableHandle<JSObject*> aObject,
|
||||
JS::MutableHandle<JSScript*> aTableScript,
|
||||
char **location,
|
||||
bool aCatchException,
|
||||
JS::MutableHandleValue aException);
|
||||
@ -94,7 +98,7 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
class ModuleEntry : public mozilla::Module
|
||||
{
|
||||
public:
|
||||
ModuleEntry() : mozilla::Module() {
|
||||
ModuleEntry(JSContext *cx) : mozilla::Module(), obj(cx), thisObjectKey(cx) {
|
||||
mVersion = mozilla::Module::kVersion;
|
||||
mCIDs = nullptr;
|
||||
mContractIDs = nullptr;
|
||||
@ -120,9 +124,6 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
JS_SetAllNonReservedSlotsToUndefined(cx, obj);
|
||||
JS_RemoveObjectRoot(cx, &obj);
|
||||
if (thisObjectKey)
|
||||
JS_RemoveScriptRoot(cx, &thisObjectKey);
|
||||
}
|
||||
|
||||
if (location)
|
||||
@ -139,9 +140,9 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
const mozilla::Module::CIDEntry& entry);
|
||||
|
||||
nsCOMPtr<xpcIJSGetFactory> getfactoryobj;
|
||||
JSObject *obj;
|
||||
JSScript *thisObjectKey;
|
||||
char *location;
|
||||
JS::PersistentRooted<JSObject*> obj;
|
||||
JS::PersistentRooted<JSScript*> thisObjectKey;
|
||||
char *location;
|
||||
};
|
||||
|
||||
friend class ModuleEntry;
|
||||
@ -158,7 +159,11 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
|
||||
nsClassHashtable<nsCStringHashKey, ModuleEntry> mImports;
|
||||
nsDataHashtable<nsCStringHashKey, ModuleEntry*> mInProgressImports;
|
||||
nsDataHashtable<nsPtrHashKey<JSScript>, JSObject*> mThisObjects;
|
||||
typedef js::HashMap<JSScript*,
|
||||
JS::Heap<JSObject*>,
|
||||
js::PointerHasher<JSScript*, 3>,
|
||||
js::SystemAllocPolicy> ThisObjectsMap;
|
||||
ThisObjectsMap mThisObjects;
|
||||
|
||||
bool mInitialized;
|
||||
bool mReuseLoaderGlobal;
|
||||
|
Loading…
Reference in New Issue
Block a user