Revert "Refactor DexFile ownership"

This reverts commit b095f022a9683a9123018c01e22595cf969fd88b.

Reason for revert: Caused huge interpreter performance regression.

Change-Id: I0f27f8f234d315807695362bf679ef47f68723f7
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h
index e44d7b8..f903f82 100644
--- a/compiler/optimizing/optimizing_unit_test.h
+++ b/compiler/optimizing/optimizing_unit_test.h
@@ -130,10 +130,12 @@
     // Create the dex file based on the fake data. Call the constructor so that we can use virtual
     // functions. Don't use the arena for the StandardDexFile otherwise the dex location leaks.
     dex_files_.emplace_back(new StandardDexFile(
-        std::make_unique<NonOwningDexFileContainer>(dex_data, sizeof(StandardDexFile::Header)),
+        dex_data,
+        sizeof(StandardDexFile::Header),
         "no_location",
         /*location_checksum*/ 0,
-        /*oat_dex_file*/ nullptr));
+        /*oat_dex_file*/ nullptr,
+        /*container*/ nullptr));
 
     return new (allocator) HGraph(
         allocator,
diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc
index 05986ec..392ce1e 100644
--- a/libdexfile/dex/art_dex_file_loader.cc
+++ b/libdexfile/dex/art_dex_file_loader.cc
@@ -71,14 +71,6 @@
     }
   }
 
-  const uint8_t* Begin() OVERRIDE {
-    return mem_map_->Begin();
-  }
-
-  size_t Size() OVERRIDE {
-    return mem_map_->Size();
-  }
-
  private:
   std::unique_ptr<MemMap> mem_map_;
   DISALLOW_COPY_AND_ASSIGN(MemMapContainer);
@@ -172,14 +164,17 @@
                                                       bool verify_checksum,
                                                       std::string* error_msg) const {
   ScopedTrace trace(std::string("Open dex file from RAM ") + location);
-  return OpenCommon(std::make_unique<NonOwningDexFileContainer>(base, size),
-                    std::make_unique<EmptyDexFileContainer>(),
+  return OpenCommon(base,
+                    size,
+                    /*data_base*/ nullptr,
+                    /*data_size*/ 0u,
                     location,
                     location_checksum,
                     oat_dex_file,
                     verify,
                     verify_checksum,
                     error_msg,
+                    /*container*/ nullptr,
                     /*verify_result*/ nullptr);
 }
 
@@ -199,16 +194,18 @@
     return nullptr;
   }
 
-  std::unique_ptr<DexFile> dex_file =
-      OpenCommon(std::make_unique<MemMapContainer>(std::move(map)),
-                 std::make_unique<EmptyDexFileContainer>(),
-                 location,
-                 location_checksum,
-                 kNoOatDexFile,
-                 verify,
-                 verify_checksum,
-                 error_msg,
-                 /*verify_result*/ nullptr);
+  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
+                                                 map->Size(),
+                                                 /*data_base*/ nullptr,
+                                                 /*data_size*/ 0u,
+                                                 location,
+                                                 location_checksum,
+                                                 kNoOatDexFile,
+                                                 verify,
+                                                 verify_checksum,
+                                                 error_msg,
+                                                 std::make_unique<MemMapContainer>(std::move(map)),
+                                                 /*verify_result*/ nullptr);
   // Opening CompactDex is only supported from vdex files.
   if (dex_file != nullptr && dex_file->IsCompactDexFile()) {
     *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files",
@@ -326,16 +323,18 @@
 
   const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(map->Begin());
 
-  std::unique_ptr<DexFile> dex_file =
-      OpenCommon(std::make_unique<MemMapContainer>(std::move(map)),
-                 std::make_unique<EmptyDexFileContainer>(),
-                 location,
-                 dex_header->checksum_,
-                 kNoOatDexFile,
-                 verify,
-                 verify_checksum,
-                 error_msg,
-                 /*verify_result*/ nullptr);
+  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
+                                                 map->Size(),
+                                                 /*data_base*/ nullptr,
+                                                 /*data_size*/ 0u,
+                                                 location,
+                                                 dex_header->checksum_,
+                                                 kNoOatDexFile,
+                                                 verify,
+                                                 verify_checksum,
+                                                 error_msg,
+                                                 std::make_unique<MemMapContainer>(std::move(map)),
+                                                 /*verify_result*/ nullptr);
 
   // Opening CompactDex is only supported from vdex files.
   if (dex_file != nullptr && dex_file->IsCompactDexFile()) {
@@ -399,16 +398,18 @@
     return nullptr;
   }
   VerifyResult verify_result;
