Bug 592943 - (3/5) Move PathifyURI to StartupCacheUtils, r=taras
authorMichael Wu <mwu@mozilla.com>
Thu, 16 Jun 2011 12:54:47 +0800
changeset 71171 743bc4458fc11da351ec5acdd43e4e6d8a4375da
parent 71170 6e3813929a579e8c877c079fc1655639c53c8cc5
child 71172 8468c5916b757c7f2938feb68d87a9785eec8c2e
push id20498
push usermlamouri@mozilla.com
push dateThu, 16 Jun 2011 09:33:31 +0000
treeherdermozilla-central@a09dfe6c7c19 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstaras
bugs592943
milestone7.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 592943 - (3/5) Move PathifyURI to StartupCacheUtils, r=taras
js/src/xpconnect/loader/mozJSComponentLoader.cpp
startupcache/StartupCacheUtils.cpp
startupcache/StartupCacheUtils.h
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -92,16 +92,17 @@
 
 #include "jsdbgapi.h"
 
 #include "mozilla/FunctionTimer.h"
 
 static const char kJSRuntimeServiceContractID[] = "@mozilla.org/js/xpc/RuntimeService;1";
 static const char kXPConnectServiceContractID[] = "@mozilla.org/js/xpc/XPConnect;1";
 static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1";
