summaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/gc/heap.cc12
-rw-r--r--runtime/gc/heap.h1
-rw-r--r--runtime/oat_file.h7
-rw-r--r--runtime/oat_file_assistant_test.cc4
-rw-r--r--runtime/oat_file_manager.cc31
5 files changed, 40 insertions, 15 deletions
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index b919cdda60..401394af6e 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -870,6 +870,18 @@ bool Heap::IsCompilingBoot() const {
return true;
}
+bool Heap::HasAppImageSpace() const {
+ for (const auto& space : GetContinuousSpaces()) {
+ if (space->IsImageSpace()) {
+ const gc::space::ImageSpace* image_space = space->AsImageSpace();
+ if (image_space->GetImageHeader().IsAppImage()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void Heap::IncrementDisableMovingGC(Thread* self) {
// Need to do this holding the lock to prevent races where the GC is about to run / running when
// we attempt to disable it.
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 515dcb3a6d..9008c01a2b 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -783,6 +783,7 @@ class Heap {
bool HasBootImageSpace() const {
return !boot_image_spaces_.empty();
}
+ bool HasAppImageSpace() const REQUIRES_SHARED(Locks::mutator_lock_);
ReferenceProcessor* GetReferenceProcessor() {
return reference_processor_.get();
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index dce34d9728..75770d73f9 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -378,6 +378,13 @@ class OatFile {
return external_dex_files_.empty();
}
+ // Returns whether an image (e.g. app image) is required to safely execute this OAT file.
+ inline bool RequiresImage() const {
+ // We currently require images only for speed profile and everything profile.
+ return GetCompilerFilter() == CompilerFilter::Filter::kSpeedProfile ||
+ GetCompilerFilter() == CompilerFilter::Filter::kEverythingProfile;
+ }
+
protected:
OatFile(const std::string& filename, bool executable);
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index ed47ca3a6b..e8a7381296 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -1437,6 +1437,7 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
TEST_F(OatFileAssistantTest, GetDexLocation) {
std::string dex_location = GetScratchDir() + "/TestDex.jar";
std::string oat_location = GetOdexDir() + "/TestDex.odex";
+ std::string art_location = GetOdexDir() + "/TestDex.art";
// Start the runtime to initialize the system's class loader.
Thread::Current()->TransitionFromSuspendedToRunnable();
@@ -1463,6 +1464,7 @@ TEST_F(OatFileAssistantTest, GetDexLocation) {
args.push_back("--dex-file=" + dex_location);
args.push_back("--dex-location=TestDex.jar");
args.push_back("--oat-file=" + oat_location);
+ args.push_back("--app-image-file=" + art_location);
std::string error_msg;
ASSERT_TRUE(DexoptTest::Dex2Oat(args, &error_msg)) << error_msg;
}
@@ -1490,6 +1492,7 @@ TEST_F(OatFileAssistantTest, SystemFrameworkDir) {
odex_dir = odex_dir + std::string(GetInstructionSetString(kRuntimeISA));
mkdir(odex_dir.c_str(), 0700);
std::string oat_location = odex_dir + "/" + filebase + ".odex";
+ std::string art_location = odex_dir + "/" + filebase + ".art";
// Clean up in case previous run crashed.
remove(oat_location.c_str());
@@ -1527,6 +1530,7 @@ TEST_F(OatFileAssistantTest, SystemFrameworkDir) {
args.push_back("--dex-file=" + dex_location);
args.push_back("--dex-location=" + filebase + ".jar");
args.push_back("--oat-file=" + oat_location);
+ args.push_back("--app-image-file=" + art_location);
std::string error_msg;
ASSERT_TRUE(DexoptTest::Dex2Oat(args, &error_msg)) << error_msg;
}
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index ff743d5158..7101a23d43 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -492,13 +492,14 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
const OatFile* source_oat_file = nullptr;
CheckCollisionResult check_collision_result = CheckCollisionResult::kPerformedHasCollisions;
std::string error_msg;
+ bool accept_oat_file = false;
if ((class_loader != nullptr || dex_elements != nullptr) && oat_file != nullptr) {
// Prevent oat files from being loaded if no class_loader or dex_elements are provided.
// This can happen when the deprecated DexFile.<init>(String) is called directly, and it
// could load oat files without checking the classpath, which would be incorrect.
// Take the file only if it has no collisions, or we must take it because of preopting.
check_collision_result = CheckCollision(oat_file.get(), context.get(), /*out*/ &error_msg);
- bool accept_oat_file = AcceptOatFile(check_collision_result);
+ accept_oat_file = AcceptOatFile(check_collision_result);
if (!accept_oat_file) {
// Failed the collision check. Print warning.
if (runtime->IsDexFileFallbackEnabled()) {
@@ -531,30 +532,24 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
LOG(WARNING) << error_msg;
}
-
- if (accept_oat_file) {
- VLOG(class_linker) << "Registering " << oat_file->GetLocation();
- source_oat_file = RegisterOatFile(std::move(oat_file));
- *out_oat_file = source_oat_file;
- }
}
std::vector<std::unique_ptr<const DexFile>> dex_files;
// Load the dex files from the oat file.
- if (source_oat_file != nullptr) {
- bool added_image_space = false;
- if (source_oat_file->IsExecutable()) {
+ bool added_image_space = false;
+ if (accept_oat_file) {
+ if (oat_file->IsExecutable()) {
ScopedTrace app_image_timing("AppImage:Loading");
// We need to throw away the image space if we are debuggable but the oat-file source of the
// image is not otherwise we might get classes with inlined methods or other such things.
std::unique_ptr<gc::space::ImageSpace> image_space;
if (ShouldLoadAppImage(check_collision_result,
- source_oat_file,
+ oat_file.get(),
context.get(),
&error_msg)) {
- image_space = oat_file_assistant.OpenImageSpace(source_oat_file);
+ image_space = oat_file_assistant.OpenImageSpace(oat_file.get());
}
if (image_space != nullptr) {
ScopedObjectAccess soa(self);
@@ -606,9 +601,9 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
}
}
}
- if (!added_image_space) {
+ if (!added_image_space && !oat_file->RequiresImage()) {
DCHECK(dex_files.empty());
- dex_files = oat_file_assistant.LoadDexFiles(*source_oat_file, dex_location);
+ dex_files = oat_file_assistant.LoadDexFiles(*oat_file.get(), dex_location);
// Register for tracking.
for (const auto& dex_file : dex_files) {
@@ -616,7 +611,7 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
}
}
if (dex_files.empty()) {
- error_msgs->push_back("Failed to open dex files from " + source_oat_file->GetLocation());
+ error_msgs->push_back("Failed to open dex files from " + oat_file->GetLocation());
} else {
// Opened dex files from an oat file, madvise them to their loaded state.
for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
@@ -625,6 +620,12 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
}
}
+ if (accept_oat_file && (added_image_space || !oat_file->RequiresImage())) {
+ VLOG(class_linker) << "Registering " << oat_file->GetLocation();
+ source_oat_file = RegisterOatFile(std::move(oat_file));
+ *out_oat_file = source_oat_file;
+ }
+
// Fall back to running out of the original dex file if we couldn't load any
// dex_files from the oat file.
if (dex_files.empty()) {