-  std::unique_ptr<DexFile> dex_file =
-      OpenCommon(std::make_unique<MemMapContainer>(std::move(map)),
-                 std::make_unique<EmptyDexFileContainer>(),
-                 location,
-                 zip_entry->GetCrc32(),
-                 kNoOatDexFile,
-                 verify,
-                 verify_checksum,
-                 error_msg,
-                 &verify_result);
+  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
+                                                 map->Size(),
+                                                 /*data_base*/ nullptr,
+                                                 /*data_size*/ 0u,
+                                                 location,
+                                                 zip_entry->GetCrc32(),
+                                                 kNoOatDexFile,
+                                                 verify,
+                                                 verify_checksum,
+                                                 error_msg,
+                                                 std::make_unique<MemMapContainer>(std::move(map)),
+                                                 &verify_result);
   if (dex_file != nullptr && dex_file->IsCompactDexFile()) {
     *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files",
                               location.c_str());
@@ -505,24 +506,29 @@
   }
 }
 
-std::unique_ptr<DexFile> ArtDexFileLoader::OpenCommon(
-    std::unique_ptr<DexFileContainer> main_section,
-    std::unique_ptr<DexFileContainer> data_section,
-    const std::string& location,
-    uint32_t location_checksum,
-    const OatDexFile* oat_dex_file,
-    bool verify,
-    bool verify_checksum,
-    std::string* error_msg,
-    VerifyResult* verify_result) {
-  std::unique_ptr<DexFile> dex_file = DexFileLoader::OpenCommon(std::move(main_section),
-                                                                std::move(data_section),
+std::unique_ptr<DexFile> ArtDexFileLoader::OpenCommon(const uint8_t* base,
+                                                      size_t size,
+                                                      const uint8_t* data_base,
+                                                      size_t data_size,
+                                                      const std::string& location,
+                                                      uint32_t location_checksum,
+                                                      const OatDexFile* oat_dex_file,
+                                                      bool verify,
+                                                      bool verify_checksum,
+                                                      std::string* error_msg,
+                                                      std::unique_ptr<DexFileContainer> container,
+                                                      VerifyResult* verify_result) {
+  std::unique_ptr<DexFile> dex_file = DexFileLoader::OpenCommon(base,
+                                                                size,
+                                                                data_base,
+                                                                data_size,
                                                                 location,
                                                                 location_checksum,
                                                                 oat_dex_file,
                                                                 verify,
                                                                 verify_checksum,
                                                                 error_msg,
+                                                                std::move(container),
                                                                 verify_result);
 
   // Check if this dex file is located in the framework directory.
diff --git a/libdexfile/dex/art_dex_file_loader.h b/libdexfile/dex/art_dex_file_loader.h
index 9f92b72..a460aee 100644
--- a/libdexfile/dex/art_dex_file_loader.h
+++ b/libdexfile/dex/art_dex_file_loader.h
@@ -121,17 +121,17 @@
                                                        std::string* error_msg,
                                                        ZipOpenErrorCode* error_code) const;
 
-  // main_section points to the header and fixed-sized objects (ids, etc.)
-  // If not empty (Begin != nullptr) data_section points to the dex file's variable-sized
-  // objects such as strings, class_data_items, etc.
-  static std::unique_ptr<DexFile> OpenCommon(std::unique_ptr<DexFileContainer> main_section,
-                                             std::unique_ptr<DexFileContainer> data_section,
+  static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
+                                             size_t size,
+                                             const uint8_t* data_base,
+                                             size_t data_size,
                                              const std::string& location,
                                              uint32_t location_checksum,
                                              const OatDexFile* oat_dex_file,
                                              bool verify,
                                              bool verify_checksum,
                                              std::string* error_msg,
+                                             std::unique_ptr<DexFileContainer> container,
                                              VerifyResult* verify_result);
 };
 
diff --git a/libdexfile/dex/compact_dex_file.cc b/libdexfile/dex/compact_dex_file.cc
index 4bd1675..302b59e 100644
--- a/libdexfile/dex/compact_dex_file.cc
+++ b/libdexfile/dex/compact_dex_file.cc
@@ -84,16 +84,22 @@
   return CalculateChecksum(Begin(), Size(), DataBegin(), DataSize());
 }
 
