Convert preload list to profile
Add functionality to profman to take a list of classes in a text file
(dot notation rather than descriptors) and build a compiler profile
file from it.
Bug: 34929204
Test: test-art-host
Change-Id: Id867ec7b436cbd8412809a8adb093f588ff474b7
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index a6c3cf0..d395c17 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -94,6 +94,54 @@
std::string error;
return ExecAndReturnCode(argv_str, &error);
}
+
+ bool CreateProfile(std::string class_file_contents, const std::string& filename) {
+ ScratchFile class_names_file;
+ File* file = class_names_file.GetFile();
+ EXPECT_TRUE(file->WriteFully(class_file_contents.c_str(), class_file_contents.length()));
+ EXPECT_EQ(0, file->Flush());
+ EXPECT_TRUE(file->ResetOffset());
+ std::string profman_cmd = GetProfmanCmd();
+ std::vector<std::string> argv_str;
+ argv_str.push_back(profman_cmd);
+ argv_str.push_back("--create-profile-from=" + class_names_file.GetFilename());
+ argv_str.push_back("--reference-profile-file=" + filename);
+ argv_str.push_back("--apk=" + GetLibCoreDexFileNames()[0]);
+ argv_str.push_back("--dex-location=classes.dex");
+ std::string error;
+ EXPECT_EQ(ExecAndReturnCode(argv_str, &error), 0);
+ return true;
+ }
+
+ bool DumpClasses(const std::string& filename, std::string* file_contents) {
+ ScratchFile class_names_file;
+ std::string profman_cmd = GetProfmanCmd();
+ std::vector<std::string> argv_str;
+ argv_str.push_back(profman_cmd);
+ argv_str.push_back("--dump-classes");
+ argv_str.push_back("--profile-file=" + filename);
+ argv_str.push_back("--apk=" + GetLibCoreDexFileNames()[0]);
+ argv_str.push_back("--dex-location=classes.dex");
+ argv_str.push_back("--dump-output-to-fd=" + std::to_string(GetFd(class_names_file)));
+ std::string error;
+ EXPECT_EQ(ExecAndReturnCode(argv_str, &error), 0);
+ File* file = class_names_file.GetFile();
+ EXPECT_EQ(0, file->Flush());
+ EXPECT_TRUE(file->ResetOffset());
+ int64_t length = file->GetLength();
+ std::unique_ptr<char[]> buf(new char[length]);
+ EXPECT_EQ(file->Read(buf.get(), length, 0), length);
+ *file_contents = std::string(buf.get(), length);
+ return true;
+ }
+
+ bool CreateAndDump(const std::string& input_file_contents, std::string* output_file_contents) {
+ ScratchFile profile_file;
+ EXPECT_TRUE(CreateProfile(input_file_contents, profile_file.GetFilename()));
+ profile_file.GetFile()->ResetOffset();
+ EXPECT_TRUE(DumpClasses(profile_file.GetFilename(), output_file_contents));
+ return true;
+ }
};
TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferences) {
@@ -307,4 +355,55 @@
ASSERT_TRUE(info.Load(GetFd(profile)));
}
+TEST_F(ProfileAssistantTest, TestProfileCreationAllMatch) {
+ // Class names put here need to be in sorted order.
+ std::vector<std::string> class_names = {
+ "java.lang.Comparable",
+ "java.lang.Math",
+ "java.lang.Object"
+ };
+ std::string input_file_contents;
+ for (std::string& class_name : class_names) {
+ input_file_contents += class_name + std::string("\n");
+ }
+ std::string output_file_contents;
+ ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents));
+ ASSERT_EQ(output_file_contents, input_file_contents);
+}
+
+TEST_F(ProfileAssistantTest, TestProfileCreationOneNotMatched) {
+ // Class names put here need to be in sorted order.
+ std::vector<std::string> class_names = {
+ "doesnt.match.this.one",
+ "java.lang.Comparable",
+ "java.lang.Object"
+ };
+ std::string input_file_contents;
+ for (std::string& class_name : class_names) {
+ input_file_contents += class_name + std::string("\n");
+ }
+ std::string output_file_contents;
+ ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents));
+ std::string expected_contents =
+ class_names[1] + std::string("\n") + class_names[2] + std::string("\n");
+ ASSERT_EQ(output_file_contents, expected_contents);
+}
+
+TEST_F(ProfileAssistantTest, TestProfileCreationNoneMatched) {
+ // Class names put here need to be in sorted order.
+ std::vector<std::string> class_names = {
+ "doesnt.match.this.one",
+ "doesnt.match.this.one.either",
+ "nor.this.one"
+ };
+ std::string input_file_contents;
+ for (std::string& class_name : class_names) {
+ input_file_contents += class_name + std::string("\n");
+ }
+ std::string output_file_contents;
+ ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents));
+ std::string expected_contents("");
+ ASSERT_EQ(output_file_contents, expected_contents);
+}
+
} // namespace art