Enable annotation parsing in profman
Class and method samples can now be annotated with the package that
generated then by using "{annotation}" prefix in front of a profile line.
This is a pre-step for allowing the testing of boot image profile
generation in profman.
Test: gtest
Bug: 152574358
Merged-In: Ibd5e459ae8d6ae0ca1407d0937872b82f1eb2572
Change-Id: Ibd5e459ae8d6ae0ca1407d0937872b82f1eb2572
diff --git a/profman/profman.cc b/profman/profman.cc
index b76bb2e..cfd1bf6 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -57,6 +57,8 @@
namespace art {
+using ProfileSampleAnnotation = ProfileCompilationInfo::ProfileSampleAnnotation;
+
static int original_argc;
static char** original_argv;
@@ -179,6 +181,8 @@
static const std::string kInvalidClassDescriptor = "invalid_class"; // NOLINT [runtime/string] [4]
static const std::string kInvalidMethod = "invalid_method"; // NOLINT [runtime/string] [4]
static const std::string kClassAllMethods = "*"; // NOLINT [runtime/string] [4]
+static constexpr char kAnnotationStart = '{';
+static constexpr char kAnnotationEnd = '}';
static constexpr char kProfileParsingInlineChacheSep = '+';
static constexpr char kProfileParsingTypeSep = ',';
static constexpr char kProfileParsingFirstCharInSignature = '(';
@@ -936,18 +940,42 @@
// Process a line defining a class or a method and its inline caches.
// Upon success return true and add the class or the method info to profile.
// The possible line formats are:
- // "LJustTheCass;".
+ // "LJustTheClass;".
// "LTestInline;->inlinePolymorphic(LSuper;)I+LSubA;,LSubB;,LSubC;".
// "LTestInline;->inlinePolymorphic(LSuper;)I+LSubA;,LSubB;,invalid_class".
// "LTestInline;->inlineMissingTypes(LSuper;)I+missing_types".
- // "LTestInline;->inlineNoInlineCaches(LSuper;)I".
+ // "{annotation}LTestInline;->inlineNoInlineCaches(LSuper;)I".
// "LTestInline;->*".
// "invalid_class".
// "LTestInline;->invalid_method".
// The method and classes are searched only in the given dex files.
bool ProcessLine(const std::vector<std::unique_ptr<const DexFile>>& dex_files,
- const std::string& line,
+ const std::string& maybe_annotated_line,
/*out*/ProfileCompilationInfo* profile) {
+ // First, process the annotation.
+ if (maybe_annotated_line.empty()) {
+ return true;
+ }
+ // Working line variable which will contain the user input without the annotations.
+ std::string line = maybe_annotated_line;
+
+ std::string annotation_string;
+ if (maybe_annotated_line[0] == kAnnotationStart) {
+ size_t end_pos = maybe_annotated_line.find(kAnnotationEnd, 0);
+ if (end_pos == std::string::npos || end_pos == 0) {
+ LOG(ERROR) << "Invalid line: " << maybe_annotated_line;
+ return false;
+ }
+ annotation_string = maybe_annotated_line.substr(1, end_pos - 1);
+ // Update the working line.
+ line = maybe_annotated_line.substr(end_pos + 1);
+ }
+
+ ProfileSampleAnnotation annotation = annotation_string.empty()
+ ? ProfileSampleAnnotation::kNone
+ : ProfileSampleAnnotation(annotation_string);
+
+ // Now process the rest of the lines.
std::string klass;
std::string method_str;
bool is_hot = false;
@@ -1010,10 +1038,11 @@
}
}
// TODO: Check return values?
- profile->AddMethods(methods, static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags));
+ profile->AddMethods(
+ methods, static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags), annotation);
std::set<dex::TypeIndex> classes;
classes.insert(class_ref.TypeIndex());
- profile->AddClassesForDex(dex_file, classes.begin(), classes.end());
+ profile->AddClassesForDex(dex_file, classes.begin(), classes.end(), annotation);
return true;
}
@@ -1065,14 +1094,16 @@
MethodReference ref(class_ref.dex_file, method_index);
if (is_hot) {
profile->AddMethod(ProfileMethodInfo(ref, inline_caches),
- static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags));
+ static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags),
+ annotation);
}
if (flags != 0) {
if (!profile->AddMethod(ProfileMethodInfo(ref),
- static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags))) {
+ static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags),
+ annotation)) {
return false;
}
- DCHECK(profile->GetMethodHotness(ref).IsInProfile());
+ DCHECK(profile->GetMethodHotness(ref, annotation).IsInProfile()) << method_spec;
}
return true;
}