-CompactDexFile::CompactDexFile(std::unique_ptr<DexFileContainer> main_section,
-                               std::unique_ptr<DexFileContainer> data_section,
+CompactDexFile::CompactDexFile(const uint8_t* base,
+                               size_t size,
+                               const uint8_t* data_begin,
+                               size_t data_size,
                                const std::string& location,
                                uint32_t location_checksum,
-                               const OatDexFile* oat_dex_file)
-    : DexFile(std::move(main_section),
-              std::move(data_section),
+                               const OatDexFile* oat_dex_file,
+                               std::unique_ptr<DexFileContainer> container)
+    : DexFile(base,
+              size,
+              data_begin,
+              data_size,
               location,
               location_checksum,
               oat_dex_file,
+              std::move(container),
               /*is_compact_dex*/ true),
       debug_info_offsets_(DataBegin() + GetHeader().debug_info_offsets_pos_,
                           GetHeader().debug_info_base_,
diff --git a/libdexfile/dex/compact_dex_file.h b/libdexfile/dex/compact_dex_file.h
index ffaa9a7..affc9a2 100644
--- a/libdexfile/dex/compact_dex_file.h
+++ b/libdexfile/dex/compact_dex_file.h
@@ -284,11 +284,14 @@
   virtual uint32_t CalculateChecksum() const OVERRIDE;
 
  private:
-  CompactDexFile(std::unique_ptr<DexFileContainer> main_section,
-                 std::unique_ptr<DexFileContainer> data_section,
+  CompactDexFile(const uint8_t* base,
+                 size_t size,
+                 const uint8_t* data_begin,
+                 size_t data_size,
                  const std::string& location,
                  uint32_t location_checksum,
-                 const OatDexFile* oat_dex_file);
+                 const OatDexFile* oat_dex_file,
+                 std::unique_ptr<DexFileContainer> container);
 
   CompactOffsetTable::Accessor debug_info_offsets_;
 
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index c2b478a..f1f8960 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -73,101 +73,61 @@
 }
 
 int DexFile::GetPermissions() const {
-  CHECK(main_section_ != nullptr);
-  return main_section_->GetPermissions();
+  CHECK(container_.get() != nullptr);
+  return container_->GetPermissions();
 }
 
 bool DexFile::IsReadOnly() const {
-  CHECK(main_section_ != nullptr);
-  return main_section_->IsReadOnly();
+  CHECK(container_.get() != nullptr);
+  return container_->IsReadOnly();
 }
 
 bool DexFile::EnableWrite() const {
-  CHECK(main_section_ != nullptr);
-  return main_section_->EnableWrite();
+  CHECK(container_.get() != nullptr);
+  return container_->EnableWrite();
 }
 
 bool DexFile::DisableWrite() const {
-  CHECK(main_section_ != nullptr);
-  return main_section_->DisableWrite();
+  CHECK(container_.get() != nullptr);
+  return container_->DisableWrite();
 }
 
-DexFile::DexFile(std::unique_ptr<DexFileContainer> main_section,
-                 std::unique_ptr<DexFileContainer> data_section,
+DexFile::DexFile(const uint8_t* base,
+                 size_t size,
+                 const uint8_t* data_begin,
+                 size_t data_size,
                  const std::string& location,
                  uint32_t location_checksum,
                  const OatDexFile* oat_dex_file,
+                 std::unique_ptr<DexFileContainer> container,
                  bool is_compact_dex)
-    : main_section_(std::move(main_section)),
+    : begin_(base),
+      size_(size),
+      data_begin_(data_begin),
+      data_size_(data_size),
       location_(location),
       location_checksum_(location_checksum),
-      header_(reinterpret_cast<const Header*>(main_section_->Begin())),
-      string_ids_(reinterpret_cast<const StringId*>(main_section_->Begin() +
-                                                    header_->string_ids_off_)),
-      type_ids_(reinterpret_cast<const TypeId*>(main_section_->Begin() + header_->type_ids_off_)),
-      field_ids_(reinterpret_cast<const FieldId*>(main_section_->Begin() +
-                                                  header_->field_ids_off_)),
-      method_ids_(reinterpret_cast<const MethodId*>(main_section_->Begin() +
-                                                    header_->method_ids_off_)),
-      proto_ids_(reinterpret_cast<const ProtoId*>(main_section_->Begin() +
-                                                  header_->proto_ids_off_)),
-      class_defs_(reinterpret_cast<const ClassDef*>(main_section_->Begin() +
-                                                    header_->class_defs_off_)),
+      header_(reinterpret_cast<const Header*>(base)),
+      string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)),
+      type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)),
+      field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)),
+      method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)),
+      proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)),
+      class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)),
       method_handles_(nullptr),
       num_method_handles_(0),
       call_site_ids_(nullptr),
       num_call_site_ids_(0),
       oat_dex_file_(oat_dex_file),
