Add support for preloaded classes blacklist in profman
Profman will now filter out any blacklisted class for the list
of preloaded classes.
Test: gtest
Bug: 152574358
Merged-In: I755176c5d5afcd821c19152fd2ea941f1b80eaa8
Change-Id: I755176c5d5afcd821c19152fd2ea941f1b80eaa8
diff --git a/profman/boot_image_profile.cc b/profman/boot_image_profile.cc
index fdd0a29..d4e7f2b 100644
--- a/profman/boot_image_profile.cc
+++ b/profman/boot_image_profile.cc
@@ -185,10 +185,13 @@
// Returns true iff a class with the given metada should be included in the list of
// prelaoded classes.
-static bool IncludeInPreloadedClasses(uint32_t max_aggregation_count,
+static bool IncludeInPreloadedClasses(const std::string& class_name,
+ uint32_t max_aggregation_count,
const FlattenProfileData::ItemMetadata& metadata,
const BootImageOptions& options) {
- return IncludeItemInProfile(
+ bool blacklisted = options.preloaded_classes_blacklist.find(class_name) !=
+ options.preloaded_classes_blacklist.end();
+ return !blacklisted && IncludeItemInProfile(
max_aggregation_count, options.preloaded_class_threshold, metadata, options);
}
@@ -235,11 +238,13 @@
options)) {
profile_classes.Put(BootImageRepresentation(it.first), it.second);
}
+ std::string preloaded_class_representation = PreloadedClassesRepresentation(it.first);
if (generate_preloaded_classes && IncludeInPreloadedClasses(
+ preloaded_class_representation,
flattenData->GetMaxAggregationForClasses(),
metadata,
options)) {
- preloaded_classes.Put(PreloadedClassesRepresentation(it.first), it.second);
+ preloaded_classes.Put(preloaded_class_representation, it.second);
}
}
diff --git a/profman/boot_image_profile.h b/profman/boot_image_profile.h
index b3b4ba9..88a2a4c 100644
--- a/profman/boot_image_profile.h
+++ b/profman/boot_image_profile.h
@@ -20,6 +20,7 @@
#include <limits>
#include <memory>
#include <vector>
+#include <set>
#include "base/safe_map.h"
#include "dex/dex_file.h"
@@ -63,6 +64,9 @@
// Should be use only for debugging as it will add additional elements to the text output
// that are not compatible with the default profile format.
bool append_package_use_list = false;
+
+ // The set of classes that should not be preloaded in Zygote
+ std::set<std::string> preloaded_classes_blacklist;
};
// Generate a boot image profile according to the specified options.
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index c4d0d39..4f42eb4 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -763,6 +763,8 @@
"Ljava/lang/Object;->toString()Ljava/lang/String;";
// Method used by a special package which will get a different threshold;
const std::string kUncommonSpecialPackageMethod = "Ljava/lang/Object;->hashCode()I";
+ // Blacklisted class
+ const std::string kPreloadedBlacklistedClass = "Ljava/lang/Thread;";
// Thresholds for this test.
static const size_t kDirtyThreshold = 100;
@@ -780,30 +782,42 @@
"{dex1}H" + kCommonHotMethod,
"{dex1}P" + kStartupMethodForUpgrade,
"{dex1}" + kUncommonDirtyClass,
+ "{dex1}" + kPreloadedBlacklistedClass,
"{dex2}" + kCleanClass,
"{dex2}" + kDirtyClass,
"{dex2}P" + kCommonHotMethod,
"{dex2}P" + kStartupMethodForUpgrade,
"{dex2}" + kUncommonDirtyClass,
+ "{dex2}" + kPreloadedBlacklistedClass,
"{dex3}P" + kUncommonMethod,
"{dex3}PS" + kStartupMethodForUpgrade,
"{dex3}S" + kCommonHotMethod,
"{dex3}S" + kSpecialPackageStartupMethod,
"{dex3}" + kDirtyClass,
+ "{dex3}" + kPreloadedBlacklistedClass,
"{dex4}" + kDirtyClass,
"{dex4}P" + kCommonHotMethod,
"{dex4}S" + kSpecialPackageStartupMethod,
- "{dex4}P" + kUncommonSpecialPackageMethod
+ "{dex4}P" + kUncommonSpecialPackageMethod,
+ "{dex4}" + kPreloadedBlacklistedClass,
};
std::string input_file_contents = JoinProfileLines(input_data);
+ ScratchFile preloaded_class_blacklist;
+ std::string blacklist_content = DescriptorToDot(kPreloadedBlacklistedClass.c_str());
+ EXPECT_TRUE(preloaded_class_blacklist.GetFile()->WriteFully(
+ blacklist_content.c_str(), blacklist_content.length()));
+
+ EXPECT_EQ(0, preloaded_class_blacklist.GetFile()->Flush());
+ EXPECT_TRUE(preloaded_class_blacklist.GetFile()->ResetOffset());
// Expected data
std::vector<std::string> expected_data = {
kCleanClass,
kDirtyClass,
+ kPreloadedBlacklistedClass,
"HSP" + kCommonHotMethod,
"HS" + kSpecialPackageStartupMethod,
"HSP" + kStartupMethodForUpgrade
@@ -840,7 +854,7 @@
args.push_back("--out-preloaded-classes-path=" + out_preloaded_classes.GetFilename());
args.push_back("--apk=" + core_dex);
args.push_back("--dex-location=" + core_dex);
-
+ args.push_back("--preloaded-classes-blacklist=" + preloaded_class_blacklist.GetFilename());
std::string error;
ASSERT_EQ(ExecAndReturnCode(args, &error), 0) << error;
diff --git a/profman/profman.cc b/profman/profman.cc
index 8d46ad4..eea83cc 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -149,23 +149,25 @@
UsageError("");
UsageError(" --generate-boot-image-profile: Generate a boot image profile based on input");
UsageError(" profiles. Requires passing in dex files to inspect properties of classes.");
- UsageError(" --method-threshold=percentage between 0 and 100"
- " what threshold to apply to the methods when deciding whether or not to"
- " include it in the final profile.");
- UsageError(" --class-threshold=percentage between 0 and 100"
- " what threshold to apply to the classes when deciding whether or not to"
- " include it in the final profile.");
- UsageError(" --clean-class-threshold=percentage between 0 and 100"
- " what threshold to apply to the clean classes when deciding whether or not to"
- " include it in the final profile.");
- UsageError(" --preloaded-class-threshold=percentage between 0 and 100"
- " what threshold to apply to the classes when deciding whether or not to"
- " include it in the final preloaded classes.");
- UsageError(" --upgrade-startup-to-hot=true|false:"
- " whether or not to upgrade startup methods to hot");
- UsageError(" --special-package=pkg_name:percentage between 0 and 100"
- " what threshold to apply to the methods/classes that are used by the given"
- " package when deciding whether or not to include it in the final profile.");
+ UsageError(" --method-threshold=percentage between 0 and 100");
+ UsageError(" what threshold to apply to the methods when deciding whether or not to");
+ UsageError(" include it in the final profile.");
+ UsageError(" --class-threshold=percentage between 0 and 100");
+ UsageError(" what threshold to apply to the classes when deciding whether or not to");
+ UsageError(" include it in the final profile.");
+ UsageError(" --clean-class-threshold=percentage between 0 and 100");
+ UsageError(" what threshold to apply to the clean classes when deciding whether or not to");
+ UsageError(" include it in the final profile.");
+ UsageError(" --preloaded-class-threshold=percentage between 0 and 100");
+ UsageError(" what threshold to apply to the classes when deciding whether or not to");
+ UsageError(" include it in the final preloaded classes.");
+ UsageError(" --preloaded-classes-blacklist=file");
+ UsageError(" a file listing the classes that should not be preloaded in Zygote");
+ UsageError(" --upgrade-startup-to-hot=true|false:");
+ UsageError(" whether or not to upgrade startup methods to hot");
+ UsageError(" --special-package=pkg_name:percentage between 0 and 100");
+ UsageError(" what threshold to apply to the methods/classes that are used by the given");
+ UsageError(" package when deciding whether or not to include it in the final profile.");
UsageError(" --debug-append-uses=bool: whether or not to append package use as debug info.");
UsageError(" --out-profile-path=path: boot image profile output path");
UsageError(" --out-preloaded-classes-path=path: preloaded classes output path");
@@ -343,6 +345,15 @@
&boot_image_options_.preloaded_class_threshold,
0u,
100u);
+ } else if (StartsWith(option, "--preloaded-classes-blacklist=")) {
+ std::string preloaded_classes_blacklist =
+ std::string(option.substr(strlen("--preloaded-classes-blacklist=")));
+ // Read the user-specified list of methods.
+ std::unique_ptr<std::set<std::string>>
+ blacklist(ReadCommentedInputFromFile<std::set<std::string>>(
+ preloaded_classes_blacklist.c_str(), nullptr)); // No post-processing.
+ boot_image_options_.preloaded_classes_blacklist.insert(
+ blacklist->begin(), blacklist->end());
} else if (StartsWith(option, "--upgrade-startup-to-hot=")) {
ParseBoolOption(raw_option,
"--upgrade-startup-to-hot=",