+static const char kJSCachePrefix[] = "jsloader";
 
 /* Some platforms don't have an implementation of PR_MemMap(). */
 #ifndef XP_OS2
 #define HAVE_PR_MEMMAP
 #endif
 
 /**
  * Buffer sizes for serialization and deserialization of scripts.
@@ -793,149 +794,25 @@ class JSPrincipalsHolder
     JSPrincipalsHolder(JSContext *cx, JSPrincipals *principals)
         : mCx(cx), mPrincipals(principals) {}
     ~JSPrincipalsHolder() { JSPRINCIPALS_DROP(mCx, mPrincipals); }
  private:
     JSContext *mCx;
     JSPrincipals *mPrincipals;
 };
 
-static const char baseName[2][5] = { "gre/", "app/" };
-
-static inline PRBool
-canonicalizeBase(nsCAutoString &spec, nsACString &out, mozilla::Omnijar::Type aType)
-{
-    nsCAutoString base;
-    nsresult rv = mozilla::Omnijar::GetURIString(aType, base);
-
-    if (NS_FAILED(rv) || !base.Length())
-        return PR_FALSE;
-
-    if (base.Compare(spec.get(), PR_FALSE, base.Length()))
-        return PR_FALSE;
-
-    out.Append("/resource/");
-    out.Append(baseName[aType]);
-    out.Append(Substring(spec, base.Length()));
-    return PR_TRUE;
-}
-/**
- * PathifyURI transforms mozilla .js uris into useful zip paths
- * to make it makes it easier to manipulate startup cache entries
- * using standard zip tools.
- * Transformations applied:
- *  * jsloader/ prefix is used to group mozJSComponentLoader cache entries in
- *    a top-level zip directory.
- *  * resource:// URIs are resolved to their corresponding file/jar URI to
- *    canonicalize resources URIs other than gre and app.
- *  * Paths under GRE or APP directory have their base path replaced with
- *    resource/gre or resource/app to avoid depending on install location.
- *  * jar:file:///path/to/file.jar!/sub/path urls are replaced with
- *    /path/to/file.jar/sub/path
- *  * .bin suffix is added to the end of the path to indicate that jsloader/ entries
- *     are binary representations of JS source.
- * For example:
- *  resource://gre/modules/XPCOMUtils.jsm or
- *  file://$GRE_DIR/modules/XPCOMUtils.jsm or
- *  jar:file://$GRE_DIR/omni.jar!/modules/XPCOMUtils.jsm become
- *     jsloader/resource/gre/modules/XPCOMUtils.jsm.bin
- *  file://$PROFILE_DIR/extensions/{uuid}/components/component.js becomes
- *     jsloader/$PROFILE_DIR/extensions/%7Buuid%7D/components/component.js.bin
- *  jar:file://$PROFILE_DIR/extensions/some.xpi!/components/component.js becomes
- *     jsloader/$PROFILE_DIR/extensions/some.xpi/components/component.js.bin
- */
-static nsresult
-PathifyURI(nsIURI *in, nsACString &out)
-{ 
-    PRBool equals;
-    nsresult rv;
-    nsCOMPtr<nsIURI> uri = in;
-    nsCAutoString spec;
-
-    out = "jsloader";
-
-    // Resolve resource:// URIs. At the end of this if/else block, we
-    // have both spec and uri variables identifying the same URI.
-    if (NS_SUCCEEDED(in->SchemeIs("resource", &equals)) && equals) {
-        nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        nsCOMPtr<nsIProtocolHandler> ph;
-        rv = ioService->GetProtocolHandler("resource", getter_AddRefs(ph));
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        nsCOMPtr<nsIResProtocolHandler> irph(do_QueryInterface(ph, &rv));
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rv = irph->ResolveURI(in, spec);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rv = ioService->NewURI(spec, nsnull, nsnull, getter_AddRefs(uri));
-        NS_ENSURE_SUCCESS(rv, rv);
-    } else {
-        rv = in->GetSpec(spec);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    if (!canonicalizeBase(spec, out, mozilla::Omnijar::GRE) &&
-        !canonicalizeBase(spec, out, mozilla::Omnijar::APP)) {
-        if (NS_SUCCEEDED(uri->SchemeIs("file", &equals)) && equals) {
-            nsCOMPtr<nsIFileURL> baseFileURL;
-            baseFileURL = do_QueryInterface(uri, &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCAutoString path;
-            rv = baseFileURL->GetPath(path);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            out.Append(path);
-        } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &equals)) && equals) {
-            nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(uri, &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCOMPtr<nsIURI> jarFileURI;
-            rv = jarURI->GetJARFile(getter_AddRefs(jarFileURI));
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCOMPtr<nsIFileURL> jarFileURL;
-            jarFileURL = do_QueryInterface(jarFileURI, &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCAutoString path;
-            rv = jarFileURL->GetPath(path);
-            NS_ENSURE_SUCCESS(rv, rv);
-            out.Append(path);
-
-            rv = jarURI->GetJAREntry(path);
-            NS_ENSURE_SUCCESS(rv, rv);
-            out.Append("/");
-            out.Append(path);
-        } else { // Very unlikely
-            nsCAutoString spec;
-            rv = uri->GetSpec(spec);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            out.Append("/");
-            out.Append(spec);
-        }
-    }
-
-    out.Append(".bin");
-    return NS_OK;
-}
-
 /* static */
 nsresult
 mozJSComponentLoader::ReadScript(StartupCache* cache, nsIURI *uri,
                                  JSContext *cx, JSObject **scriptObj)
 {
     nsresult rv;
     
-    nsCAutoString spec;
-    rv = PathifyURI(uri, spec);
+    nsCAutoString spec(kJSCachePrefix);
+    rv = NS_PathifyURI(uri, spec);
     NS_ENSURE_SUCCESS(rv, rv);
     
     nsAutoArrayPtr<char> buf;   
     PRUint32 len;
     rv = cache->GetBuffer(spec.get(), getter_Transfers(buf), 
                           &len);
     if (NS_FAILED(rv)) {
         return rv; // don't warn since NOT_AVAILABLE is an ok error
@@ -951,18 +828,18 @@ mozJSComponentLoader::ReadScript(Startup
 }
 
 nsresult
 mozJSComponentLoader::WriteScript(StartupCache* cache, JSObject *scriptObj,
                                   nsIFile *component, nsIURI *uri, JSContext *cx)
 {
     nsresult rv;
 
-    nsCAutoString spec;
-    rv = PathifyURI(uri, spec);
+    nsCAutoString spec(kJSCachePrefix);
+    rv = NS_PathifyURI(uri, spec);
     NS_ENSURE_SUCCESS(rv, rv);
 
     LOG(("Writing %s to startupcache\n", spec.get()));
     nsCOMPtr<nsIObjectOutputStream> oos;
     nsCOMPtr<nsIStorageStream> storageStream; 
     rv = NS_NewObjectOutputWrappedStorageStream(getter_AddRefs(oos),
                                                 getter_AddRefs(storageStream));
     NS_ENSURE_SUCCESS(rv, rv);
--- a/startupcache/StartupCacheUtils.cpp
+++ b/startupcache/StartupCacheUtils.cpp
@@ -1,15 +1,19 @@
 
 #include "nsCOMPtr.h"
 #include "nsIInputStream.h"
 #include "nsIStringStream.h"
+#include "nsNetUtil.h"
+#include "nsIJARURI.h"
+#include "nsIResProtocolHandler.h"
 #include "nsAutoPtr.h"
 #include "StartupCacheUtils.h"
 #include "mozilla/scache/StartupCache.h"
+#include "mozilla/Omnijar.h"
 
 namespace mozilla {
 namespace scache {
 
 NS_EXPORT nsresult
 NS_NewObjectInputStreamFromBuffer(char* buffer, PRUint32 len, 
                                   nsIObjectInputStream** stream)
 {
@@ -79,10 +83,135 @@ NS_NewBufferFromStorageStream(nsIStorage
     return rv;
   }
   
   *len = avail;
   *buffer = temp.forget();
   return NS_OK;
 }
 
+static const char baseName[2][5] = { "gre/", "app/" };
+
+static inline PRBool
+canonicalizeBase(nsCAutoString &spec,
+                 nsACString &out,
+                 mozilla::Omnijar::Type aType)
+{
+    nsCAutoString base;
+    nsresult rv = mozilla::Omnijar::GetURIString(aType, base);
+
+    if (NS_FAILED(rv) || !base.Length())
+        return PR_FALSE;
+
+    if (base.Compare(spec.get(), PR_FALSE, base.Length()))
+        return PR_FALSE;
+
+    out.Append("/resource/");
+    out.Append(baseName[aType]);
+    out.Append(Substring(spec, base.Length()));
+    return PR_TRUE;
+}
+
+/**
+ * PathifyURI transforms uris into useful zip paths
+ * to make it easier to manipulate startup cache entries
+ * using standard zip tools.
+ * Transformations applied:
+ *  * resource:// URIs are resolved to their corresponding file/jar URI to
+ *    canonicalize resources URIs other than gre and app.
+ *  * Paths under GRE or APP directory have their base path replaced with
+ *    resource/gre or resource/app to avoid depending on install location.
+ *  * jar:file:///path/to/file.jar!/sub/path urls are replaced with
+ *    /path/to/file.jar/sub/path
+ *  * .bin suffix is added to the end of the path to indicate that jsloader/ entries
+ *     are binary representations of JS source.
+ *  The result is appended to the string passed in, and it is recommended
+ *  to add some sort of prefix before calling to group types of entries
+ * For example, in the js loader:
+ *  resource://gre/modules/XPCOMUtils.jsm or
+ *  file://$GRE_DIR/modules/XPCOMUtils.jsm or
+ *  jar:file://$GRE_DIR/omni.jar!/modules/XPCOMUtils.jsm become
+ *     jsloader/resource/gre/modules/XPCOMUtils.jsm.bin
+ *  file://$PROFILE_DIR/extensions/{uuid}/components/component.js becomes
+ *     jsloader/$PROFILE_DIR/extensions/%7Buuid%7D/components/component.js.bin
+ *  jar:file://$PROFILE_DIR/extensions/some.xpi!/components/component.js becomes
+ *     jsloader/$PROFILE_DIR/extensions/some.xpi/components/component.js.bin
+ */
+NS_EXPORT nsresult
+NS_PathifyURI(nsIURI *in, nsACString &out)
+{
+    PRBool equals;
+    nsresult rv;
+    nsCOMPtr<nsIURI> uri = in;
+    nsCAutoString spec;
+
+    // Resolve resource:// URIs. At the end of this if/else block, we
+    // have both spec and uri variables identifying the same URI.
+    if (NS_SUCCEEDED(in->SchemeIs("resource", &equals)) && equals) {
+        nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        nsCOMPtr<nsIProtocolHandler> ph;
+        rv = ioService->GetProtocolHandler("resource", getter_AddRefs(ph));
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        nsCOMPtr<nsIResProtocolHandler> irph(do_QueryInterface(ph, &rv));
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        rv = irph->ResolveURI(in, spec);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        rv = ioService->NewURI(spec, nsnull, nsnull, getter_AddRefs(uri));
+        NS_ENSURE_SUCCESS(rv, rv);
+    } else {
+        rv = in->GetSpec(spec);
+        NS_ENSURE_SUCCESS(rv, rv);
+    }
+
+    if (!canonicalizeBase(spec, out, mozilla::Omnijar::GRE) &&
+        !canonicalizeBase(spec, out, mozilla::Omnijar::APP)) {
+        if (NS_SUCCEEDED(uri->SchemeIs("file", &equals)) && equals) {
+            nsCOMPtr<nsIFileURL> baseFileURL;
+            baseFileURL = do_QueryInterface(uri, &rv);
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            nsCAutoString path;
+            rv = baseFileURL->GetPath(path);
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            out.Append(path);
+        } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &equals)) && equals) {
+            nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(uri, &rv);
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            nsCOMPtr<nsIURI> jarFileURI;
+            rv = jarURI->GetJARFile(getter_AddRefs(jarFileURI));
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            nsCOMPtr<nsIFileURL> jarFileURL;
+            jarFileURL = do_QueryInterface(jarFileURI, &rv);
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            nsCAutoString path;
+            rv = jarFileURL->GetPath(path);
+            NS_ENSURE_SUCCESS(rv, rv);
+            out.Append(path);
+
+            rv = jarURI->GetJAREntry(path);
+            NS_ENSURE_SUCCESS(rv, rv);
+            out.Append("/");
+            out.Append(path);
+        } else { // Very unlikely
+            nsCAutoString spec;
+            rv = uri->GetSpec(spec);
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            out.Append("/");
+            out.Append(spec);
+        }
+    }
+
+    out.Append(".bin");
+    return NS_OK;
+}
+
 }
 }
--- a/startupcache/StartupCacheUtils.h
+++ b/startupcache/StartupCacheUtils.h
@@ -53,11 +53,14 @@ NS_NewObjectInputStreamFromBuffer(char* 
 // so we return it here.
 NS_EXPORT nsresult
 NS_NewObjectOutputWrappedStorageStream(nsIObjectOutputStream **wrapperStream,
                                        nsIStorageStream** stream);
 
 NS_EXPORT nsresult
 NS_NewBufferFromStorageStream(nsIStorageStream *storageStream, 
                               char** buffer, PRUint32* len);
+
+NS_EXPORT nsresult
+NS_PathifyURI(nsIURI *in, nsACString &out);
 }
 }
 #endif //nsStartupCacheUtils_h_