+      container_(std::move(container)),
       is_compact_dex_(is_compact_dex),
       is_platform_dex_(false) {
-  CHECK(main_section_->Begin() != nullptr) << GetLocation();
-  CHECK_GT(main_section_->Size(), 0U) << GetLocation();
+  CHECK(begin_ != nullptr) << GetLocation();
+  CHECK_GT(size_, 0U) << GetLocation();
   // Check base (=header) alignment.
   // Must be 4-byte aligned to avoid undefined behavior when accessing
   // any of the sections via a pointer.
-  CHECK_ALIGNED(main_section_->Begin(), alignof(Header));
-
-  data_section_ = std::move(data_section);
-
-  InitializeSectionsFromMapList();
-}
-
-DexFile::DexFile(std::unique_ptr<DexFileContainer> main_section,
-                 const std::string& location,
-                 uint32_t location_checksum,
-                 const OatDexFile* oat_dex_file,
-                 bool is_compact_dex)
-    : main_section_(std::move(main_section)),
-      location_(location),
-      location_checksum_(location_checksum),
-      header_(reinterpret_cast<const Header*>(main_section_->Begin())),
-      string_ids_(reinterpret_cast<const StringId*>(main_section_->Begin() +
-                                                    header_->string_ids_off_)),
-      type_ids_(reinterpret_cast<const TypeId*>(main_section_->Begin() + header_->type_ids_off_)),
-      field_ids_(reinterpret_cast<const FieldId*>(main_section_->Begin() +
-                                                  header_->field_ids_off_)),
-      method_ids_(reinterpret_cast<const MethodId*>(main_section_->Begin() +
-                                                    header_->method_ids_off_)),
-      proto_ids_(reinterpret_cast<const ProtoId*>(main_section_->Begin() +
-                                                  header_->proto_ids_off_)),
-      class_defs_(reinterpret_cast<const ClassDef*>(main_section_->Begin() +
-                                                    header_->class_defs_off_)),
-      method_handles_(nullptr),
-      num_method_handles_(0),
-      call_site_ids_(nullptr),
-      num_call_site_ids_(0),
-      oat_dex_file_(oat_dex_file),
-      is_compact_dex_(is_compact_dex),
-      is_platform_dex_(false) {
-  CHECK(main_section_->Begin() != nullptr) << GetLocation();
-  CHECK_GT(main_section_->Size(), 0U) << GetLocation();
-  // Check base (=header) alignment.
-  // Must be 4-byte aligned to avoid undefined behavior when accessing
-  // any of the sections via a pointer.
-  CHECK_ALIGNED(main_section_->Begin(), alignof(Header));
-
-  data_section_ = std::make_unique<NonOwningDexFileContainer>(main_section_->Begin(),
-                                                              main_section_->Size());
+  CHECK_ALIGNED(begin_, alignof(Header));
 
   InitializeSectionsFromMapList();
 }
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index c94c786..67abdca 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -56,48 +56,11 @@
   virtual bool IsReadOnly() = 0;
   virtual bool EnableWrite() = 0;
   virtual bool DisableWrite() = 0;
