Add a phenotype flag to force disable CMC GC.
This new flag (`runtime_native_boot.force_disable_uffd_gc`) has priority
over the flag that enables the CMC GC
(`runtime_native_boot.enable_uffd_gc_2`).
Bug: 251150519
Test: -
1. Build with OVERRIDE_ENABLE_UFFD_GC=false
2. See "Using CollectorTypeCC GC".
3. adb shell device_config set_sync_disabled_for_tests persistent
4. adb shell device_config put runtime_native_boot enable_uffd_gc_2 true
5. adb reboot
6. See odrefresh triggered on the reboot.
7. See "Using CollectorTypeCMC GC".
8. adb shell device_config put runtime_native_boot force_disable_uffd_gc true
9. adb reboot
10. See odrefresh triggered on the reboot.
11. See "Using CollectorTypeCC GC".
Change-Id: I2a53ccadf7e2932969a80a0c86c1307a58abf47a
diff --git a/odrefresh/odr_config.h b/odrefresh/odr_config.h
index 5a11b04..44b847c 100644
--- a/odrefresh/odr_config.h
+++ b/odrefresh/odr_config.h
@@ -74,6 +74,8 @@
const android::base::NoDestructor<std::vector<SystemPropertyConfig>> kSystemProperties{
{SystemPropertyConfig{.name = "persist.device_config.runtime_native_boot.enable_uffd_gc_2",
.default_value = "false"},
+ SystemPropertyConfig{.name = "persist.device_config.runtime_native_boot.force_disable_uffd_gc",
+ .default_value = "false"},
SystemPropertyConfig{.name = kPhDisableCompactDex, .default_value = "false"},
SystemPropertyConfig{.name = kSystemPropertySystemServerCompilerFilterOverride,
.default_value = ""}}};
diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc
index aee5b29..ad308f4 100644
--- a/runtime/gc/collector/mark_compact.cc
+++ b/runtime/gc/collector/mark_compact.cc
@@ -186,7 +186,7 @@
return -1;
}
-static bool GetCachedBoolProperty(const std::string& key, bool default_value) {
+static std::unordered_map<std::string, std::string> GetCachedProperties() {
// For simplicity, we don't handle multiple calls because otherwise we would have to reset the fd.
static bool called = false;
CHECK(!called) << "GetCachedBoolProperty can be called only once";
@@ -197,7 +197,7 @@
if (fd >= 0) {
if (!android::base::ReadFdToString(fd, &cache_info_contents)) {
PLOG(ERROR) << "Failed to read cache-info from fd " << fd;
- return default_value;
+ return {};
}
} else {
std::string path = GetApexDataDalvikCacheDirectory(InstructionSet::kNone) + "/cache-info.xml";
@@ -208,7 +208,7 @@
if (errno != ENOENT) {
PLOG(ERROR) << "Failed to read cache-info from the default path";
}
- return default_value;
+ return {};
}
}
@@ -217,37 +217,51 @@
if (!cache_info.has_value()) {
// This should never happen.
LOG(ERROR) << "Failed to parse cache-info";
- return default_value;
+ return {};
}
const com::android::art::KeyValuePairList* list = cache_info->getFirstSystemProperties();
if (list == nullptr) {
// This should never happen.
LOG(ERROR) << "Missing system properties from cache-info";
- return default_value;
+ return {};
}
const std::vector<com::android::art::KeyValuePair>& properties = list->getItem();
+ std::unordered_map<std::string, std::string> result;
for (const com::android::art::KeyValuePair& pair : properties) {
- if (pair.getK() == key) {
- ParseBoolResult result = ParseBool(pair.getV());
- switch (result) {
- case ParseBoolResult::kTrue:
- return true;
- case ParseBoolResult::kFalse:
- return false;
- case ParseBoolResult::kError:
- return default_value;
- }
- }
+ result[pair.getK()] = pair.getV();
}
- return default_value;
+ return result;
+}
+
+static bool GetCachedBoolProperty(
+ const std::unordered_map<std::string, std::string>& cached_properties,
+ const std::string& key,
+ bool default_value) {
+ auto it = cached_properties.find(key);
+ if (it == cached_properties.end()) {
+ return default_value;
+ }
+ ParseBoolResult result = ParseBool(it->second);
+ switch (result) {
+ case ParseBoolResult::kTrue:
+ return true;
+ case ParseBoolResult::kFalse:
+ return false;
+ case ParseBoolResult::kError:
+ return default_value;
+ }
}
static bool SysPropSaysUffdGc() {
// The phenotype flag can change at time time after boot, but it shouldn't take effect until a
// reboot. Therefore, we read the phenotype flag from the cache info, which is generated on boot.
- return GetCachedBoolProperty("persist.device_config.runtime_native_boot.enable_uffd_gc_2",
- false) ||
- GetBoolProperty("ro.dalvik.vm.enable_uffd_gc", false);
+ std::unordered_map<std::string, std::string> cached_properties = GetCachedProperties();
+ bool phenotype_enable = GetCachedBoolProperty(
+ cached_properties, "persist.device_config.runtime_native_boot.enable_uffd_gc_2", false);
+ bool phenotype_force_disable = GetCachedBoolProperty(
+ cached_properties, "persist.device_config.runtime_native_boot.force_disable_uffd_gc", false);
+ bool build_enable = GetBoolProperty("ro.dalvik.vm.enable_uffd_gc", false);
+ return (phenotype_enable || build_enable) && !phenotype_force_disable;
}
#else
// Never called.