diff options
| author | 2014-07-09 07:58:38 +0000 | |
|---|---|---|
| committer | 2014-07-02 20:49:53 +0000 | |
| commit | 8078b294e8001abff5a6c8637e844b55a65fff4b (patch) | |
| tree | d23d8693bdc9d7bf155582850461c8c086c5bbcb /runtime | |
| parent | 608520c8ba1adc7d8d0623b021b7ea509b00751c (diff) | |
| parent | 452bee5da9811f62123978e142bd67b385e9ff82 (diff) | |
Merge "Revert "ART: Key-Value Store in Oat header""
Diffstat (limited to 'runtime')
| -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 |
7 files changed, 45 insertions, 351 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 860cbd207e..5180e34313 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1159,9 +1159,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 a87aa890c8..d534bcb74d 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -341,10 +341,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 dd9b58084d..372db3a580 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 b9ff0ac5ab..0000000000 --- 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 1421baffcf..857c0a24e2 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 fbed596d33..7be768c5cb 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 bae1632fa2..6c44aa91bd 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; } |