-  virtual const uint8_t* Begin() = 0;
-  virtual size_t Size() = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DexFileContainer);
 };
 
-class EmptyDexFileContainer FINAL : public DexFileContainer {
- public:
-  EmptyDexFileContainer() { }
-  ~EmptyDexFileContainer() { }
-
-  int GetPermissions() OVERRIDE { return 0; }
-  bool IsReadOnly() OVERRIDE { return true; }
-  bool EnableWrite() OVERRIDE { return false; }
-  bool DisableWrite() OVERRIDE { return false; }
-  const uint8_t* Begin() OVERRIDE { return nullptr; }
-  size_t Size() OVERRIDE { return 0U; }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(EmptyDexFileContainer);
-};
-
-class NonOwningDexFileContainer FINAL : public DexFileContainer {
- public:
-  NonOwningDexFileContainer(const uint8_t* begin, size_t size) : begin_(begin), size_(size) { }
-  ~NonOwningDexFileContainer() { }
-
-  int GetPermissions() OVERRIDE { return 0; }
-  bool IsReadOnly() OVERRIDE { return true; }
-  bool EnableWrite() OVERRIDE { return false; }
-  bool DisableWrite() OVERRIDE { return false; }
-  const uint8_t* Begin() OVERRIDE { return begin_; }
-  size_t Size() OVERRIDE { return size_; }
-
- private:
-  const uint8_t* begin_;
-  size_t size_;
-
-  DISALLOW_COPY_AND_ASSIGN(NonOwningDexFileContainer);
-};
-
 // Dex file is the API that exposes native dex files (ordinary dex files) and CompactDex.
 // Originally, the dex file format used by ART was mostly the same as APKs. The only change was
 // quickened opcodes and layout optimizations.
@@ -791,7 +754,7 @@
     // Check that the offset is in bounds.
     // Note that although the specification says that 0 should be used if there
     // is no debug information, some applications incorrectly use 0xFFFFFFFF.
-    return (debug_info_off == 0 || debug_info_off >= DataSize())
+    return (debug_info_off == 0 || debug_info_off >= data_size_)
         ? nullptr
         : DataBegin() + debug_info_off;
   }
@@ -966,19 +929,19 @@
   bool DisableWrite() const;
 
   const uint8_t* Begin() const {
-    return main_section_->Begin();
+    return begin_;
   }
 
   size_t Size() const {
-    return main_section_->Size();
+    return size_;
   }
 
   const uint8_t* DataBegin() const {
-    return data_section_->Begin();
+    return data_begin_;
   }
 
   size_t DataSize() const {
-    return data_section_->Size();
+    return data_size_;
   }
 
   template <typename T>
@@ -1046,7 +1009,7 @@
   }
 
   DexFileContainer* GetContainer() const {
-    return main_section_.get();
+    return container_.get();
   }
 
   // Changes the dex class data pointed to by data_ptr it to not have any hiddenapi flags.
@@ -1058,25 +1021,14 @@
   // First Dex format version supporting default methods.
   static const uint32_t kDefaultMethodsVersion = 37;
 
