// Data to write to a separate section.
dchecked_vector<uint32_t> class_offsets_;
+ void InitTypeLookupTable(const DexFile& dex_file, uint8_t* storage) const {
+ lookup_table_.reset(TypeLookupTable::Create(dex_file, storage));
+ }
+
+ TypeLookupTable* GetTypeLookupTable() const {
+ return lookup_table_.get();
+ }
+
private:
+ mutable std::unique_ptr<TypeLookupTable> lookup_table_;
size_t GetClassOffsetsRawSize() const {
return class_offsets_.size() * sizeof(class_offsets_[0]);
}
}
// Create the lookup table. When `nullptr` is given as the storage buffer,
- // TypeLookupTable allocates its own and DexFile takes ownership.
- opened_dex_files[i]->CreateTypeLookupTable(/* storage */ nullptr);
- TypeLookupTable* table = opened_dex_files[i]->GetTypeLookupTable();
+ // TypeLookupTable allocates its own and OatDexFile takes ownership.
+ oat_dex_file->InitTypeLookupTable(*opened_dex_files[i], /* storage */ nullptr);
+ TypeLookupTable* table = oat_dex_file->GetTypeLookupTable();
// Type tables are required to be 4 byte aligned.
size_t initial_offset = oat_size_;
#include <string.h>
#include <unistd.h>
+#include "base/logging.h"
#include "mem_map.h"
-#include "runtime.h"
namespace art {
#include "base/stringprintf.h"
#include "common_runtime_test.h"
#include "runtime/arch/instruction_set.h"
-#include "runtime/gc/heap.h"
-#include "runtime/gc/space/image_space.h"
#include "runtime/os.h"
#include "runtime/utils.h"
#include "utils.h"
#include <string.h>
#include <unistd.h>
+#include "base/logging.h"
#include "mem_map.h"
-#include "runtime.h"
namespace art {
} else {
const char* descriptor = m->GetDeclaringClassDescriptor();
const DexFile::ClassDef* class_def =
- dex_file->FindClassDef(descriptor, ComputeModifiedUtf8Hash(descriptor));
+ OatDexFile::FindClassDef(*dex_file, descriptor, ComputeModifiedUtf8Hash(descriptor));
if (class_def != nullptr) {
uint16_t class_def_index = dex_file->GetIndexForClassDef(*class_def);
const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
if (oat_dex_file.GetLookupTableData() != nullptr) {
uint32_t table_offset = dchecked_integral_cast<uint32_t>(
oat_dex_file.GetLookupTableData() - oat_file_begin);
- uint32_t table_size = TypeLookupTable::RawDataLength(*dex_file);
+ uint32_t table_size = TypeLookupTable::RawDataLength(dex_file->NumClassDefs());
os << StringPrintf("type-table: 0x%08x..0x%08x\n",
table_offset,
table_offset + table_size - 1);
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);
}
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,
#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"
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() {
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) {
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 {
// 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;
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);
// 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
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();
#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"
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();
#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"
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() {}
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,
#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"
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:
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;
}
}
-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;
}
: 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) {
}
}
-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) {}
// 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 {
}
// 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);
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(
// 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.