OSDN Git Service

Remove TypeLookupTable from DexFile.
authorDavid Sehr <sehr@google.com>
Fri, 16 Sep 2016 01:13:52 +0000 (18:13 -0700)
committerDavid Sehr <sehr@google.com>
Fri, 16 Sep 2016 23:31:19 +0000 (16:31 -0700)
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

14 files changed:
compiler/oat_writer.cc
dexdump/dexdump_main.cc
dexdump/dexdump_test.cc
dexlayout/dexlayout_main.cc
oatdump/oatdump.cc
runtime/class_linker.cc
runtime/dex_file.cc
runtime/dex_file.h
runtime/native/dalvik_system_DexFile.cc
runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc
runtime/oat_file.cc
runtime/oat_file.h
runtime/type_lookup_table.cc
runtime/type_lookup_table.h

index 5e0c64b..d629c0c 100644 (file)
@@ -259,7 +259,16 @@ class OatWriter::OatDexFile {
   // 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]);
   }
@@ -2285,9 +2294,9 @@ bool OatWriter::WriteTypeLookupTables(
     }
 
     // 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_;
index f716ba8..5c032a0 100644 (file)
@@ -28,8 +28,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "base/logging.h"
 #include "mem_map.h"
-#include "runtime.h"
 
 namespace art {
 
index 9819233..d28ca28 100644 (file)
@@ -24,8 +24,6 @@
 #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"
index 286a0c6..09fa0ef 100644 (file)
@@ -26,8 +26,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "base/logging.h"
 #include "mem_map.h"
-#include "runtime.h"
 
 namespace art {
 
index db6a709..d8ac581 100644 (file)
@@ -526,7 +526,7 @@ class OatDumper {
       } 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);
@@ -742,7 +742,7 @@ class OatDumper {
     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);
index 6d93736..845e39a 100644 (file)
@@ -2242,7 +2242,7 @@ typedef std::pair<const DexFile*, const DexFile::ClassDef*> ClassPathEntry;
 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 @@ bool ClassLinker::FindClassInPathClassLoader(ScopedObjectAccessAlreadyRunnable&
           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,
index ccc4c16..03223b0 100644 (file)
 #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 @@ DexFile::DexFile(const uint8_t* base, size_t size,
       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 @@ uint32_t DexFile::Header::GetVersion() const {
   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 @@ const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_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 {
index 0ae36f7..97c2596 100644 (file)
@@ -664,10 +664,6 @@ class DexFile {
   // 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 @@ class DexFile {
     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 @@ class DexFile {
   // 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
index b2349fc..384de34 100644 (file)
@@ -270,7 +270,8 @@ static jclass DexFile_defineClassNative(JNIEnv* env,
   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();
index 1761799..94933bc 100644 (file)
@@ -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 @@ static jclass InMemoryDexClassLoader_DexData_findClass(
   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();
index 76b71a3..ea692cd 100644 (file)
@@ -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 @@ OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
       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 @@ OatFile::OatClass OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) con
                            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,
index a48791e..a61b941 100644 (file)
@@ -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 @@ class OatDexFile FINAL {
     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 @@ class OatDexFile FINAL {
   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;
index fc9faec..56e9262 100644 (file)
@@ -38,14 +38,6 @@ TypeLookupTable::~TypeLookupTable() {
   }
 }
 
-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 @@ TypeLookupTable* TypeLookupTable::Create(const DexFile& dex_file, uint8_t* stora
       : 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 DexFile& dex_file, uint8_t* storage)
   }
 }
 
-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) {}
 
index d74d01d..9595743 100644 (file)
@@ -62,8 +62,11 @@ class TypeLookupTable {
   // 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 @@ class TypeLookupTable {
   }
 
   // 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 @@ class TypeLookupTable {
   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 @@ class TypeLookupTable {
   // 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.