Bug 990353 - Flag for discarding where appropriate. r=bent
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -694,16 +694,30 @@ ScriptExecutorRunnable::WorkerRun(JSCont
if (!loadInfo.mExecutionResult) {
return true;
}
}
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
NS_ASSERTION(global, "Must have a global by now!");
+ // Determine whether we want to be discarding source on this global to save
+ // memory. It would make more sense to do this when we create the global, but
+ // the information behind UsesSystemPrincipal() et al isn't finalized until
+ // the call to SetPrincipal during the first script load. After that, however,
+ // it never changes. So we can just idempotently set the bits here.
+ //
+ // Note that we read a pref that is cached on the main thread. This is benignly
+ // racey.
+ if (xpc::ShouldDiscardSystemSource()) {
+ bool discard = aWorkerPrivate->UsesSystemPrincipal() ||
+ aWorkerPrivate->IsInPrivilegedApp();
+ JS::CompartmentOptionsRef(global).setDiscardSource(discard);
+ }
+
for (uint32_t index = mFirstIndex; index <= mLastIndex; index++) {
ScriptLoadInfo& loadInfo = loadInfos.ElementAt(index);
NS_ASSERTION(!loadInfo.mChannel, "Should no longer have a channel!");
NS_ASSERTION(loadInfo.mExecutionScheduled, "Should be scheduled!");
NS_ASSERTION(!loadInfo.mExecutionResult, "Should not have executed yet!");
if (NS_FAILED(loadInfo.mLoadResult)) {
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -3505,16 +3505,17 @@ XPCJSRuntime::GetCompilationScope()
SandboxOptions options;
options.sandboxName.AssignLiteral("XPConnect Compilation Compartment");
options.invisibleToDebugger = true;
RootedValue v(cx);
nsresult rv = CreateSandboxObject(cx, &v, /* principal = */ nullptr, options);
NS_ENSURE_SUCCESS(rv, nullptr);
mCompilationScope = js::UncheckedUnwrap(&v.toObject());
+ CompartmentOptionsRef(mCompilationScope).setDiscardSource(ShouldDiscardSystemSource());
}
return mCompilationScope;
}
void
XPCJSRuntime::DeleteSingletonScopes()
{
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -409,16 +409,27 @@ InitGlobalObject(JSContext* aJSContext,
if (!(aFlags & nsIXPConnect::OMIT_COMPONENTS_OBJECT)) {
// XPCCallContext gives us an active request needed to save/restore.
if (!GetCompartmentPrivate(aGlobal)->scope->AttachComponentsObject(aJSContext) ||
!XPCNativeWrapper::AttachNewConstructorObject(aJSContext, aGlobal)) {
return UnexpectedFailure(false);
}
}
+ if (ShouldDiscardSystemSource()) {
+ nsIPrincipal *prin = GetObjectPrincipal(aGlobal);
+ bool isSystem = nsContentUtils::IsSystemPrincipal(prin);
+ if (!isSystem) {
+ short status = prin->GetAppStatus();
+ isSystem = status == nsIPrincipal::APP_STATUS_PRIVILEGED ||
+ status == nsIPrincipal::APP_STATUS_CERTIFIED;
+ }
+ JS::CompartmentOptionsRef(aGlobal).setDiscardSource(isSystem);
+ }
+
// Stuff coming through this path always ends up as a DOM global.
MOZ_ASSERT(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL);
// Init WebIDL binding constructors wanted on all XPConnect globals.
//
// XXX Please do not add any additional classes here without the approval of
// the XPConnect module owner.
if (!PromiseBinding::GetConstructorObject(aJSContext, aGlobal) ||