Bug 990353 - Flag for discarding where appropriate. r=bent
authorBobby Holley <bobbyholley@gmail.com>
Tue, 22 Apr 2014 14:08:28 -0700
changeset 179646 42aaedb9345585d7c51332a4b6d47a4762a1dac1
parent 179645 26a22df461a295204f77b122230aec0bf00da687
child 179647 6f6abed86df788f06c6567c730505985eddb841f
push id42573
push userbobbyholley@gmail.com
push dateTue, 22 Apr 2014 21:09:44 +0000
treeherdermozilla-inbound@a256a26923ff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs990353
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 990353 - Flag for discarding where appropriate. r=bent
dom/workers/ScriptLoader.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/nsXPConnect.cpp
--- 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) ||