Bug 1398601 - Add global/non-syntactic prefix to subscript loader cache draft
authorTed Campbell <tcampbell@mozilla.com>
Tue, 12 Sep 2017 18:05:08 -0400
changeset 664082 ae66d061f6358df228a7bcfabb9f193acb303492
parent 664081 cebdd9b2872b4b7d65caa4b5e82cc9077ff27a35
child 664083 10cdd94404a218b27c15f0645d8729fba0889891
push id79624
push userbmo:tcampbell@mozilla.com
push dateWed, 13 Sep 2017 18:23:23 +0000
bugs1398601
milestone57.0a1
Bug 1398601 - Add global/non-syntactic prefix to subscript loader cache We want to be able to store scripts compiled with or without non-syntactic support in cache when we toggle JSM global sharing. In current code this script is cloned on execution, but with JSM global sharing we have would hit assertions. MozReview-Commit-ID: 2pVTTxLpx6S
js/xpconnect/loader/mozJSSubScriptLoader.cpp
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -84,16 +84,31 @@ mozJSSubScriptLoader::mozJSSubScriptLoad
 }
 
 mozJSSubScriptLoader::~mozJSSubScriptLoader()
 {
 }
 
 NS_IMPL_ISUPPORTS(mozJSSubScriptLoader, mozIJSSubScriptLoader)
 
+#define JSSUB_CACHE_PREFIX(aType) "jssubloader/" aType
+
+static void
+SubscriptCachePath(JSContext* cx, nsIURI* uri, JS::HandleObject targetObj, nsACString& cachePath)
+{
+    // StartupCache must distinguish between non-syntactic vs global, as well as
+    // javascript version when computing the cache key.
+    bool hasNonSyntacticScope = !JS_IsGlobalObject(targetObj);
+    JSVersion version = JS_GetVersion(cx);
+    cachePath.Assign(hasNonSyntacticScope ? JSSUB_CACHE_PREFIX("non-syntactic")
+                                          : JSSUB_CACHE_PREFIX("global"));
+    cachePath.AppendPrintf("/%d", version);
+    PathifyURI(uri, cachePath);
+}
+
 static void
 ReportError(JSContext* cx, const nsACString& msg)
 {
     NS_ConvertUTF8toUTF16 ucMsg(msg);
 
     RootedValue exn(cx);
     if (xpc::NonVoidStringToJsval(cx, ucMsg, &exn)) {
         JS_SetPendingException(cx, exn);
@@ -201,19 +216,17 @@ EvalScript(JSContext* cx,
 
     JSAutoCompartment rac(cx, targetObj);
     if (!JS_WrapValue(cx, retval)) {
         return false;
     }
 
     if (script && (startupCache || preloadCache)) {
         nsAutoCString cachePath;
-        JSVersion version = JS_GetVersion(cx);
-        cachePath.AppendPrintf("jssubloader/%d", version);
-        PathifyURI(uri, cachePath);
+        SubscriptCachePath(cx, uri, targetObj, cachePath);
 
         nsCString uriStr;
         if (preloadCache && NS_SUCCEEDED(uri->GetSpec(uriStr))) {
             // Note that, when called during startup, this will keep the
             // original JSScript object alive for an indefinite amount of time.
             // This has the side-effect of keeping the global that the script
             // was compiled for alive, too.
             //
@@ -656,20 +669,18 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
 
     // Suppress caching if we're compiling as content or if we're loading a
     // blob: URI.
     bool ignoreCache = options.ignoreCache
         || !GetObjectPrincipal(targetObj)->GetIsSystemPrincipal()
         || scheme.EqualsLiteral("blob");
     StartupCache* cache = ignoreCache ? nullptr : StartupCache::GetSingleton();
 
-    JSVersion version = JS_GetVersion(cx);
     nsAutoCString cachePath;
-    cachePath.AppendPrintf("jssubloader/%d", version);
-    PathifyURI(uri, cachePath);
+    SubscriptCachePath(cx, uri, targetObj, cachePath);
 
     RootedScript script(cx);
     if (!options.ignoreCache) {
         if (!options.wantReturnValue)
             script = ScriptPreloader::GetSingleton().GetCachedScript(cx, cachePath);
         if (!script && cache)
             rv = ReadCachedScript(cache, cachePath, cx, &script);
         if (NS_FAILED(rv) || !script) {