-  // For the two constructors, some notation needs explanation.
-  // Dex files consist of two sections:
-  // 1) "main" -- contains the header and fixed-sized objects (ids, etc.)
-  // 2) "data" -- contains variable-sized objects such as strings, class_data_items, etc.
-  // For StandardDexFile, both sections are addressed through one pointer.
-  // For CompactDexFile multiple dex files share one data section, but each has its
-  // own main section, and hence we need two pointers.
-
-  DexFile(std::unique_ptr<DexFileContainer> main_section,
+  DexFile(const uint8_t* base,
+          size_t size,
+          const uint8_t* data_begin,
+          size_t data_size,
           const std::string& location,
           uint32_t location_checksum,
           const OatDexFile* oat_dex_file,
-          bool is_compact_dex);
-
-  DexFile(std::unique_ptr<DexFileContainer> main_section,
-          std::unique_ptr<DexFileContainer> data_section,
-          const std::string& location,
-          uint32_t location_checksum,
-          const OatDexFile* oat_dex_file,
+          std::unique_ptr<DexFileContainer> container,
           bool is_compact_dex);
 
   // Top-level initializer that calls other Init methods.
@@ -1088,11 +1040,17 @@
   // Initialize section info for sections only found in map. Returns true on success.
   void InitializeSectionsFromMapList();
 
-  // The container for the header and fixed portions.
-  std::unique_ptr<DexFileContainer> main_section_;
+  // The base address of the memory mapping.
+  const uint8_t* const begin_;
 
-  // The container for the data section
-  std::unique_ptr<DexFileContainer> data_section_;
+  // The size of the underlying memory allocation in bytes.
+  const size_t size_;
+
+  // The base address of the data section (same as Begin() for standard dex).
+  const uint8_t* const data_begin_;
+
+  // The size of the data section.
+  const size_t data_size_;
 
   // Typically the dex file name when available, alternatively some identifying string.
   //
@@ -1140,6 +1098,9 @@
   // null.
   mutable const OatDexFile* oat_dex_file_;
 
+  // Manages the underlying memory allocation.
+  std::unique_ptr<DexFileContainer> container_;
+
   // If the dex file is a compact dex file. If false then the dex file is a standard dex file.
   const bool is_compact_dex_;
 
diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc
index 156f655..457addf 100644
--- a/libdexfile/dex/dex_file_loader.cc
+++ b/libdexfile/dex/dex_file_loader.cc
@@ -54,17 +54,8 @@
     return false;
   }
 
-  uint8_t* Begin() OVERRIDE {
-    return vector_.data();
-  }
-
-  size_t Size() OVERRIDE {
-    return vector_.size();
-  }
-
  private:
   std::vector<uint8_t> vector_;
-
   DISALLOW_COPY_AND_ASSIGN(VectorContainer);
 };
 
@@ -233,14 +224,17 @@
                                                    bool verify,
                                                    bool verify_checksum,
                                                    std::string* error_msg) const {
-  return OpenCommon(std::make_unique<NonOwningDexFileContainer>(base, size),
-                    std::make_unique<EmptyDexFileContainer>(),
+  return OpenCommon(base,
+                    size,
+                    /*data_base*/ nullptr,
+                    /*data_size*/ 0,
                     location,
                     location_checksum,
                     oat_dex_file,
                     verify,
                     verify_checksum,
                     error_msg,
+                    /*container*/ nullptr,
                     /*verify_result*/ nullptr);
 }
 
@@ -255,14 +249,17 @@
     bool verify,
     bool verify_checksum,
     std::string* error_msg) const {
-  return OpenCommon(std::make_unique<NonOwningDexFileContainer>(base, size),
-                    std::make_unique<NonOwningDexFileContainer>(data_base, data_size),
+  return OpenCommon(base,
+                    size,
+                    data_base,
+                    data_size,
                     location,
                     location_checksum,
                     oat_dex_file,
                     verify,
                     verify_checksum,
                     error_msg,
+                    /*container*/ nullptr,
                     /*verify_result*/ nullptr);
 }
 
@@ -310,47 +307,49 @@
   return false;
 }
 
