summaryrefslogtreecommitdiffstats
path: root/runtime/oat_file.cc
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-07-09 11:38:21 -0700
committerAndreas Gampe <agampe@google.com>2014-07-11 15:53:27 -0700
commit22f8e5c82d12951be38cd893426e13bee33fd69d (patch)
treef575655ba55315205b7a73f1e02773497913b157 /runtime/oat_file.cc
parent946a55fa7aec5058d357b601ac3554e242cd1afa (diff)
downloadart-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.cc67
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;
}