Bug 1366402: Use AutoMemMap helper in mozJSComponentLoader. r=mccr8
authorKris Maglione <maglione.k@gmail.com>
Sat, 20 May 2017 12:20:35 -0700
changeset 410431 4d78fccf03b43ff103be9339a705402b7da66602
parent 410430 4e0dc2b1aebdb1f9bf160117d8f714ddcf7d0079
child 410432 af18a71db2946e60778fc8c4666fad11e883eb49
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1366402, 989373
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 1366402: Use AutoMemMap helper in mozJSComponentLoader. r=mccr8 This helper is already being used in the script preloader, and encapsulates all of the memory mapping and RAII logic used to do the same in the component loader. Reusing it there allows us to remove a lot of redundant code. This is applied on top of the patches for bug 989373 in order to avoid conflicts. MozReview-Commit-ID: AJ26qV4JLci
js/xpconnect/loader/ScriptPreloader-inl.h
js/xpconnect/loader/mozJSComponentLoader.cpp
--- a/js/xpconnect/loader/ScriptPreloader-inl.h
+++ b/js/xpconnect/loader/ScriptPreloader-inl.h
@@ -15,16 +15,32 @@
 #include "mozilla/Unused.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "nsString.h"
 #include "nsTArray.h"
 
 #include <prio.h>
 
 namespace mozilla {
+
+// A specialization of GenericErrorResult which auto-converts to a nsresult.
+// This should be removed when bug 1366511 is fixed.
+template <>
+class MOZ_MUST_USE_TYPE GenericErrorResult<nsresult>
+{
+  nsresult mErrorValue;
+
+  template<typename V, typename E2> friend class Result;
+
+public:
+  explicit GenericErrorResult(nsresult aErrorValue) : mErrorValue(aErrorValue) {}
+
+  operator nsresult() { return mErrorValue; }
+};
+
 namespace loader {
 
 using mozilla::dom::AutoJSAPI;
 
 struct MOZ_RAII AutoSafeJSAPI : public AutoJSAPI
 {
     AutoSafeJSAPI() { Init(); }
 };
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -34,28 +34,32 @@
 #include "nsJSPrincipals.h"
 #include "nsJSUtils.h"
 #include "xpcprivate.h"
 #include "xpcpublic.h"
 #include "nsContentUtils.h"
 #include "nsXULAppAPI.h"
 #include "WrapperFactory.h"
 
+#include "AutoMemMap.h"
+#include "ScriptPreloader-inl.h"
+
 #include "mozilla/AddonPathService.h"
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #include "mozilla/MacroForEach.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ScriptPreloader.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/UniquePtrExtensions.h"
 #include "mozilla/Unused.h"
 
 using namespace mozilla;
 using namespace mozilla::scache;
+using namespace mozilla::loader;
 using namespace xpc;
 using namespace JS;
 
 static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1";
 static const char kJSCachePrefix[] = "jsloader";
 
 /**
  * Buffer sizes for serialization and deserialization of scripts.
@@ -501,35 +505,16 @@ mozJSComponentLoader::CreateLoaderGlobal
     if (!JS_DefineFunctions(aCx, global, gGlobalFun) ||
         !JS_DefineProfilingFunctions(aCx, global)) {
         return;
     }
 
     aGlobal.set(global);
 }
 
-// Some stack based classes for cleaning up on early return
-class FileAutoCloser
-{
- public:
-    explicit FileAutoCloser(PRFileDesc* file) : mFile(file) {}
-    ~FileAutoCloser() { PR_Close(mFile); }
- private:
-    PRFileDesc* mFile;
-};
-
-class FileMapAutoCloser
-{
- public:
-    explicit FileMapAutoCloser(PRFileMap* map) : mMap(map) {}
-    ~FileMapAutoCloser() { PR_CloseFileMap(mMap); }
- private:
-    PRFileMap* mMap;
-};
-
 JSObject*
 mozJSComponentLoader::PrepareObjectForLocation(JSContext* aCx,
                                                nsIFile* aComponentFile,
                                                nsIURI* aURI,
                                                bool* aRealFile)
 {
     RootedObject globalObj(aCx);
 
@@ -666,64 +651,23 @@ mozJSComponentLoader::ObjectForLocation(
         // See bug 1303754.
         CompileOptions options(cx);
         options.setNoScriptRval(true)
                .setVersion(JSVERSION_LATEST)
                .setFileAndLine(nativePath.get(), 1)
                .setSourceIsLazy(!!cache);
 
         if (realFile) {
-            int64_t fileSize;
-            rv = aComponentFile->GetFileSize(&fileSize);
-            if (NS_FAILED(rv)) {
-                return rv;
-            }
-
-            int64_t maxSize = UINT32_MAX;
-            if (fileSize > maxSize) {
-                NS_ERROR("file too large");
-                return NS_ERROR_FAILURE;
-            }
-
-            PRFileDesc* fileHandle;
-            rv = aComponentFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle);
-            if (NS_FAILED(rv)) {
-                return NS_ERROR_FILE_NOT_FOUND;
-            }
-
-            // Make sure the file is closed, no matter how we return.
-            FileAutoCloser fileCloser(fileHandle);
-
-            // We don't provide the file size here.  If we did, PR_CreateFileMap
-            // would simply stat() the file to verify that the size we provided
-            // didn't require extending the file.  We know that the file doesn't
-            // need to be extended, so skip the extra work by not providing the
-            // size.
-            PRFileMap* map = PR_CreateFileMap(fileHandle, 0, PR_PROT_READONLY);
-            if (!map) {
-                NS_ERROR("Failed to create file map");
-                return NS_ERROR_FAILURE;
-            }
-
-            // Make sure the file map is closed, no matter how we return.
-            FileMapAutoCloser mapCloser(map);
-
-            uint32_t fileSize32 = fileSize;
-
-            char* buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32));
-            if (!buf) {
-                NS_WARNING("Failed to map file");
-                return NS_ERROR_FAILURE;
-            }
+            AutoMemMap map;
+            MOZ_TRY(map.init(aComponentFile));
 
             // Note: exceptions will get handled further down;
             // don't early return for them here.
-            Compile(cx, options, buf, fileSize32, &script);
-
-            PR_MemUnmap(buf, fileSize32);
+            auto buf = map.get<char>();
+            Compile(cx, options, buf.get(), map.size(), &script);
         } else {
             rv = aInfo.EnsureScriptChannel();
             NS_ENSURE_SUCCESS(rv, rv);
             nsCOMPtr<nsIInputStream> scriptStream;
             rv = NS_MaybeOpenChannelUsingOpen2(aInfo.ScriptChannel(),
                    getter_AddRefs(scriptStream));
             NS_ENSURE_SUCCESS(rv, rv);