Bug 1364118 - List JS bytecode cache preferences in all.js. r=mrbkap
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Thu, 18 May 2017 14:12:15 +0000
changeset 358991 031089f91a7c827aaf579a11db52a995153df7fd
parent 358990 da3f45e77632f87847a79cdbbf2be0679915b36f
child 358992 c67aff0a734d82dd7675392df2e88fc1b805164e
push id90421
push usernpierron@mozilla.com
push dateThu, 18 May 2017 14:12:46 +0000
treeherdermozilla-inbound@031089f91a7c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs1364118
milestone55.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 1364118 - List JS bytecode cache preferences in all.js. r=mrbkap
dom/base/test/test_script_loader_js_cache.html
dom/script/ScriptLoader.cpp
dom/script/ScriptLoader.h
modules/libpref/init/all.js
--- a/dom/base/test/test_script_loader_js_cache.html
+++ b/dom/base/test/test_script_loader_js_cache.html
@@ -111,24 +111,24 @@
 
     promise_test(async function() {
       // Setting dom.expose_test_interfaces pref causes the
       // nsScriptLoadRequest to fire event on script tags, with information
       // about its internal state. The ScriptLoader source send events to
       // trace these and resolve a promise with the path taken by the
       // script loader.
       //
-      // Setting dom.script_loader.force_bytecode_cache causes the
+      // Setting dom.script_loader.bytecode_cache.eager causes the
       // nsScriptLoadRequest to force all the conditions necessary to make a
       // script be saved as bytecode in the alternate data storage provided
       // by the channel (necko cache).
       await SpecialPowers.pushPrefEnv({set: [
         ['dom.script_loader.bytecode_cache.enabled', true],
         ['dom.expose_test_interfaces', true],
-        ['dom.script_loader.force_bytecode_cache', true]
+        ['dom.script_loader.bytecode_cache.eager', true]
       ]});
 
       // Load the test page, and verify that the code path taken by the
       // nsScriptLoadRequest corresponds to the code path which is loading a
       // source and saving it as bytecode.
       var stateMachineResult = WaitForScriptTagEvent("file_js_cache.html");
       assert_equals(await stateMachineResult, "bytecode_saved",
                     "[1] ScriptLoadRequest status after the first visit");
@@ -169,17 +169,17 @@
 
     }, "Check the JS bytecode cache");
 
     promise_test(async function() {
       // (see above)
       await SpecialPowers.pushPrefEnv({set: [
         ['dom.script_loader.bytecode_cache.enabled', true],
         ['dom.expose_test_interfaces', true],
-        ['dom.script_loader.force_bytecode_cache', true]
+        ['dom.script_loader.bytecode_cache.eager', true]
       ]});
 
       // The test page add a new script which generate a "ping" event, which
       // should be recorded before the bytecode is stored in the cache.
       var stateMachineResult =
           WaitForScriptTagEvent("file_js_cache_save_after_load.html");
       assert_equals(await stateMachineResult, "bytecode_saved & ping(=3)",
                     "Wait on all scripts to be executed");
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -813,16 +813,31 @@ ScriptLoader::IsBytecodeCacheEnabled()
     sExposeTestInterfacePrefCached = true;
     Preferences::AddBoolVarCache(&sExposeTestInterfaceEnabled,
                                  "dom.script_loader.bytecode_cache.enabled",
                                  false);
   }
   return sExposeTestInterfaceEnabled;
 }
 
+/* static */ bool
+ScriptLoader::IsEagerBytecodeCache()
+{
+  // When testing, we want to force use of the bytecode cache.
+  static bool sEagerBytecodeCache = false;
+  static bool sForceBytecodeCachePrefCached = false;
+  if (!sForceBytecodeCachePrefCached) {
+    sForceBytecodeCachePrefCached = true;
+    Preferences::AddBoolVarCache(&sEagerBytecodeCache,
+                                 "dom.script_loader.bytecode_cache.eager",
+                                 false);
+  }
+  return sEagerBytecodeCache;
+}
+
 nsresult
 ScriptLoader::RestartLoad(ScriptLoadRequest* aRequest)
 {
   MOZ_ASSERT(aRequest->IsBytecode());
   aRequest->mScriptBytecode.clearAndFree();
   TRACE_FOR_TEST(aRequest->mElement, "scriptloader_fallback");
 
   // Start a new channel from which we explicitly request to stream the source
@@ -1859,29 +1874,20 @@ ScriptLoader::FillCompileOptionsForReque
   MOZ_ASSERT(aRequest->mElement);
   if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, aRequest->mElement,
                                               &elementVal,
                                               /* aAllowWrapping = */ true))) {
     MOZ_ASSERT(elementVal.isObject());
     aOptions->setElement(&elementVal.toObject());
   }
 
-  // When testing, we want to force use of the bytecode cache.
-  static bool sForceBytecodeCacheEnabled = false;
-  static bool sForceBytecodeCachePrefCached = false;
-  if (!sForceBytecodeCachePrefCached) {
-    sForceBytecodeCachePrefCached = true;
-    Preferences::AddBoolVarCache(&sForceBytecodeCacheEnabled,
-                                 "dom.script_loader.force_bytecode_cache",
-                                 false);
-  }
   // At the moment, the bytecode cache is only triggered if a script is large
   // enough to be parsed out of the main thread.  Thus, for testing purposes, we
   // force parsing any script out of the main thread.
-  if (sForceBytecodeCacheEnabled) {
+  if (IsEagerBytecodeCache()) {
     aOptions->forceAsync = true;
   }
 
   return NS_OK;
 }
 
 nsresult
 ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -466,16 +466,19 @@ private:
   ModuleScript* GetFetchedModule(nsIURI* aURL) const;
 
   friend bool
   HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp);
 
   static bool
   IsBytecodeCacheEnabled();
 
+  static bool
+  IsEagerBytecodeCache();
+
   nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
   nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
   void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest);
   bool InstantiateModuleTree(ModuleLoadRequest* aRequest);
   void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest);
 
   RefPtr<mozilla::GenericPromise>
   StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, nsIURI* aURI);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -204,16 +204,26 @@ pref("dom.gamepad.extensions.enabled", f
 // even if this is true).
 pref("dom.keyboardevent.dispatch_during_composition", false);
 
 // Whether to run add-on code in different compartments from browser code. This
 // causes a separate compartment for each (addon, global) combination, which may
 // significantly increase the number of compartments in the system.
 pref("dom.compartment_per_addon", true);
 
+// Whether to enable the JavaScript start-up cache. This causes one of the first
+// execution to record the bytecode of the JavaScript function used, and save it
+// in the existing cache entry. On the following loads of the same script, the
+// bytecode would be loaded from the cache instead of being generated once more.
+pref("dom.script_loader.bytecode_cache.enabled", false); // Not tuned yet.
+
+// Ignore the heuristics of the bytecode cache, and always record on the first
+// visit. (used for testing purposes).
+pref("dom.script_loader.bytecode_cache.eager", false);
+
 // Fastback caching - if this pref is negative, then we calculate the number
 // of content viewers to cache based on the amount of available memory.
 pref("browser.sessionhistory.max_total_viewers", -1);
 
 pref("ui.use_native_colors", true);
 pref("ui.click_hold_context_menus", false);
 // Duration of timeout of incremental search in menus (ms).  0 means infinite.
 pref("ui.menu.incremental_search.timeout", 1000);