Remove unnecessary indirection from MemMap.

Avoid plain MemMap pointers being passed around by changing
the MemMap to moveable and return MemMap objects by value.
Previously we could have a valid zero-size MemMap but this
is now forbidden.

MemMap::RemapAtEnd() is changed to avoid the explicit call
to munmap(); mmap() with MAP_FIXED automatically removes
old mappings for overlapping regions.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: Pixel 2 XL boots.
Test: m test-art-target-gtest
Test: testrunner.py --target --optimizing
Change-Id: I12bd453c26a396edc20eb141bfd4dad20923f170
diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc
index cc7d7aa..1846a13 100644
--- a/libdexfile/dex/art_dex_file_loader.cc
+++ b/libdexfile/dex/art_dex_file_loader.cc
@@ -23,6 +23,7 @@
 
 #include "base/file_magic.h"
 #include "base/file_utils.h"
+#include "base/mem_map.h"
 #include "base/stl_util.h"
 #include "base/systrace.h"
 #include "base/unix_file/fd_file.h"
@@ -38,14 +39,14 @@
 
 class MemMapContainer : public DexFileContainer {
  public:
-  explicit MemMapContainer(std::unique_ptr<MemMap>&& mem_map) : mem_map_(std::move(mem_map)) { }
+  explicit MemMapContainer(MemMap&& mem_map) : mem_map_(std::move(mem_map)) { }
   virtual ~MemMapContainer() OVERRIDE { }
 
   int GetPermissions() OVERRIDE {
-    if (mem_map_.get() == nullptr) {
+    if (!mem_map_.IsValid()) {
       return 0;
     } else {
-      return mem_map_->GetProtect();
+      return mem_map_.GetProtect();
     }
   }
 
@@ -55,24 +56,24 @@
 
   bool EnableWrite() OVERRIDE {
     CHECK(IsReadOnly());
-    if (mem_map_.get() == nullptr) {
+    if (!mem_map_.IsValid()) {
       return false;
     } else {
-      return mem_map_->Protect(PROT_READ | PROT_WRITE);
+      return mem_map_.Protect(PROT_READ | PROT_WRITE);
     }
   }
 
   bool DisableWrite() OVERRIDE {
     CHECK(!IsReadOnly());
-    if (mem_map_.get() == nullptr) {
+    if (!mem_map_.IsValid()) {
       return false;
     } else {
-      return mem_map_->Protect(PROT_READ);
+      return mem_map_.Protect(PROT_READ);
     }
   }
 
  private:
-  std::unique_ptr<MemMap> mem_map_;
+  MemMap mem_map_;
   DISALLOW_COPY_AND_ASSIGN(MemMapContainer);
 };
 
@@ -180,22 +181,24 @@
 
 std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const std::string& location,
                                                       uint32_t location_checksum,
-                                                      std::unique_ptr<MemMap> map,
+                                                      MemMap&& map,
                                                       bool verify,
                                                       bool verify_checksum,
                                                       std::string* error_msg) const {
   ScopedTrace trace(std::string("Open dex file from mapped-memory ") + location);
-  CHECK(map.get() != nullptr);
+  CHECK(map.IsValid());
 
-  if (map->Size() < sizeof(DexFile::Header)) {
+  size_t size = map.Size();
+  if (size < sizeof(DexFile::Header)) {
     *error_msg = StringPrintf(
         "DexFile: failed to open dex file '%s' that is too short to have a header",
         location.c_str());
     return nullptr;
   }
 
-  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
-                                                 map->Size(),
+  uint8_t* begin = map.Begin();
+  std::unique_ptr<DexFile> dex_file = OpenCommon(begin,
+                                                 size,
                                                  /*data_base*/ nullptr,
                                                  /*data_size*/ 0u,
                                                  location,
@@ -285,7 +288,7 @@
                                                           std::string* error_msg) const {
   ScopedTrace trace(std::string("Open dex file ") + std::string(location));
   CHECK(!location.empty());
-  std::unique_ptr<MemMap> map;
+  MemMap map;
   {
     File delayed_close(fd, /* check_usage */ false);
     struct stat sbuf;
@@ -300,31 +303,33 @@
       return nullptr;
     }
     size_t length = sbuf.st_size;
-    map.reset(MemMap::MapFile(length,
-                              PROT_READ,
-                              mmap_shared ? MAP_SHARED : MAP_PRIVATE,
-                              fd,
-                              0,
-                              /*low_4gb*/false,
-                              location.c_str(),
-                              error_msg));
-    if (map == nullptr) {
+    map = MemMap::MapFile(length,
+                          PROT_READ,
+                          mmap_shared ? MAP_SHARED : MAP_PRIVATE,
+                          fd,
+                          0,
+                          /*low_4gb*/false,
+                          location.c_str(),
+                          error_msg);
+    if (!map.IsValid()) {
       DCHECK(!error_msg->empty());
       return nullptr;
     }
   }
 
-  if (map->Size() < sizeof(DexFile::Header)) {
+  const uint8_t* begin = map.Begin();
+  size_t size = map.Size();
+  if (size < sizeof(DexFile::Header)) {
     *error_msg = StringPrintf(
         "DexFile: failed to open dex file '%s' that is too short to have a header",
         location.c_str());
     return nullptr;
   }
 
-  const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(map->Begin());
+  const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(begin);
 
-  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
-                                                 map->Size(),
+  std::unique_ptr<DexFile> dex_file = OpenCommon(begin,
+                                                 size,
                                                  /*data_base*/ nullptr,
                                                  /*data_size*/ 0u,
                                                  location,
@@ -366,7 +371,7 @@
     return nullptr;
   }
 
-  std::unique_ptr<MemMap> map;
+  MemMap map;
   if (zip_entry->IsUncompressed()) {
     if (!zip_entry->IsAlignedTo(alignof(DexFile::Header))) {
       // Do not mmap unaligned ZIP entries because
@@ -376,8 +381,8 @@
                    << "Falling back to extracting file.";
     } else {
       // Map uncompressed files within zip as file-backed to avoid a dirty copy.
-      map.reset(zip_entry->MapDirectlyFromFile(location.c_str(), /*out*/error_msg));
-      if (map == nullptr) {
+      map = zip_entry->MapDirectlyFromFile(location.c_str(), /*out*/error_msg);
+      if (!map.IsValid()) {
         LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
                      << "is your ZIP file corrupted? Falling back to extraction.";
         // Try again with Extraction which still has a chance of recovery.
@@ -385,21 +390,23 @@
     }
   }
 
-  if (map == nullptr) {
+  if (!map.IsValid()) {
     // Default path for compressed ZIP entries,
     // and fallback for stored ZIP entries.
-    map.reset(zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg));
+    map = zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg);
   }
 
-  if (map == nullptr) {
+  if (!map.IsValid()) {
     *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(),
                               error_msg->c_str());
     *error_code = DexFileLoaderErrorCode::kExtractToMemoryError;
     return nullptr;
   }
   VerifyResult verify_result;
-  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
-                                                 map->Size(),
+  uint8_t* begin = map.Begin();
+  size_t size = map.Size();
+  std::unique_ptr<DexFile> dex_file = OpenCommon(begin,
+                                                 size,
                                                  /*data_base*/ nullptr,
                                                  /*data_size*/ 0u,
                                                  location,