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 id6
push usergsharp@mozilla.com
push dateFri, 17 Jun 2011 14:49:53 +0000
treeherderfx-team@9ac190a247ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstaras
bugs592943
milestone7.0a1
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_