Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/proto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ uint64_t ProfileProtoBuilder::LocationID(const string &class_name,
frame_name += signature;
}

const string simplified_name =
::google::javaprofiler::SimplifyFunctionName(frame_name);
string simplified_name = frame_name;
::google::javaprofiler::SimplifyFunctionName(&simplified_name);

uint64_t function_id = builder_.FunctionId(
simplified_name.c_str(), frame_name.c_str(), file_name.c_str(), 0);
Expand Down
3 changes: 2 additions & 1 deletion third_party/javaprofiler/profile_proto_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ perftools::profiles::Location *LocationBuilder::LocationFor(

auto line = location->add_line();

auto simplified_name = SimplifyFunctionName(function_name);
string simplified_name = function_name;
SimplifyFunctionName(&simplified_name);
auto function_id = builder_->FunctionId(
simplified_name.c_str(), function_name.c_str(), file_name.c_str(), 0);

Expand Down
100 changes: 53 additions & 47 deletions third_party/javaprofiler/stacktrace_fixer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,94 +27,101 @@ namespace {
// followed by specified suffix chars and removing those. For example,
// calling the function with ("foo123bar", "foo", "321") returns "foobar".
template <size_t M, size_t N>
string SimplifySuffixedName(string name, const char (&trigger)[M],
const char (&suffix_chars)[N]) {
void SimplifySuffixedName(string *name, const char (&trigger)[M],
const char (&suffix_chars)[N]) {
size_t first = 0;
while ((first = name.find(trigger, first)) != std::string::npos) {
while ((first = name->find(trigger, first)) != std::string::npos) {
first += M - 1; // Exclude last zero char.
size_t last = name.find_first_not_of(suffix_chars, first, N);
size_t last = name->find_first_not_of(suffix_chars, first, N);
if (last == std::string::npos) {
name.erase(first);
name->erase(first);
break;
}
name.erase(first, last - first);
name->erase(first, last - first);
}
return name;
}

// Simplifies the name of a method in a dynamic class (with '$$FastClassBy*$$'
// or '$$EnhancedBy*$$' in its name) to make it more human readable, and group
// related functions under a single name. This could be done with a regexp
// replacement, but including RE2 increases the size of the agent.
string SimplifyDynamicClassName(string name) {
void SimplifyDynamicClassName(string *name) {
// Replace $$[0-9a-f]+ by $$ to remove unique values, for example in
// $FastClassByCGLIB$$fd6bdf6d.invoke.
return SimplifySuffixedName(std::move(name), "$$", "0123456789abcdef");
SimplifySuffixedName(name, "$$", "0123456789abcdef");
}

// Simplifies the name of a lambda method to replace $$Lambda$[0-9]+\.[0-9]+ by
// $$Lambda$ to remove unique values, for example in
// com.google.something.Something$$Lambda$197.1849072452.run.
string SimplifyLambdaName(string name) {
void SimplifyLambdaName(string *name) {
constexpr char trigger[] = "$$Lambda$";
constexpr char digits[] = "0123456789";
const size_t trigger_length = strlen(trigger);

// Assume and handle just one instance of a $$Lambda$ pattern.
size_t first = name.find(trigger);
size_t first = name->find(trigger);
if (first == std::string::npos) {
return name;
return;
}
first += trigger_length;
if (first >= name.size() || !isdigit(name[first])) {
return name;
if (first >= name->size() || !isdigit((*name)[first])) {
return;
}
size_t last = name.find_first_not_of(digits, first);
if (last == std::string::npos || name[last] != '.') {
return name;
size_t last = name->find_first_not_of(digits, first);
if (last == std::string::npos || (*name)[last] != '.') {
return;
}
last++; // skip the dot
if (last >= name.size() || !isdigit(name[last])) {
return name;
if (last >= name->size() || !isdigit((*name)[last])) {
return;
}
last = name.find_first_not_of(digits, last);
last = name->find_first_not_of(digits, last);
if (last == std::string::npos) {
name.erase(first);
return name;
name->erase(first);
return;
}
name.erase(first, last - first);
return name;
name->erase(first, last - first);
}

constexpr char digits[] = "0123456789";

// Simplifies the name of a method generated by the runtime as a reflection
// stub. See the test file for examples, or generateName() in
// jdk/internal/reflect/MethodAccessorGenerator.java.
string SimplifyInternalReflectionMethodName(string name) {
return SimplifySuffixedName(
SimplifySuffixedName(
SimplifySuffixedName(
std::move(name),
"jdk.internal.reflect.GeneratedConstructorAccessor",
digits),
"jdk.internal.reflect.GeneratedMethodAccessor",
digits),
void SimplifyInternalReflectionMethodName(string *name) {
SimplifySuffixedName(
name,
"jdk.internal.reflect.GeneratedConstructorAccessor",
digits);

SimplifySuffixedName(
name,
"jdk.internal.reflect.GeneratedMethodAccessor",
digits);

SimplifySuffixedName(
name,
"jdk.internal.reflect.GeneratedSerializationConstructorAccessor",
digits);
}

// Simplifies the name of a method generated by the runtime as a reflection
// stub. See the test file for examples, or generateName() in
// sun/reflect/MethodAccessorGenerator.java.
string SimplifyReflectionMethodName(string name) {
return SimplifySuffixedName(
SimplifySuffixedName(
SimplifySuffixedName(std::move(name),
"sun.reflect.GeneratedConstructorAccessor",
digits),
"sun.reflect.GeneratedMethodAccessor",
digits),
void SimplifyReflectionMethodName(string *name) {
SimplifySuffixedName(
name,
"sun.reflect.GeneratedConstructorAccessor",
digits);

SimplifySuffixedName(
name,
"sun.reflect.GeneratedMethodAccessor",
digits);

SimplifySuffixedName(
name,
"sun.reflect.GeneratedSerializationConstructorAccessor",
digits);
}
Expand Down Expand Up @@ -247,12 +254,11 @@ string ParseMethodTypeSignatureWithReturn(const char *buffer, int buffer_size,

} // namespace

string SimplifyFunctionName(const string& name) {
// The calls should be kept nested, without explicit string declarations, so
// that move semantics can be applied to minimize copies.
return SimplifyInternalReflectionMethodName(
SimplifyReflectionMethodName(
SimplifyLambdaName(SimplifyDynamicClassName(name))));
void SimplifyFunctionName(string* name) {
SimplifyDynamicClassName(name);
SimplifyLambdaName(name);
SimplifyReflectionMethodName(name);
SimplifyInternalReflectionMethodName(name);
}

void FixPath(string *s) {
Expand Down
2 changes: 1 addition & 1 deletion third_party/javaprofiler/stacktrace_fixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace google {
namespace javaprofiler {
// Simplifies the name of a function to make it more human readable, and group
// related functions under a single name.
string SimplifyFunctionName(const string& name);
void SimplifyFunctionName(string *name);

// Fix the parameter signature from a JVM type signature to a pretty-print
// one.
Expand Down