diff options
-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 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 111 | ||||
-rw-r--r-- | oatdump/oatdump.cc | 16 | ||||
-rw-r--r-- | runtime/class_linker.cc | 4 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 4 | ||||
-rw-r--r-- | runtime/gc/space/image_space.h | 3 | ||||
-rw-r--r-- | runtime/implicit_check_options.h | 118 | ||||
-rw-r--r-- | runtime/oat.cc | 145 | ||||
-rw-r--r-- | runtime/oat.h | 42 | ||||
-rw-r--r-- | runtime/oat_file.cc | 80 |
13 files changed, 138 insertions, 481 deletions
diff --git a/compiler/image_test.cc b/compiler/image_test.cc index 406d9d2..d52ec0a 100644 --- a/compiler/image_test.cc +++ b/compiler/image_test.cc @@ -25,7 +25,6 @@ #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" @@ -78,11 +77,8 @@ TEST_F(ImageTest, WriteRead) { t.NewTiming("WriteElf"); ScopedObjectAccess soa(Thread::Current()); - 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); + OatWriter oat_writer(class_linker->GetBootClassPath(), + 0, 0, "", compiler_driver_.get(), &timings); bool success = compiler_driver_->WriteElf(GetTestAndroidRoot(), !kIsTargetBuild, class_linker->GetBootClassPath(), diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index d2ee0ed..254faac 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -18,7 +18,6 @@ #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" @@ -112,16 +111,12 @@ 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, - &key_value_store); + &timings); bool success = compiler_driver_->WriteElf(GetTestAndroidRoot(), !kIsTargetBuild, class_linker->GetBootClassPath(), @@ -141,7 +136,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", std::string(oat_header.GetStoreValueByKey(OatHeader::kImageLocationKey))); + ASSERT_EQ("lue.art", oat_header.GetImageFileLocation()); const DexFile* dex_file = java_lang_dex_file_; uint32_t dex_file_checksum = dex_file->GetLocationChecksum(); @@ -194,20 +189,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; - 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()); + 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()); 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 92ed33c..e1b6992 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, - SafeMap<std::string, std::string>* key_value_store) + TimingLogger* timings) : 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), - key_value_store_(key_value_store), + image_file_location_(image_file_location), oat_header_(NULL), size_dex_file_alignment_(0), size_executable_offset_alignment_(0), size_oat_header_(0), - size_oat_header_key_value_store_(0), + size_oat_header_image_file_location_(0), size_dex_file_(0), size_interpreter_to_interpreter_bridge_(0), size_interpreter_to_compiled_code_bridge_(0), @@ -89,8 +89,6 @@ 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); @@ -123,8 +121,7 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, size_ = offset; CHECK_EQ(dex_files_->size(), oat_dex_files_.size()); - CHECK_EQ(compiler->IsImage(), - key_value_store_->find(OatHeader::kImageLocationKey) == key_value_store_->end()); + CHECK(image_file_location.empty() == compiler->IsImage()); } OatWriter::~OatWriter() { @@ -719,14 +716,16 @@ bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) { } size_t OatWriter::InitOatHeader() { - 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(); + // 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; } size_t OatWriter::InitOatDexFiles(size_t offset) { @@ -865,13 +864,17 @@ size_t OatWriter::InitOatCodeDexFiles(size_t offset) { bool OatWriter::Write(OutputStream* out) { const size_t file_offset = out->Seek(0, kSeekCurrent); - size_t header_size = oat_header_->GetHeaderSize(); - if (!out->WriteFully(oat_header_, header_size)) { + if (!out->WriteFully(oat_header_, sizeof(*oat_header_))) { PLOG(ERROR) << "Failed to write oat header to " << out->GetLocation(); return false; } - size_oat_header_ += sizeof(OatHeader); - size_oat_header_key_value_store_ += oat_header_->GetHeaderSize() - sizeof(OatHeader); + 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(); if (!WriteTables(out, file_offset)) { LOG(ERROR) << "Failed to write oat tables to " << out->GetLocation(); @@ -906,7 +909,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_key_value_store_); + DO_STAT(size_oat_header_image_file_location_); 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 3d34956..dbecb95 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, - SafeMap<std::string, std::string>* key_value_store); + TimingLogger* timings); 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_key_value_store_; + uint32_t size_oat_header_image_file_location_; uint32_t size_dex_file_; uint32_t size_interpreter_to_interpreter_bridge_; uint32_t size_interpreter_to_compiled_code_bridge_; diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 7f6c752..80e7724 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -48,7 +48,6 @@ #include "gc/space/image_space.h" #include "gc/space/space-inl.h" #include "image_writer.h" -#include "implicit_check_options.h" #include "leb128.h" #include "mirror/art_method-inl.h" #include "mirror/class-inl.h" @@ -337,10 +336,7 @@ class Dex2Oat { bool dump_passes, TimingLogger& timings, CumulativeLogger& compiler_phases_timings, - std::string profile_file, - SafeMap<std::string, std::string>* key_value_store) { - CHECK(key_value_store != nullptr); - + std::string profile_file) { // Handle and ClassLoader creation needs to come after Runtime::Create jobject class_loader = nullptr; Thread* self = Thread::Current(); @@ -360,18 +356,18 @@ class Dex2Oat { } std::unique_ptr<CompilerDriver> driver(new CompilerDriver(compiler_options_, - verification_results_, - method_inliner_map_, - compiler_kind_, - instruction_set_, - instruction_set_features_, - image, - image_classes.release(), - thread_count_, - dump_stats, - dump_passes, - &compiler_phases_timings, - profile_file)); + verification_results_, + method_inliner_map_, + compiler_kind_, + instruction_set_, + instruction_set_features_, + image, + image_classes.release(), + thread_count_, + dump_stats, + dump_passes, + &compiler_phases_timings, + profile_file)); driver->GetCompiler()->SetBitcodeFileName(*driver.get(), bitcode_filename); @@ -390,15 +386,11 @@ class Dex2Oat { image_file_location = image_space->GetImageFilename(); } - if (!image_file_location.empty()) { - key_value_store->Put(OatHeader::kImageLocationKey, image_file_location); - } - OatWriter oat_writer(dex_files, image_file_location_oat_checksum, image_file_location_oat_data_begin, + image_file_location, driver.get(), - &timings, - key_value_store); + &timings); t2.NewTiming("Writing ELF"); if (!driver->WriteElf(android_root, is_host, dex_files, &oat_writer, oat_file)) { @@ -1175,8 +1167,8 @@ static int dex2oat(int argc, char** argv) { Usage("Unknown --compiler-filter value %s", compiler_filter_string); } - ImplicitCheckOptions::Check(instruction_set, &explicit_null_checks, &explicit_so_checks, - &explicit_suspend_checks); + CheckExplicitCheckOptions(instruction_set, &explicit_null_checks, &explicit_so_checks, + &explicit_suspend_checks); if (!explicit_include_patch_information) { include_patch_information = @@ -1270,15 +1262,24 @@ static int dex2oat(int argc, char** argv) { // TODO: Not sure whether it's a good idea to allow anything else but the runtime option in // this case at all, as we'll have to throw away produced code for a mismatch. if (!has_explicit_checks_options) { - if (ImplicitCheckOptions::CheckForCompiling(kRuntimeISA, instruction_set, &explicit_null_checks, - &explicit_so_checks, &explicit_suspend_checks)) { - compiler_options.SetExplicitNullChecks(explicit_null_checks); - compiler_options.SetExplicitStackOverflowChecks(explicit_so_checks); - compiler_options.SetExplicitSuspendChecks(explicit_suspend_checks); + bool cross_compiling = true; + switch (kRuntimeISA) { + case kArm: + case kThumb2: + cross_compiling = instruction_set != kArm && instruction_set != kThumb2; + break; + default: + cross_compiling = instruction_set != kRuntimeISA; + break; + } + if (!cross_compiling) { + Runtime* runtime = Runtime::Current(); + compiler_options.SetExplicitNullChecks(runtime->ExplicitNullChecks()); + compiler_options.SetExplicitStackOverflowChecks(runtime->ExplicitStackOverflowChecks()); + compiler_options.SetExplicitSuspendChecks(runtime->ExplicitSuspendChecks()); } } - // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, // give it away now so that we don't starve GC. Thread* self = Thread::Current(); @@ -1377,43 +1378,19 @@ static int dex2oat(int argc, char** argv) { } } - // Fill some values into the key-value store for the oat header. - SafeMap<std::string, std::string> key_value_store; - - // Insert implicit check options. - key_value_store.Put(ImplicitCheckOptions::kImplicitChecksOatHeaderKey, - ImplicitCheckOptions::Serialize(compiler_options.GetExplicitNullChecks(), - compiler_options. - GetExplicitStackOverflowChecks(), - compiler_options.GetExplicitSuspendChecks())); - - // Insert some compiler things. - std::ostringstream oss; - for (int i = 0; i < argc; ++i) { - if (i > 0) { - oss << ' '; - } - oss << argv[i]; - } - key_value_store.Put(OatHeader::kDex2OatCmdLineKey, oss.str()); - oss.str(""); // Reset. - oss << kRuntimeISA; - key_value_store.Put(OatHeader::kDex2OatHostKey, oss.str()); - std::unique_ptr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option, - android_root, - is_host, - dex_files, - oat_file.get(), - bitcode_filename, - image, - image_classes, - dump_stats, - dump_passes, - timings, - compiler_phases_timings, - profile_file, - &key_value_store)); + android_root, + is_host, + dex_files, + oat_file.get(), + bitcode_filename, + image, + image_classes, + dump_stats, + dump_passes, + timings, + compiler_phases_timings, + profile_file)); if (compiler.get() == nullptr) { LOG(ERROR) << "Failed to create oat file: " << oat_location; diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 631d538..12970fc 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -171,18 +171,10 @@ class OatDumper { os << "IMAGE FILE LOCATION OAT BEGIN:\n"; os << StringPrintf("0x%08x\n\n", oat_header.GetImageFileLocationOatDataBegin()); - // Print the key-value store. - { - os << "KEY VALUE STORE:\n"; - size_t index = 0; - const char* key; - const char* value; - while (oat_header.GetStoreKeyValuePairByIndex(index, &key, &value)) { - os << key << " = " << value << "\n"; - index++; - } - os << "\n"; - } + os << "IMAGE FILE LOCATION:\n"; + const std::string image_file_location(oat_header.GetImageFileLocation()); + os << image_file_location; + os << "\n\n"; os << "BEGIN:\n"; os << reinterpret_cast<const void*>(oat_file_.Begin()) << "\n\n"; diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 0e4028b..60453c3 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1163,9 +1163,7 @@ void ClassLinker::InitFromImage() { OatFile& oat_file = GetImageOatFile(space); CHECK_EQ(oat_file.GetOatHeader().GetImageFileLocationOatChecksum(), 0U); CHECK_EQ(oat_file.GetOatHeader().GetImageFileLocationOatDataBegin(), 0U); - const char* image_file_location = oat_file.GetOatHeader(). - GetStoreValueByKey(OatHeader::kImageLocationKey); - CHECK(image_file_location == nullptr || *image_file_location == 0); + CHECK(oat_file.GetOatHeader().GetImageFileLocation().empty()); portable_resolution_trampoline_ = oat_file.GetOatHeader().GetPortableResolutionTrampoline(); quick_resolution_trampoline_ = oat_file.GetOatHeader().GetQuickResolutionTrampoline(); portable_imt_conflict_trampoline_ = oat_file.GetOatHeader().GetPortableImtConflictTrampoline(); diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 891ace8..61633cd 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -348,10 +348,6 @@ bool ImageSpace::ValidateOatFile(std::string* error_msg) const { return true; } -const OatFile* ImageSpace::GetOatFile() const { - return oat_file_.get(); -} - OatFile* ImageSpace::ReleaseOatFile() { CHECK(oat_file_.get() != NULL); return oat_file_.release(); diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h index dd9b580..372db3a 100644 --- a/runtime/gc/space/image_space.h +++ b/runtime/gc/space/image_space.h @@ -51,9 +51,6 @@ class ImageSpace : public MemMapSpace { static ImageHeader* ReadImageHeaderOrDie(const char* image_location, InstructionSet image_isa); - // Give access to the OatFile. - const OatFile* GetOatFile() const; - // Releases the OatFile from the ImageSpace so it can be transfer to // the caller, presumably the ClassLinker. OatFile* ReleaseOatFile() diff --git a/runtime/implicit_check_options.h b/runtime/implicit_check_options.h deleted file mode 100644 index b9ff0ac..0000000 --- a/runtime/implicit_check_options.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_RUNTIME_IMPLICIT_CHECK_OPTIONS_H_ -#define ART_RUNTIME_IMPLICIT_CHECK_OPTIONS_H_ - -#include "gc/heap.h" -#include "gc/space/image_space.h" -#include "instruction_set.h" -#include "runtime.h" - -#include <string> - -namespace art { - -class ImplicitCheckOptions { - public: - static constexpr const char* kImplicitChecksOatHeaderKey = "implicit-checks"; - - static std::string Serialize(bool explicit_null_checks, bool explicit_stack_overflow_checks, - bool explicit_suspend_checks) { - char tmp[4]; - tmp[0] = explicit_null_checks ? 'N' : 'n'; - tmp[1] = explicit_stack_overflow_checks ? 'O' : 'o'; - tmp[2] = explicit_suspend_checks ? 'S' : 's'; - tmp[3] = 0; - return std::string(tmp); - } - - static bool Parse(const char* str, bool* explicit_null_checks, - bool* explicit_stack_overflow_checks, bool* explicit_suspend_checks) { - if (str != nullptr && str[0] != 0 && str[1] != 0 && str[2] != 0 && - (str[0] == 'n' || str[0] == 'N') && - (str[1] == 'o' || str[1] == 'O') && - (str[2] == 's' || str[2] == 'S')) { - *explicit_null_checks = str[0] == 'N'; - *explicit_stack_overflow_checks = str[1] == 'O'; - *explicit_suspend_checks = str[2] == 'S'; - return true; - } else { - return false; - } - } - - static void Check(InstructionSet isa, bool* explicit_null_checks, - bool* explicit_stack_overflow_checks, bool* explicit_suspend_checks) { - switch (isa) { - case kArm: - case kThumb2: - break; // All checks implemented, leave as is. - - default: // No checks implemented, reset all to explicit checks. - *explicit_null_checks = true; - *explicit_stack_overflow_checks = true; - *explicit_suspend_checks = true; - } - } - - static bool CheckForCompiling(InstructionSet host, InstructionSet target, - bool* explicit_null_checks, bool* explicit_stack_overflow_checks, - bool* explicit_suspend_checks) { - // Check the boot image settings. - Runtime* runtime = Runtime::Current(); - if (runtime != nullptr) { - gc::space::ImageSpace* ispace = runtime->GetHeap()->GetImageSpace(); - if (ispace != nullptr) { - const OatFile* oat_file = ispace->GetOatFile(); - if (oat_file != nullptr) { - const char* v = oat_file->GetOatHeader().GetStoreValueByKey(kImplicitChecksOatHeaderKey); - if (!Parse(v, explicit_null_checks, explicit_stack_overflow_checks, - explicit_suspend_checks)) { - LOG(FATAL) << "Should have been able to parse boot image implicit check values"; - } - return true; - } - } - } - - // Check the current runtime. - bool cross_compiling = true; - switch (host) { - case kArm: - case kThumb2: - cross_compiling = target != kArm && target != kThumb2; - break; - default: - cross_compiling = host != target; - break; - } - if (!cross_compiling) { - Runtime* runtime = Runtime::Current(); - *explicit_null_checks = runtime->ExplicitNullChecks(); - *explicit_stack_overflow_checks = runtime->ExplicitStackOverflowChecks(); - *explicit_suspend_checks = runtime->ExplicitSuspendChecks(); - return true; - } - - // Give up. - return false; - } -}; - -} // namespace art - -#endif // ART_RUNTIME_IMPLICIT_CHECK_OPTIONS_H_ diff --git a/runtime/oat.cc b/runtime/oat.cc index 1421baf..857c0a2 100644 --- a/runtime/oat.cc +++ b/runtime/oat.cc @@ -17,46 +17,15 @@ #include "oat.h" #include "utils.h" -#include <string.h> #include <zlib.h> namespace art { const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' }; -const uint8_t OatHeader::kOatVersion[] = { '0', '3', '7', '\0' }; - -static size_t ComputeOatHeaderSize(const SafeMap<std::string, std::string>* variable_data) { - size_t estimate = 0U; - if (variable_data != nullptr) { - SafeMap<std::string, std::string>::const_iterator it = variable_data->begin(); - SafeMap<std::string, std::string>::const_iterator end = variable_data->end(); - for ( ; it != end; ++it) { - estimate += it->first.length() + 1; - estimate += it->second.length() + 1; - } - } - return sizeof(OatHeader) + estimate; -} - -OatHeader* OatHeader::Create(InstructionSet instruction_set, - const InstructionSetFeatures& instruction_set_features, - const std::vector<const DexFile*>* dex_files, - uint32_t image_file_location_oat_checksum, - uint32_t image_file_location_oat_data_begin, - const SafeMap<std::string, std::string>* variable_data) { - // Estimate size of optional data. - size_t needed_size = ComputeOatHeaderSize(variable_data); - - // Reserve enough memory. - void* memory = operator new (needed_size); +const uint8_t OatHeader::kOatVersion[] = { '0', '3', '6', '\0' }; - // Create the OatHeader in-place. - return new (memory) OatHeader(instruction_set, - instruction_set_features, - dex_files, - image_file_location_oat_checksum, - image_file_location_oat_data_begin, - variable_data); +OatHeader::OatHeader() { + memset(this, 0, sizeof(*this)); } OatHeader::OatHeader(InstructionSet instruction_set, @@ -64,7 +33,7 @@ OatHeader::OatHeader(InstructionSet instruction_set, const std::vector<const DexFile*>* dex_files, uint32_t image_file_location_oat_checksum, uint32_t image_file_location_oat_data_begin, - const SafeMap<std::string, std::string>* variable_data) { + const std::string& image_file_location) { memcpy(magic_, kOatMagic, sizeof(kOatMagic)); memcpy(version_, kOatVersion, sizeof(kOatVersion)); @@ -87,16 +56,9 @@ OatHeader::OatHeader(InstructionSet instruction_set, image_file_location_oat_data_begin_ = image_file_location_oat_data_begin; UpdateChecksum(&image_file_location_oat_data_begin_, sizeof(image_file_location_oat_data_begin_)); - // Flatten the map. Will also update variable_size_data_size_. - Flatten(variable_data); - - // Update checksum for variable data size. - UpdateChecksum(&key_value_store_size_, sizeof(key_value_store_size_)); - - // Update for data, if existing. - if (key_value_store_size_ > 0U) { - UpdateChecksum(&key_value_store_, key_value_store_size_); - } + image_file_location_size_ = image_file_location.size(); + UpdateChecksum(&image_file_location_size_, sizeof(image_file_location_size_)); + UpdateChecksum(image_file_location.data(), image_file_location_size_); executable_offset_ = 0; interpreter_to_interpreter_bridge_offset_ = 0; @@ -365,97 +327,20 @@ uint32_t OatHeader::GetImageFileLocationOatDataBegin() const { return image_file_location_oat_data_begin_; } -uint32_t OatHeader::GetKeyValueStoreSize() const { +uint32_t OatHeader::GetImageFileLocationSize() const { CHECK(IsValid()); - return key_value_store_size_; + return image_file_location_size_; } -const uint8_t* OatHeader::GetKeyValueStore() const { +const uint8_t* OatHeader::GetImageFileLocationData() const { CHECK(IsValid()); - return key_value_store_; -} - -// Advance start until it is either end or \0. -static const char* ParseString(const char* start, const char* end) { - while (start < end && *start != 0) { - start++; - } - return start; -} - -const char* OatHeader::GetStoreValueByKey(const char* key) const { - const char* ptr = reinterpret_cast<const char*>(&key_value_store_); - const char* end = ptr + key_value_store_size_; - - while (ptr < end) { - // Scan for a closing zero. - const char* str_end = ParseString(ptr, end); - if (str_end < end) { - if (strcmp(key, ptr) == 0) { - // Same as key. Check if value is OK. - if (ParseString(str_end + 1, end) < end) { - return str_end + 1; - } - } else { - // Different from key. Advance over the value. - ptr = ParseString(str_end + 1, end) + 1; - } - } else { - break; - } - } - // Not found. - return nullptr; -} - -bool OatHeader::GetStoreKeyValuePairByIndex(size_t index, const char** key, - const char** value) const { - const char* ptr = reinterpret_cast<const char*>(&key_value_store_); - const char* end = ptr + key_value_store_size_; - ssize_t counter = static_cast<ssize_t>(index); - - while (ptr < end && counter >= 0) { - // Scan for a closing zero. - const char* str_end = ParseString(ptr, end); - if (str_end < end) { - const char* maybe_key = ptr; - ptr = ParseString(str_end + 1, end) + 1; - if (ptr <= end) { - if (counter == 0) { - *key = maybe_key; - *value = str_end + 1; - return true; - } else { - counter--; - } - } else { - return false; - } - } else { - break; - } - } - // Not found. - return false; + return image_file_location_data_; } -size_t OatHeader::GetHeaderSize() const { - return sizeof(OatHeader) + key_value_store_size_; -} - -void OatHeader::Flatten(const SafeMap<std::string, std::string>* key_value_store) { - char* data_ptr = reinterpret_cast<char*>(&key_value_store_); - if (key_value_store != nullptr) { - SafeMap<std::string, std::string>::const_iterator it = key_value_store->begin(); - SafeMap<std::string, std::string>::const_iterator end = key_value_store->end(); - for ( ; it != end; ++it) { - strcpy(data_ptr, it->first.c_str()); - data_ptr += it->first.length() + 1; - strcpy(data_ptr, it->second.c_str()); - data_ptr += it->second.length() + 1; - } - } - key_value_store_size_ = data_ptr - reinterpret_cast<char*>(&key_value_store_); +std::string OatHeader::GetImageFileLocation() const { + CHECK(IsValid()); + return std::string(reinterpret_cast<const char*>(GetImageFileLocationData()), + GetImageFileLocationSize()); } OatMethodOffsets::OatMethodOffsets() diff --git a/runtime/oat.h b/runtime/oat.h index fbed596..7be768c 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -23,7 +23,6 @@ #include "dex_file.h" #include "instruction_set.h" #include "quick/quick_method_frame_info.h" -#include "safe_map.h" namespace art { @@ -32,16 +31,13 @@ class PACKED(4) OatHeader { static const uint8_t kOatMagic[4]; static const uint8_t kOatVersion[4]; - static constexpr const char* kImageLocationKey = "image-location"; - static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; - static constexpr const char* kDex2OatHostKey = "dex2oat-host"; - - static OatHeader* Create(InstructionSet instruction_set, - const InstructionSetFeatures& instruction_set_features, - const std::vector<const DexFile*>* dex_files, - uint32_t image_file_location_oat_checksum, - uint32_t image_file_location_oat_data_begin, - const SafeMap<std::string, std::string>* variable_data); + OatHeader(); + OatHeader(InstructionSet instruction_set, + const InstructionSetFeatures& instruction_set_features, + const std::vector<const DexFile*>* dex_files, + uint32_t image_file_location_oat_checksum, + uint32_t image_file_location_oat_data_begin, + const std::string& image_file_location); bool IsValid() const; const char* GetMagic() const; @@ -92,24 +88,11 @@ class PACKED(4) OatHeader { const InstructionSetFeatures& GetInstructionSetFeatures() const; uint32_t GetImageFileLocationOatChecksum() const; uint32_t GetImageFileLocationOatDataBegin() const; - - uint32_t GetKeyValueStoreSize() const; - const uint8_t* GetKeyValueStore() const; - const char* GetStoreValueByKey(const char* key) const; - bool GetStoreKeyValuePairByIndex(size_t index, const char** key, const char** value) const; - - size_t GetHeaderSize() const; + uint32_t GetImageFileLocationSize() const; + const uint8_t* GetImageFileLocationData() const; + std::string GetImageFileLocation() const; private: - OatHeader(InstructionSet instruction_set, - const InstructionSetFeatures& instruction_set_features, - const std::vector<const DexFile*>* dex_files, - uint32_t image_file_location_oat_checksum, - uint32_t image_file_location_oat_data_begin, - const SafeMap<std::string, std::string>* variable_data); - - void Flatten(const SafeMap<std::string, std::string>* variable_data); - uint8_t magic_[4]; uint8_t version_[4]; uint32_t adler32_checksum_; @@ -131,9 +114,8 @@ class PACKED(4) OatHeader { uint32_t image_file_location_oat_checksum_; uint32_t image_file_location_oat_data_begin_; - - uint32_t key_value_store_size_; - uint8_t key_value_store_[0]; // note variable width data at end + uint32_t image_file_location_size_; + uint8_t image_file_location_data_[0]; // note variable width data at end DISALLOW_COPY_AND_ASSIGN(OatHeader); }; diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index bae1632..6c44aa9 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -17,20 +17,17 @@ #include "oat_file.h" #include <dlfcn.h> -#include <sstream> #include "base/bit_vector.h" #include "base/stl_util.h" #include "base/unix_file/fd_file.h" #include "elf_file.h" -#include "implicit_check_options.h" #include "oat.h" #include "mirror/art_method.h" #include "mirror/art_method-inl.h" #include "mirror/class.h" #include "mirror/object-inl.h" #include "os.h" -#include "runtime.h" #include "utils.h" #include "vmap_table.h" @@ -58,71 +55,28 @@ OatFile* OatFile::Open(const std::string& filename, std::string* error_msg) { CHECK(!filename.empty()) << location; CheckLocation(filename); - std::unique_ptr<OatFile> ret; - if (kUsePortableCompiler && executable) { + if (kUsePortableCompiler) { // If we are using PORTABLE, use dlopen to deal with relocations. // // We use our own ELF loader for Quick to deal with legacy apps that // open a generated dex file by name, remove the file, then open // another generated dex file with the same name. http://b/10614658 - ret.reset(OpenDlopen(filename, location, requested_base, error_msg)); - } else { - // If we aren't trying to execute, we just use our own ElfFile loader for a couple reasons: - // - // On target, dlopen may fail when compiling due to selinux restrictions on installd. - // - // On host, dlopen is expected to fail when cross compiling, so fall back to OpenElfFile. - // This won't work for portable runtime execution because it doesn't process relocations. - std::unique_ptr<File> file(OS::OpenFileForReading(filename.c_str())); - if (file.get() == NULL) { - *error_msg = StringPrintf("Failed to open oat filename for reading: %s", strerror(errno)); - return nullptr; + if (executable) { + return OpenDlopen(filename, location, requested_base, error_msg); } - ret.reset(OpenElfFile(file.get(), location, requested_base, false, executable, error_msg)); - } - - if (ret.get() == nullptr) { - return nullptr; - } - - // Embedded options check. Right now only implicit checks. - // TODO: Refactor to somewhere else? - const char* implicit_checks_value = ret->GetOatHeader(). - GetStoreValueByKey(ImplicitCheckOptions::kImplicitChecksOatHeaderKey); - - if (implicit_checks_value == nullptr) { - *error_msg = "Did not find implicit checks value."; - return nullptr; } - - bool explicit_null_checks, explicit_so_checks, explicit_suspend_checks; - if (ImplicitCheckOptions::Parse(implicit_checks_value, &explicit_null_checks, - &explicit_so_checks, &explicit_suspend_checks)) { - if (!executable) { - // Not meant to be run, i.e., either we are compiling or dumping. Just accept. - return ret.release(); - } - - Runtime* runtime = Runtime::Current(); - // We really should have a runtime. - DCHECK_NE(static_cast<Runtime*>(nullptr), runtime); - - if (runtime->ExplicitNullChecks() != explicit_null_checks || - runtime->ExplicitStackOverflowChecks() != explicit_so_checks || - runtime->ExplicitSuspendChecks() != explicit_suspend_checks) { - std::ostringstream os; - os << "Explicit check options do not match runtime: " << implicit_checks_value << " -> "; - os << runtime->ExplicitNullChecks() << " vs " << explicit_null_checks << " | "; - os << runtime->ExplicitStackOverflowChecks() << " vs " << explicit_so_checks << " | "; - os << runtime->ExplicitSuspendChecks() << " vs " << explicit_suspend_checks; - *error_msg = os.str(); - return nullptr; - } - return ret.release(); - } else { - *error_msg = "Failed parsing implicit check options."; - return nullptr; + // If we aren't trying to execute, we just use our own ElfFile loader for a couple reasons: + // + // On target, dlopen may fail when compiling due to selinux restrictions on installd. + // + // On host, dlopen is expected to fail when cross compiling, so fall back to OpenElfFile. + // This won't work for portable runtime execution because it doesn't process relocations. + std::unique_ptr<File> file(OS::OpenFileForReading(filename.c_str())); + if (file.get() == NULL) { + *error_msg = StringPrintf("Failed to open oat filename for reading: %s", strerror(errno)); + return NULL; } + return OpenElfFile(file.get(), location, requested_base, false, executable, error_msg); } OatFile* OatFile::OpenWritable(File* file, const std::string& location, std::string* error_msg) { @@ -252,11 +206,11 @@ bool OatFile::Setup(std::string* error_msg) { return false; } - oat += GetOatHeader().GetKeyValueStoreSize(); + oat += GetOatHeader().GetImageFileLocationSize(); if (oat > End()) { - *error_msg = StringPrintf("In oat file '%s' found truncated variable-size data: " + *error_msg = StringPrintf("In oat file '%s' found truncated image file location: " "%p + %zd + %ud <= %p", GetLocation().c_str(), - Begin(), sizeof(OatHeader), GetOatHeader().GetKeyValueStoreSize(), + Begin(), sizeof(OatHeader), GetOatHeader().GetImageFileLocationSize(), End()); return false; } |