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.