diff options
author | Andreas Gampe <agampe@google.com> | 2014-07-09 11:38:21 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-07-11 15:53:27 -0700 |
commit | 22f8e5c82d12951be38cd893426e13bee33fd69d (patch) | |
tree | f575655ba55315205b7a73f1e02773497913b157 /runtime/oat_file.cc | |
parent | 946a55fa7aec5058d357b601ac3554e242cd1afa (diff) | |
download | art-22f8e5c82d12951be38cd893426e13bee33fd69d.zip art-22f8e5c82d12951be38cd893426e13bee33fd69d.tar.gz art-22f8e5c82d12951be38cd893426e13bee33fd69d.tar.bz2 |
Revert "Revert "ART: Key-Value Store in Oat header""
This reverts commit 452bee5da9811f62123978e142bd67b385e9ff82.
Heap-allocate a couple of objects in dex2oat to avoid large frame
size.
Includes fixes originally in 100596 and 100605.
Change-Id: Id51a44198c973c91f0a3f87b9d992a5dc110c6f8
Diffstat (limited to 'runtime/oat_file.cc')
-rw-r--r-- | runtime/oat_file.cc | 67 |
1 files changed, 50 insertions, 17 deletions
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index 6c44aa9..9cefcb6 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -17,17 +17,20 @@ #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" @@ -55,28 +58,58 @@ OatFile* OatFile::Open(const std::string& filename, std::string* error_msg) { CHECK(!filename.empty()) << location; CheckLocation(filename); - if (kUsePortableCompiler) { + std::unique_ptr<OatFile> ret; + if (kUsePortableCompiler && executable) { // 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 - if (executable) { - return OpenDlopen(filename, location, requested_base, error_msg); + 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; } + 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; } - // 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; + + 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)) { + // Check whether the runtime agrees with the recorded checks. + if (ImplicitCheckOptions::CheckRuntimeSupport(executable, explicit_null_checks, + explicit_so_checks, explicit_suspend_checks, + error_msg)) { + return ret.release(); + } else { + return nullptr; + } + } else { + *error_msg = "Failed parsing implicit check options."; + return nullptr; } - return OpenElfFile(file.get(), location, requested_base, false, executable, error_msg); } OatFile* OatFile::OpenWritable(File* file, const std::string& location, std::string* error_msg) { @@ -206,11 +239,11 @@ bool OatFile::Setup(std::string* error_msg) { return false; } - oat += GetOatHeader().GetImageFileLocationSize(); + oat += GetOatHeader().GetKeyValueStoreSize(); if (oat > End()) { - *error_msg = StringPrintf("In oat file '%s' found truncated image file location: " + *error_msg = StringPrintf("In oat file '%s' found truncated variable-size data: " "%p + %zd + %ud <= %p", GetLocation().c_str(), - Begin(), sizeof(OatHeader), GetOatHeader().GetImageFileLocationSize(), + Begin(), sizeof(OatHeader), GetOatHeader().GetKeyValueStoreSize(), End()); return false; } |