ART: Restrict ImageSpace space check to first image
The "secondary image inconsistent" path is sensitive to running
the space check twice.
Also disable patching/compilation under low-space condition to
not fill up the space again.
Bug: 73667005
Test: m
Test: manual
Change-Id: Ic93c28c272e6485b06fdb887a3d873a381db94af
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 9ae1f45..366eb53 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1531,15 +1531,20 @@
&has_cache,
&cache_filename);
- if (is_zygote && dalvik_cache_exists) {
+ bool dex2oat_enabled = Runtime::Current()->IsImageDex2OatEnabled();
+
+ if (is_zygote && dalvik_cache_exists && !secondary_image) {
+ // Extra checks for the zygote. These only apply when loading the first image, explained below.
DCHECK(!dalvik_cache.empty());
std::string local_error_msg;
// All secondary images are verified when the primary image is verified.
- bool verified = secondary_image || VerifyImage(image_location,
- dalvik_cache.c_str(),
- image_isa,
- &local_error_msg);
- if (!(verified && CheckSpace(dalvik_cache, &local_error_msg))) {
+ bool verified = VerifyImage(image_location, dalvik_cache.c_str(), image_isa, &local_error_msg);
+ // If we prune for space at a secondary image, we may end up in a crash loop with the _exit
+ // path.
+ bool check_space = CheckSpace(dalvik_cache, &local_error_msg);
+ if (!verified || !check_space) {
+ // Note: it is important to only prune for space on the primary image, or we will hit the
+ // restart path.
LOG(WARNING) << local_error_msg << " Preemptively pruning the dalvik cache.";
PruneDalvikCache(image_isa);
@@ -1554,6 +1559,10 @@
&has_cache,
&cache_filename);
}
+ if (!check_space) {
+ // Disable compilation/patching - we do not want to fill up the space again.
+ dex2oat_enabled = false;
+ }
}
// Collect all the errors.
@@ -1620,7 +1629,7 @@
// secondary image.
if (found_image && has_system && relocate) {
std::string local_error_msg;
- if (!Runtime::Current()->IsImageDex2OatEnabled()) {
+ if (!dex2oat_enabled) {
local_error_msg = "Patching disabled.";
} else if (secondary_image) {
// We really want a working image. Prune and restart.
@@ -1652,7 +1661,7 @@
// cache. This step fails if this is a secondary image.
if (!has_system) {
std::string local_error_msg;
- if (!Runtime::Current()->IsImageDex2OatEnabled()) {
+ if (!dex2oat_enabled) {
local_error_msg = "Image compilation disabled.";
} else if (secondary_image) {
local_error_msg = "Cannot compile a secondary image.";