Remove TypeLookupTable from DexFile.
One more step towards removing runtime dependencies from the DexFile
API. This severs the ties to OatFile. Work remains to move MemMap out
of DexFile.
Bug: 22322814
Change-Id: I29e7ad8fd292c7919ed2689dc754b958b88d6819
Test: test-art-host
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6d93736..845e39a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2242,7 +2242,7 @@
ClassPathEntry FindInClassPath(const char* descriptor,
size_t hash, const std::vector<const DexFile*>& class_path) {
for (const DexFile* dex_file : class_path) {
- const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor, hash);
+ const DexFile::ClassDef* dex_class_def = OatDexFile::FindClassDef(*dex_file, descriptor, hash);
if (dex_class_def != nullptr) {
return ClassPathEntry(dex_file, dex_class_def);
}
@@ -2343,7 +2343,8 @@
for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
long_array->GetWithoutChecks(j)));
- const DexFile::ClassDef* dex_class_def = cp_dex_file->FindClassDef(descriptor, hash);
+ const DexFile::ClassDef* dex_class_def =
+ OatDexFile::FindClassDef(*cp_dex_file, descriptor, hash);
if (dex_class_def != nullptr) {
mirror::Class* klass = DefineClass(self,
descriptor,
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index ccc4c16..03223b0 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -32,14 +32,15 @@
#include "base/hash_map.h"
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/stringprintf.h"
#include "base/systrace.h"
#include "base/unix_file/fd_file.h"
-#include "class_linker-inl.h"
#include "dex_file-inl.h"
#include "dex_file_verifier.h"
#include "globals.h"
#include "jvalue.h"
#include "leb128.h"
+#include "oat_file.h"
#include "os.h"
#include "safe_map.h"
#include "thread.h"
@@ -502,16 +503,6 @@
oat_dex_file_(oat_dex_file) {
CHECK(begin_ != nullptr) << GetLocation();
CHECK_GT(size_, 0U) << GetLocation();
- const uint8_t* lookup_data = (oat_dex_file != nullptr)
- ? oat_dex_file->GetLookupTableData()
- : nullptr;
- if (lookup_data != nullptr) {
- if (lookup_data + TypeLookupTable::RawDataLength(*this) > oat_dex_file->GetOatFile()->End()) {
- LOG(WARNING) << "found truncated lookup table in " << GetLocation();
- } else {
- lookup_table_.reset(TypeLookupTable::Open(lookup_data, *this));
- }
- }
}
DexFile::~DexFile() {
@@ -571,33 +562,12 @@
return atoi(version);
}
-const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor, size_t hash) const {
- DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash);
- if (LIKELY(lookup_table_ != nullptr)) {
- const uint32_t class_def_idx = lookup_table_->Lookup(descriptor, hash);
- return (class_def_idx != DexFile::kDexNoIndex) ? &GetClassDef(class_def_idx) : nullptr;
- }
-
+const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
+ size_t num_class_defs = NumClassDefs();
// Fast path for rare no class defs case.
- const uint32_t num_class_defs = NumClassDefs();
if (num_class_defs == 0) {
return nullptr;
}
- const TypeId* type_id = FindTypeId(descriptor);
- if (type_id != nullptr) {
- uint16_t type_idx = GetIndexForTypeId(*type_id);
- for (size_t i = 0; i < num_class_defs; ++i) {
- const ClassDef& class_def = GetClassDef(i);
- if (class_def.class_idx_ == type_idx) {
- return &class_def;
- }
- }
- }
- return nullptr;
-}
-
-const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
- size_t num_class_defs = NumClassDefs();
for (size_t i = 0; i < num_class_defs; ++i) {
const ClassDef& class_def = GetClassDef(i);
if (class_def.class_idx_ == type_idx) {
@@ -788,10 +758,6 @@
return nullptr;
}
-void DexFile::CreateTypeLookupTable(uint8_t* storage) const {
- lookup_table_.reset(TypeLookupTable::Create(*this, storage));
-}
-
// Given a signature place the type ids into the given vector
bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
std::vector<uint16_t>* param_type_idxs) const {
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 0ae36f7..97c2596 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -664,10 +664,6 @@
// Returns the class descriptor string of a class definition.
const char* GetClassDescriptor(const ClassDef& class_def) const;
- // Looks up a class definition by its class descriptor. Hash must be
- // ComputeModifiedUtf8Hash(descriptor).
- const ClassDef* FindClassDef(const char* descriptor, size_t hash) const;
-
// Looks up a class definition by its type index.
const ClassDef* FindClassDef(uint16_t type_idx) const;
@@ -1008,12 +1004,6 @@
return oat_dex_file_;
}
- TypeLookupTable* GetTypeLookupTable() const {
- return lookup_table_.get();
- }
-
- void CreateTypeLookupTable(uint8_t* storage = nullptr) const;
-
// Utility methods for reading integral values from a buffer.
static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth);
static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right);
@@ -1126,7 +1116,6 @@
// pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
// null.
const OatDexFile* oat_dex_file_;
- mutable std::unique_ptr<TypeLookupTable> lookup_table_;
friend class DexFileVerifierTest;
ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName); // for constructor
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index b2349fc..384de34 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -270,7 +270,8 @@
const std::string descriptor(DotToDescriptor(class_name.c_str()));
const size_t hash(ComputeModifiedUtf8Hash(descriptor.c_str()));
for (auto& dex_file : dex_files) {
- const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor.c_str(), hash);
+ const DexFile::ClassDef* dex_class_def =
+ OatDexFile::FindClassDef(*dex_file, descriptor.c_str(), hash);
if (dex_class_def != nullptr) {
ScopedObjectAccess soa(env);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
diff --git a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc
index 1761799..94933bc 100644
--- a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc
+++ b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc
@@ -23,6 +23,7 @@
#include "mem_map.h"
#include "mirror/class_loader.h"
#include "mirror/object-inl.h"
+#include "oat_file.h"
#include "scoped_thread_state_change.h"
#include "ScopedUtfChars.h"
@@ -140,7 +141,8 @@
const char* class_descriptor = descriptor.c_str();
const size_t hash = ComputeModifiedUtf8Hash(class_descriptor);
const DexFile* dex_file = CookieToDexFile(cookie);
- const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(class_descriptor, hash);
+ const DexFile::ClassDef* dex_class_def =
+ OatDexFile::FindClassDef(*dex_file, class_descriptor, hash);
if (dex_class_def != nullptr) {
ScopedObjectAccess soa(env);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 76b71a3..ea692cd 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -49,6 +49,7 @@
#include "os.h"
#include "runtime.h"
#include "type_lookup_table.h"
+#include "utf-inl.h"
#include "utils.h"
#include "utils/dex_cache_arrays_layout-inl.h"
@@ -1204,7 +1205,21 @@
dex_file_pointer_(dex_file_pointer),
lookup_table_data_(lookup_table_data),
oat_class_offsets_pointer_(oat_class_offsets_pointer),
- dex_cache_arrays_(dex_cache_arrays) {}
+ dex_cache_arrays_(dex_cache_arrays) {
+ // Initialize TypeLookupTable.
+ if (lookup_table_data_ != nullptr) {
+ // Peek the number of classes from the DexFile.
+ const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer_);
+ const uint32_t num_class_defs = dex_header->class_defs_size_;
+ if (lookup_table_data_ + TypeLookupTable::RawDataLength(num_class_defs) > GetOatFile()->End()) {
+ LOG(WARNING) << "found truncated lookup table in " << dex_file_location_;
+ } else {
+ lookup_table_.reset(TypeLookupTable::Open(dex_file_pointer_,
+ lookup_table_data_,
+ num_class_defs));
+ }
+ }
+}
OatFile::OatDexFile::~OatDexFile() {}
@@ -1273,6 +1288,28 @@
reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
}
+const DexFile::ClassDef* OatFile::OatDexFile::FindClassDef(const DexFile& dex_file,
+ const char* descriptor,
+ size_t hash) {
+ const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
+ DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash);
+ if (LIKELY((oat_dex_file != nullptr) && (oat_dex_file->GetTypeLookupTable() != nullptr))) {
+ const uint32_t class_def_idx = oat_dex_file->GetTypeLookupTable()->Lookup(descriptor, hash);
+ return (class_def_idx != DexFile::kDexNoIndex) ? &dex_file.GetClassDef(class_def_idx) : nullptr;
+ }
+ // Fast path for rare no class defs case.
+ const uint32_t num_class_defs = dex_file.NumClassDefs();
+ if (num_class_defs == 0) {
+ return nullptr;
+ }
+ const DexFile::TypeId* type_id = dex_file.FindTypeId(descriptor);
+ if (type_id != nullptr) {
+ uint16_t type_idx = dex_file.GetIndexForTypeId(*type_id);
+ return dex_file.FindClassDef(type_idx);
+ }
+ return nullptr;
+}
+
OatFile::OatClass::OatClass(const OatFile* oat_file,
mirror::Class::Status status,
OatClassType type,
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index a48791e..a61b941 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -29,6 +29,8 @@
#include "mirror/class.h"
#include "oat.h"
#include "os.h"
+#include "type_lookup_table.h"
+#include "utf.h"
#include "utils.h"
#include "vdex_file.h"
@@ -404,6 +406,16 @@
return dex_file_pointer_;
}
+ // Looks up a class definition by its class descriptor. Hash must be
+ // ComputeModifiedUtf8Hash(descriptor).
+ static const DexFile::ClassDef* FindClassDef(const DexFile& dex_file,
+ const char* descriptor,
+ size_t hash);
+
+ TypeLookupTable* GetTypeLookupTable() const {
+ return lookup_table_.get();
+ }
+
~OatDexFile();
private:
@@ -424,6 +436,7 @@
const uint8_t* lookup_table_data_;
const uint32_t* const oat_class_offsets_pointer_;
uint8_t* const dex_cache_arrays_;
+ mutable std::unique_ptr<TypeLookupTable> lookup_table_;
friend class OatFile;
friend class OatFileBase;
diff --git a/runtime/type_lookup_table.cc b/runtime/type_lookup_table.cc
index fc9faec..56e9262 100644
--- a/runtime/type_lookup_table.cc
+++ b/runtime/type_lookup_table.cc
@@ -38,14 +38,6 @@
}
}
-uint32_t TypeLookupTable::RawDataLength() const {
- return RawDataLength(dex_file_);
-}
-
-uint32_t TypeLookupTable::RawDataLength(const DexFile& dex_file) {
- return RawDataLength(dex_file.NumClassDefs());
-}
-
uint32_t TypeLookupTable::RawDataLength(uint32_t num_class_defs) {
return SupportedSize(num_class_defs) ? RoundUpToPowerOfTwo(num_class_defs) * sizeof(Entry) : 0u;
}
@@ -65,12 +57,15 @@
: nullptr;
}
-TypeLookupTable* TypeLookupTable::Open(const uint8_t* raw_data, const DexFile& dex_file) {
- return new TypeLookupTable(raw_data, dex_file);
+TypeLookupTable* TypeLookupTable::Open(const uint8_t* dex_file_pointer,
+ const uint8_t* raw_data,
+ uint32_t num_class_defs) {
+ return new TypeLookupTable(dex_file_pointer, raw_data, num_class_defs);
}
TypeLookupTable::TypeLookupTable(const DexFile& dex_file, uint8_t* storage)
- : dex_file_(dex_file),
+ : dex_file_begin_(dex_file.Begin()),
+ raw_data_length_(RawDataLength(dex_file.NumClassDefs())),
mask_(CalculateMask(dex_file.NumClassDefs())),
entries_(storage != nullptr ? reinterpret_cast<Entry*>(storage) : new Entry[mask_ + 1]),
owns_entries_(storage == nullptr) {
@@ -106,9 +101,12 @@
}
}
-TypeLookupTable::TypeLookupTable(const uint8_t* raw_data, const DexFile& dex_file)
- : dex_file_(dex_file),
- mask_(CalculateMask(dex_file.NumClassDefs())),
+TypeLookupTable::TypeLookupTable(const uint8_t* dex_file_pointer,
+ const uint8_t* raw_data,
+ uint32_t num_class_defs)
+ : dex_file_begin_(dex_file_pointer),
+ raw_data_length_(RawDataLength(num_class_defs)),
+ mask_(CalculateMask(num_class_defs)),
entries_(reinterpret_cast<Entry*>(const_cast<uint8_t*>(raw_data))),
owns_entries_(false) {}
diff --git a/runtime/type_lookup_table.h b/runtime/type_lookup_table.h
index d74d01d..9595743 100644
--- a/runtime/type_lookup_table.h
+++ b/runtime/type_lookup_table.h
@@ -62,8 +62,11 @@
// Method creates lookup table for dex file
static TypeLookupTable* Create(const DexFile& dex_file, uint8_t* storage = nullptr);
- // Method opens lookup table from binary data. Lookup table does not owns binary data.
- static TypeLookupTable* Open(const uint8_t* raw_data, const DexFile& dex_file);
+ // Method opens lookup table from binary data. Lookups will traverse strings and other
+ // data contained in dex_file as well. Lookup table does not own raw_data or dex_file.
+ static TypeLookupTable* Open(const uint8_t* dex_file_pointer,
+ const uint8_t* raw_data,
+ uint32_t num_class_defs);
// Method returns pointer to binary data of lookup table. Used by the oat writer.
const uint8_t* RawData() const {
@@ -71,10 +74,7 @@
}
// Method returns length of binary data. Used by the oat writer.
- uint32_t RawDataLength() const;
-
- // Method returns length of binary data for the specified dex file.
- static uint32_t RawDataLength(const DexFile& dex_file);
+ uint32_t RawDataLength() const { return raw_data_length_; }
// Method returns length of binary data for the specified number of class definitions.
static uint32_t RawDataLength(uint32_t num_class_defs);
@@ -119,10 +119,13 @@
explicit TypeLookupTable(const DexFile& dex_file, uint8_t* storage);
// Construct from a dex file with existing data.
- TypeLookupTable(const uint8_t* raw_data, const DexFile& dex_file);
+ TypeLookupTable(const uint8_t* dex_file_pointer,
+ const uint8_t* raw_data,
+ uint32_t num_class_defs);
bool IsStringsEquals(const char* str, uint32_t str_offset) const {
- const uint8_t* ptr = dex_file_.Begin() + str_offset;
+ const uint8_t* ptr = dex_file_begin_ + str_offset;
+ CHECK(dex_file_begin_ != nullptr);
// Skip string length.
DecodeUnsignedLeb128(&ptr);
return CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(
@@ -154,7 +157,8 @@
// Find the last entry in a chain.
uint32_t FindLastEntryInBucket(uint32_t cur_pos) const;
- const DexFile& dex_file_;
+ const uint8_t* dex_file_begin_;
+ const uint32_t raw_data_length_;
const uint32_t mask_;
std::unique_ptr<Entry[]> entries_;
// owns_entries_ specifies if the lookup table owns the entries_ array.