-std::unique_ptr<DexFile> DexFileLoader::OpenCommon(std::unique_ptr<DexFileContainer> main_section,
-                                                   std::unique_ptr<DexFileContainer> data_section,
+std::unique_ptr<DexFile> DexFileLoader::OpenCommon(const uint8_t* base,
+                                                   size_t size,
+                                                   const uint8_t* data_base,
+                                                   size_t data_size,
                                                    const std::string& location,
                                                    uint32_t location_checksum,
                                                    const OatDexFile* oat_dex_file,
                                                    bool verify,
                                                    bool verify_checksum,
                                                    std::string* error_msg,
+                                                   std::unique_ptr<DexFileContainer> container,
                                                    VerifyResult* verify_result) {
   if (verify_result != nullptr) {
     *verify_result = VerifyResult::kVerifyNotAttempted;
   }
   std::unique_ptr<DexFile> dex_file;
-  if (main_section->Size() >= sizeof(StandardDexFile::Header) &&
-      StandardDexFile::IsMagicValid(main_section->Begin())) {
-    if (data_section->Size() != 0) {
-      CHECK_EQ(main_section->Begin(), data_section->Begin()) << "Unsupported for standard dex";
+  if (size >= sizeof(StandardDexFile::Header) && StandardDexFile::IsMagicValid(base)) {
+    if (data_size != 0) {
+      CHECK_EQ(base, data_base) << "Unsupported for standard dex";
     }
-    CHECK(main_section != nullptr);
-    CHECK(main_section->Begin() != nullptr);
-    dex_file.reset(new StandardDexFile(std::move(main_section),
+    dex_file.reset(new StandardDexFile(base,
+                                       size,
                                        location,
                                        location_checksum,
-                                       oat_dex_file));
-  } else if (main_section->Size() >= sizeof(CompactDexFile::Header) &&
-             CompactDexFile::IsMagicValid(main_section->Begin())) {
-    if (data_section->Begin() == nullptr) {
+                                       oat_dex_file,
+                                       std::move(container)));
+  } else if (size >= sizeof(CompactDexFile::Header) && CompactDexFile::IsMagicValid(base)) {
+    if (data_base == nullptr) {
       // TODO: Is there a clean way to support both an explicit data section and reading the one
       // from the header.
-      CHECK_EQ(data_section->Size(), 0u);
-      const CompactDexFile::Header* const header =
-          CompactDexFile::Header::At(main_section->Begin());
-      data_section =
-          std::make_unique<NonOwningDexFileContainer>(main_section->Begin() + header->data_off_,
-                                                      header->data_size_);
+      CHECK_EQ(data_size, 0u);
+      const CompactDexFile::Header* const header = CompactDexFile::Header::At(base);
+      data_base = base + header->data_off_;
+      data_size = header->data_size_;
     }
-    dex_file.reset(new CompactDexFile(std::move(main_section),
-                                      std::move(data_section),
+    dex_file.reset(new CompactDexFile(base,
+                                      size,
+                                      data_base,
+                                      data_size,
                                       location,
                                       location_checksum,
-                                      oat_dex_file));
+                                      oat_dex_file,
+                                      std::move(container)));
     // Disable verification for CompactDex input.
     verify = false;
   } else {
@@ -410,16 +409,19 @@
     return nullptr;
   }
   VerifyResult verify_result;
-  std::unique_ptr<const DexFile> dex_file =
-      OpenCommon(std::make_unique<VectorContainer>(std::move(map)),
-                 std::make_unique<EmptyDexFileContainer>(),
-                 location,
-                 zip_entry->GetCrc32(),
-                 /*oat_dex_file*/ nullptr,
-                 verify,
-                 verify_checksum,
-                 error_msg,
-                 &verify_result);
+  std::unique_ptr<const DexFile> dex_file = OpenCommon(
+      map.data(),
+      map.size(),
+      /*data_base*/ nullptr,
+      /*data_size*/ 0u,
+      location,
+      zip_entry->GetCrc32(),
+      /*oat_dex_file*/ nullptr,
+      verify,
+      verify_checksum,
+      error_msg,
+      std::make_unique<VectorContainer>(std::move(map)),
+      &verify_result);
   if (dex_file == nullptr) {
     if (verify_result == VerifyResult::kVerifyNotAttempted) {
       *error_code = ZipOpenErrorCode::kDexFileError;
diff --git a/libdexfile/dex/dex_file_loader.h b/libdexfile/dex/dex_file_loader.h
index 0bd6446..0153220 100644
--- a/libdexfile/dex/dex_file_loader.h
+++ b/libdexfile/dex/dex_file_loader.h
@@ -161,17 +161,17 @@
     kVerifyFailed
   };
 
-  // main_section points to the header and fixed-sized objects (ids, etc.)
-  // If not empty (Begin != nullptr) data_section points to the dex file's variable-sized
-  // objects such as strings, class_data_items, etc.
-  static std::unique_ptr<DexFile> OpenCommon(std::unique_ptr<DexFileContainer> main_section,
-                                             std::unique_ptr<DexFileContainer> data_section,
+  static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
+                                             size_t size,
+                                             const uint8_t* data_base,
+                                             size_t data_size,
                                              const std::string& location,
                                              uint32_t location_checksum,
                                              const OatDexFile* oat_dex_file,
                                              bool verify,
                                              bool verify_checksum,
                                              std::string* error_msg,
+                                             std::unique_ptr<DexFileContainer> container,
                                              VerifyResult* verify_result);
 
  private:
diff --git a/libdexfile/dex/dex_file_verifier_test.cc b/libdexfile/dex/dex_file_verifier_test.cc
index 9d9f1bd..c9bac0f 100644
--- a/libdexfile/dex/dex_file_verifier_test.cc
+++ b/libdexfile/dex/dex_file_verifier_test.cc
@@ -56,10 +56,7 @@
 class DexFileVerifierTest : public testing::Test {
  protected:
   DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) {
-    return new StandardDexFile(std::make_unique<NonOwningDexFileContainer>(dex_bytes, length),
-                               "tmp",
-                               0,
-                               nullptr);
+    return new StandardDexFile(dex_bytes, length, "tmp", 0, nullptr, nullptr);
   }
 
   void VerifyModification(const char* dex_file_base64_content,
diff --git a/libdexfile/dex/standard_dex_file.h b/libdexfile/dex/standard_dex_file.h
index 0121d60..999e5b9 100644
--- a/libdexfile/dex/standard_dex_file.h
+++ b/libdexfile/dex/standard_dex_file.h
@@ -88,14 +88,20 @@
   }
 
  private:
-  StandardDexFile(std::unique_ptr<DexFileContainer> container,
+  StandardDexFile(const uint8_t* base,
+                  size_t size,
                   const std::string& location,
                   uint32_t location_checksum,
-                  const OatDexFile* oat_dex_file)
-      : DexFile(std::move(container),
+                  const OatDexFile* oat_dex_file,
+                  std::unique_ptr<DexFileContainer> container)
+      : DexFile(base,
+                size,
+                /*data_begin*/ base,
+                /*data_size*/ size,
                 location,
                 location_checksum,
                 oat_dex_file,
+                std::move(container),
                 /*is_compact_dex*/ false) {}
 
   friend class DexFileLoader;
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 2a2aff1..e40f1db 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -1521,12 +1521,12 @@
   dex_cache->SetLocation(location.Get());
   const DexFile* old_dex_file = dex_cache->GetDexFile();
 
-  std::unique_ptr<DexFile> dex_file(
-      new StandardDexFile(std::make_unique<NonOwningDexFileContainer>(old_dex_file->Begin(),
-                                                                      old_dex_file->Size()),
-                          location->ToModifiedUtf8(),
-                          0u,
-                          nullptr));
+  std::unique_ptr<DexFile> dex_file(new StandardDexFile(old_dex_file->Begin(),
+                                                        old_dex_file->Size(),
+                                                        location->ToModifiedUtf8(),
+                                                        0u,
+                                                        nullptr,
+                                                        nullptr));
   {
     WriterMutexLock mu(soa.Self(), *Locks::dex_lock_);
     // Check that inserting with a UTF16 name works.