diff options
| author | 2014-06-26 16:11:07 -0700 | |
|---|---|---|
| committer | 2014-07-08 12:14:38 -0700 | |
| commit | c87d27b25994da8670d82a8f7bad6327b693bfff (patch) | |
| tree | e8ad0fa224f050c5c3e3e30ccdc0912f28650f42 /compiler | |
| parent | e8a30f37bf1530a80a7df17692dbe7a68764ac30 (diff) | |
ART: Key-Value Store in Oat header
Allows the storage of string-string pairs in the oat header. The
first significant use of this is storing the implicit-check flags,
so that an oat file can be rejected if it doesn't agree with the
current runtime.
Bump the oat version as the header structure changes.
Change-Id: I15a1c16886e6b8fa7b881c918c19c1efa5c7c00f
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/image_test.cc | 8 | ||||
| -rw-r--r-- | compiler/oat_test.cc | 35 | ||||
| -rw-r--r-- | compiler/oat_writer.cc | 45 | ||||
| -rw-r--r-- | compiler/oat_writer.h | 8 |
4 files changed, 51 insertions, 45 deletions
diff --git a/compiler/image_test.cc b/compiler/image_test.cc index d52ec0ad5a..406d9d2696 100644 --- a/compiler/image_test.cc +++ b/compiler/image_test.cc @@ -25,6 +25,7 @@ #include "compiler/image_writer.h" #include "compiler/oat_writer.h" #include "gc/space/image_space.h" +#include "implicit_check_options.h" #include "lock_word.h" #include "mirror/object-inl.h" #include "signal_catcher.h" @@ -77,8 +78,11 @@ TEST_F(ImageTest, WriteRead) { t.NewTiming("WriteElf"); ScopedObjectAccess soa(Thread::Current()); - OatWriter oat_writer(class_linker->GetBootClassPath(), - 0, 0, "", compiler_driver_.get(), &timings); + SafeMap<std::string, std::string> key_value_store; + key_value_store.Put(ImplicitCheckOptions::kImplicitChecksOatHeaderKey, + ImplicitCheckOptions::Serialize(true, true, true)); + OatWriter oat_writer(class_linker->GetBootClassPath(), 0, 0, compiler_driver_.get(), &timings, + &key_value_store); bool success = compiler_driver_->WriteElf(GetTestAndroidRoot(), !kIsTargetBuild, class_linker->GetBootClassPath(), diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 254faac796..d2ee0ede80 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -18,6 +18,7 @@ #include "compiler/compiler.h" #include "compiler/oat_writer.h" #include "entrypoints/quick/quick_entrypoints.h" +#include "implicit_check_options.h" #include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" @@ -111,12 +112,16 @@ TEST_F(OatTest, WriteRead) { ScopedObjectAccess soa(Thread::Current()); ScratchFile tmp; + SafeMap<std::string, std::string> key_value_store; + key_value_store.Put(OatHeader::kImageLocationKey, "lue.art"); + key_value_store.Put(ImplicitCheckOptions::kImplicitChecksOatHeaderKey, + ImplicitCheckOptions::Serialize(true, true, true)); OatWriter oat_writer(class_linker->GetBootClassPath(), 42U, 4096U, - "lue.art", compiler_driver_.get(), - &timings); + &timings, + &key_value_store); bool success = compiler_driver_->WriteElf(GetTestAndroidRoot(), !kIsTargetBuild, class_linker->GetBootClassPath(), @@ -136,7 +141,7 @@ TEST_F(OatTest, WriteRead) { ASSERT_EQ(1U, oat_header.GetDexFileCount()); // core ASSERT_EQ(42U, oat_header.GetImageFileLocationOatChecksum()); ASSERT_EQ(4096U, oat_header.GetImageFileLocationOatDataBegin()); - ASSERT_EQ("lue.art", oat_header.GetImageFileLocation()); + ASSERT_EQ("lue.art", std::string(oat_header.GetStoreValueByKey(OatHeader::kImageLocationKey))); const DexFile* dex_file = java_lang_dex_file_; uint32_t dex_file_checksum = dex_file->GetLocationChecksum(); @@ -189,20 +194,20 @@ TEST_F(OatTest, OatHeaderIsValid) { std::vector<const DexFile*> dex_files; uint32_t image_file_location_oat_checksum = 0; uint32_t image_file_location_oat_begin = 0; - const std::string image_file_location; - OatHeader oat_header(instruction_set, - instruction_set_features, - &dex_files, - image_file_location_oat_checksum, - image_file_location_oat_begin, - image_file_location); - ASSERT_TRUE(oat_header.IsValid()); - - char* magic = const_cast<char*>(oat_header.GetMagic()); + OatHeader* oat_header = OatHeader::Create(instruction_set, + instruction_set_features, + &dex_files, + image_file_location_oat_checksum, + image_file_location_oat_begin, + nullptr); + ASSERT_NE(oat_header, nullptr); + ASSERT_TRUE(oat_header->IsValid()); + + char* magic = const_cast<char*>(oat_header->GetMagic()); strcpy(magic, ""); // bad magic - ASSERT_FALSE(oat_header.IsValid()); + ASSERT_FALSE(oat_header->IsValid()); strcpy(magic, "oat\n000"); // bad version - ASSERT_FALSE(oat_header.IsValid()); + ASSERT_FALSE(oat_header->IsValid()); } } // namespace art diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index e1b6992c47..92ed33c644 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -49,19 +49,19 @@ namespace art { OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, uint32_t image_file_location_oat_checksum, uintptr_t image_file_location_oat_begin, - const std::string& image_file_location, const CompilerDriver* compiler, - TimingLogger* timings) + TimingLogger* timings, + SafeMap<std::string, std::string>* key_value_store) : compiler_driver_(compiler), dex_files_(&dex_files), image_file_location_oat_checksum_(image_file_location_oat_checksum), image_file_location_oat_begin_(image_file_location_oat_begin), - image_file_location_(image_file_location), + key_value_store_(key_value_store), oat_header_(NULL), size_dex_file_alignment_(0), size_executable_offset_alignment_(0), size_oat_header_(0), - size_oat_header_image_file_location_(0), + size_oat_header_key_value_store_(0), size_dex_file_(0), size_interpreter_to_interpreter_bridge_(0), size_interpreter_to_compiled_code_bridge_(0), @@ -89,6 +89,8 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, size_oat_class_status_(0), size_oat_class_method_bitmaps_(0), size_oat_class_method_offsets_(0) { + CHECK(key_value_store != nullptr); + size_t offset; { TimingLogger::ScopedTiming split("InitOatHeader", timings); @@ -121,7 +123,8 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, size_ = offset; CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); - CHECK(image_file_location.empty() == compiler->IsImage()); + CHECK_EQ(compiler->IsImage(), + key_value_store_->find(OatHeader::kImageLocationKey) == key_value_store_->end()); } OatWriter::~OatWriter() { @@ -716,16 +719,14 @@ bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) { } size_t OatWriter::InitOatHeader() { - // create the OatHeader - oat_header_ = new OatHeader(compiler_driver_->GetInstructionSet(), - compiler_driver_->GetInstructionSetFeatures(), - dex_files_, - image_file_location_oat_checksum_, - image_file_location_oat_begin_, - image_file_location_); - size_t offset = sizeof(*oat_header_); - offset += image_file_location_.size(); - return offset; + oat_header_ = OatHeader::Create(compiler_driver_->GetInstructionSet(), + compiler_driver_->GetInstructionSetFeatures(), + dex_files_, + image_file_location_oat_checksum_, + image_file_location_oat_begin_, + key_value_store_); + + return oat_header_->GetHeaderSize(); } size_t OatWriter::InitOatDexFiles(size_t offset) { @@ -864,17 +865,13 @@ size_t OatWriter::InitOatCodeDexFiles(size_t offset) { bool OatWriter::Write(OutputStream* out) { const size_t file_offset = out->Seek(0, kSeekCurrent); - if (!out->WriteFully(oat_header_, sizeof(*oat_header_))) { + size_t header_size = oat_header_->GetHeaderSize(); + if (!out->WriteFully(oat_header_, header_size)) { PLOG(ERROR) << "Failed to write oat header to " << out->GetLocation(); return false; } - size_oat_header_ += sizeof(*oat_header_); - - if (!out->WriteFully(image_file_location_.data(), image_file_location_.size())) { - PLOG(ERROR) << "Failed to write oat header image file location to " << out->GetLocation(); - return false; - } - size_oat_header_image_file_location_ += image_file_location_.size(); + size_oat_header_ += sizeof(OatHeader); + size_oat_header_key_value_store_ += oat_header_->GetHeaderSize() - sizeof(OatHeader); if (!WriteTables(out, file_offset)) { LOG(ERROR) << "Failed to write oat tables to " << out->GetLocation(); @@ -909,7 +906,7 @@ bool OatWriter::Write(OutputStream* out) { DO_STAT(size_dex_file_alignment_); DO_STAT(size_executable_offset_alignment_); DO_STAT(size_oat_header_); - DO_STAT(size_oat_header_image_file_location_); + DO_STAT(size_oat_header_key_value_store_); DO_STAT(size_dex_file_); DO_STAT(size_interpreter_to_interpreter_bridge_); DO_STAT(size_interpreter_to_compiled_code_bridge_); diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h index dbecb95362..3d34956651 100644 --- a/compiler/oat_writer.h +++ b/compiler/oat_writer.h @@ -79,9 +79,9 @@ class OatWriter { OatWriter(const std::vector<const DexFile*>& dex_files, uint32_t image_file_location_oat_checksum, uintptr_t image_file_location_oat_begin, - const std::string& image_file_location, const CompilerDriver* compiler, - TimingLogger* timings); + TimingLogger* timings, + SafeMap<std::string, std::string>* key_value_store); const OatHeader& GetOatHeader() const { return *oat_header_; @@ -253,9 +253,9 @@ class OatWriter { // dependencies on the image. uint32_t image_file_location_oat_checksum_; uintptr_t image_file_location_oat_begin_; - std::string image_file_location_; // data to write + SafeMap<std::string, std::string>* key_value_store_; OatHeader* oat_header_; std::vector<OatDexFile*> oat_dex_files_; std::vector<OatClass*> oat_classes_; @@ -274,7 +274,7 @@ class OatWriter { uint32_t size_dex_file_alignment_; uint32_t size_executable_offset_alignment_; uint32_t size_oat_header_; - uint32_t size_oat_header_image_file_location_; + uint32_t size_oat_header_key_value_store_; uint32_t size_dex_file_; uint32_t size_interpreter_to_interpreter_bridge_; uint32_t size_interpreter_to_compiled_code_bridge_; |