Merge "ART: Add boot classpath check for initialization"
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index f9173f5..bde00cf 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -260,16 +260,7 @@
// 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]);
}
@@ -2481,8 +2472,15 @@
// Create the lookup table. When `nullptr` is given as the storage buffer,
// TypeLookupTable allocates its own and OatDexFile takes ownership.
- oat_dex_file->InitTypeLookupTable(*opened_dex_files[i], /* storage */ nullptr);
- TypeLookupTable* table = oat_dex_file->GetTypeLookupTable();
+ const DexFile& dex_file = *opened_dex_files[i];
+ {
+ std::unique_ptr<TypeLookupTable> type_lookup_table =
+ TypeLookupTable::Create(dex_file, /* storage */ nullptr);
+ type_lookup_table_oat_dex_files_.push_back(
+ std::make_unique<art::OatDexFile>(std::move(type_lookup_table)));
+ dex_file.SetOatDexFile(type_lookup_table_oat_dex_files_.back().get());
+ }
+ TypeLookupTable* const table = type_lookup_table_oat_dex_files_.back()->GetTypeLookupTable();
// Type tables are required to be 4 byte aligned.
size_t initial_offset = oat_size_;
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 3d08ad3..b92ba76 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -363,6 +363,9 @@
// Offset of the oat data from the start of the mmapped region of the elf file.
size_t oat_data_offset_;
+ // Fake OatDexFiles to hold type lookup tables for the compiler.
+ std::vector<std::unique_ptr<art::OatDexFile>> type_lookup_table_oat_dex_files_;
+
// data to write
std::unique_ptr<OatHeader> oat_header_;
dchecked_vector<OatDexFile> oat_dex_files_;
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index c550a1b..17c5959 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -476,7 +476,11 @@
}
// The table is in the .vdex file.
const OatFile::OatDexFile* oat_dex_file = GetDexCache()->GetDexFile()->GetOatDexFile();
- return oat_dex_file->GetOatFile()->DexBegin() + header->vmap_table_offset_;
+ const OatFile* oat_file = oat_dex_file->GetOatFile();
+ if (oat_file == nullptr) {
+ return nullptr;
+ }
+ return oat_file->DexBegin() + header->vmap_table_offset_;
} else {
return oat_method.GetVmapTable();
}
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 311d7d7..1338cc9 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4006,7 +4006,7 @@
const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
// In case we run without an image there won't be a backing oat file.
- if (oat_dex_file == nullptr) {
+ if (oat_dex_file == nullptr || oat_dex_file->GetOatFile() == nullptr) {
return false;
}
diff --git a/runtime/class_table.cc b/runtime/class_table.cc
index b44104e..0fcce6b 100644
--- a/runtime/class_table.cc
+++ b/runtime/class_table.cc
@@ -170,7 +170,7 @@
const DexFile* dex_file = ObjPtr<mirror::DexCache>::DownCast(obj)->GetDexFile();
if (dex_file != nullptr && dex_file->GetOatDexFile() != nullptr) {
const OatFile* oat_file = dex_file->GetOatDexFile()->GetOatFile();
- if (!oat_file->GetBssGcRoots().empty()) {
+ if (oat_file != nullptr && !oat_file->GetBssGcRoots().empty()) {
InsertOatFileLocked(oat_file); // Ignore return value.
}
}
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index da9fa50..bd236f6 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -1010,6 +1010,11 @@
return oat_dex_file_;
}
+ // Used by oat writer.
+ void SetOatDexFile(OatDexFile* oat_dex_file) const {
+ oat_dex_file_ = oat_dex_file;
+ }
+
// 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);
@@ -1138,9 +1143,10 @@
// If this dex file was loaded from an oat file, oat_dex_file_ contains a
// pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
// null.
- const OatDexFile* oat_dex_file_;
+ mutable const OatDexFile* oat_dex_file_;
friend class DexFileVerifierTest;
+ friend class OatWriter;
ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName); // for constructor
};
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index c14b616..61979c7 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -1252,13 +1252,14 @@
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));
+ lookup_table_ = TypeLookupTable::Open(dex_file_pointer_, lookup_table_data_, num_class_defs);
}
}
}
+OatFile::OatDexFile::OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table)
+ : lookup_table_(std::move(lookup_table)) {}
+
OatFile::OatDexFile::~OatDexFile() {}
size_t OatFile::OatDexFile::FileSize() const {
@@ -1540,7 +1541,7 @@
bool* found) {
DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
- if (oat_dex_file == nullptr) {
+ if (oat_dex_file == nullptr || oat_dex_file->GetOatFile() == nullptr) {
*found = false;
return OatFile::OatClass::Invalid();
}
@@ -1548,4 +1549,8 @@
return oat_dex_file->GetOatClass(class_def_idx);
}
+void OatFile::OatDexFile::AssertAotCompiler() {
+ CHECK(Runtime::Current()->IsAotCompiler());
+}
+
} // namespace art
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 63a0e14..29add5b 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -384,7 +384,13 @@
// Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
+ // May return null if the OatDexFile only contains a type lookup table. This case only happens
+ // for the compiler to speed up compilation.
const OatFile* GetOatFile() const {
+ // Avoid pulling in runtime.h in the header file.
+ if (kIsDebugBuild && oat_file_ == nullptr) {
+ AssertAotCompiler();
+ }
return oat_file_;
}
@@ -436,6 +442,9 @@
~OatDexFile();
+ // Create only with a type lookup table, used by the compiler to speed up compilation.
+ explicit OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table);
+
private:
OatDexFile(const OatFile* oat_file,
const std::string& dex_file_location,
@@ -446,14 +455,16 @@
const uint32_t* oat_class_offsets_pointer,
uint8_t* dex_cache_arrays);
- const OatFile* const oat_file_;
+ static void AssertAotCompiler();
+
+ const OatFile* const oat_file_ = nullptr;
const std::string dex_file_location_;
const std::string canonical_dex_file_location_;
- const uint32_t dex_file_location_checksum_;
- const uint8_t* const dex_file_pointer_;
- const uint8_t* lookup_table_data_;
- const uint32_t* const oat_class_offsets_pointer_;
- uint8_t* const dex_cache_arrays_;
+ const uint32_t dex_file_location_checksum_ = 0u;
+ const uint8_t* const dex_file_pointer_ = nullptr;
+ const uint8_t* lookup_table_data_ = nullptr;
+ const uint32_t* const oat_class_offsets_pointer_ = 0u;
+ uint8_t* const dex_cache_arrays_ = nullptr;
mutable std::unique_ptr<TypeLookupTable> lookup_table_;
friend class OatFile;
diff --git a/runtime/type_lookup_table.cc b/runtime/type_lookup_table.cc
index 56e9262..16cd722 100644
--- a/runtime/type_lookup_table.cc
+++ b/runtime/type_lookup_table.cc
@@ -50,17 +50,19 @@
return num_class_defs != 0u && num_class_defs <= std::numeric_limits<uint16_t>::max();
}
-TypeLookupTable* TypeLookupTable::Create(const DexFile& dex_file, uint8_t* storage) {
+std::unique_ptr<TypeLookupTable> TypeLookupTable::Create(const DexFile& dex_file,
+ uint8_t* storage) {
const uint32_t num_class_defs = dex_file.NumClassDefs();
- return SupportedSize(num_class_defs)
+ return std::unique_ptr<TypeLookupTable>(SupportedSize(num_class_defs)
? new TypeLookupTable(dex_file, storage)
- : nullptr;
+ : nullptr);
}
-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);
+std::unique_ptr<TypeLookupTable> TypeLookupTable::Open(const uint8_t* dex_file_pointer,
+ const uint8_t* raw_data,
+ uint32_t num_class_defs) {
+ return std::unique_ptr<TypeLookupTable>(
+ new TypeLookupTable(dex_file_pointer, raw_data, num_class_defs));
}
TypeLookupTable::TypeLookupTable(const DexFile& dex_file, uint8_t* storage)
diff --git a/runtime/type_lookup_table.h b/runtime/type_lookup_table.h
index 9595743..3f6f76f 100644
--- a/runtime/type_lookup_table.h
+++ b/runtime/type_lookup_table.h
@@ -60,13 +60,14 @@
}
// Method creates lookup table for dex file
- static TypeLookupTable* Create(const DexFile& dex_file, uint8_t* storage = nullptr);
+ static std::unique_ptr<TypeLookupTable> Create(const DexFile& dex_file,
+ uint8_t* storage = nullptr);
// 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);
+ static std::unique_ptr<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 {