Skip to content

Commit

Permalink
PerfProfiler: collapse Java interpreter stackframes, i.e. such that d…
Browse files Browse the repository at this point in the history
…eep Java stack traces are rendered without redundant Interpreter frames.

Summary: Java stack traces are deep and often include multiple "interpreter" stack frames. To provide a better visualization of the data (and as a side effect, save on memory consumption by stack trace strings) we collapse repeated interpreter frames into one frame.

Test Plan: Existing.

Reviewers: #stirling, yzhao

Reviewed By: #stirling, yzhao

Subscribers: yzhao

JIRA Issues: PP-2982, PP-3235

Signed-off-by: Pete Stevenson <jps@pixielabs.ai>

Differential Revision: https://phab.corp.pixielabs.ai/D10777

GitOrigin-RevId: 98c797e
  • Loading branch information
Pete Stevenson authored and copybaranaut committed Feb 16, 2022
1 parent 1a5f8eb commit dc168b6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
22 changes: 19 additions & 3 deletions src/stirling/source_connectors/perf_profiler/stringifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "src/stirling/source_connectors/perf_profiler/stringifier.h"
#include <stdint.h>

#include <utility>
#include <vector>

namespace px {
Expand All @@ -31,6 +32,9 @@ Stringifier::Stringifier(Symbolizer* u_symbolizer, Symbolizer* k_symbolizer,
std::string Stringifier::BuildStackTraceString(const std::vector<uintptr_t>& addrs,
profiler::SymbolizerFn symbolize_fn,
const std::string_view& suffix) {
using stringifier::kJavaInterpreter;
using stringifier::kSeparator;

// TODO(jps): re-evaluate the correct amount to reserve here.
std::string stack_trace_str;
stack_trace_str.reserve(128);
Expand All @@ -39,6 +43,7 @@ std::string Stringifier::BuildStackTraceString(const std::vector<uintptr_t>& add
// otherwise expect to find "main" or "start_thread". Given that this address
// is not a "real" address, we filter it out below.
constexpr uint64_t kSentinelAddr = 0xcccccccccccccccc;
uint64_t num_collapsed = 0;

// Build the folded stack trace string.
for (auto iter = addrs.rbegin(); iter != addrs.rend(); ++iter) {
Expand All @@ -48,9 +53,20 @@ std::string Stringifier::BuildStackTraceString(const std::vector<uintptr_t>& add
// Sentinel values can occur in other spots (though it's rare); leave those ones in.
continue;
}
stack_trace_str += symbolize_fn(addr);
stack_trace_str += suffix;
stack_trace_str += stringifier::kSeparator;
const std::string_view symbol = symbolize_fn(addr);
if (symbol == kJavaInterpreter) {
++num_collapsed;
continue;
} else if (num_collapsed > 0) {
stack_trace_str = absl::StrCat(stack_trace_str, kJavaInterpreter, " [", num_collapsed, "x]",
suffix, kSeparator);
num_collapsed = 0;
}
stack_trace_str = absl::StrCat(stack_trace_str, symbol, suffix, kSeparator);
}
if (num_collapsed) {
stack_trace_str = absl::StrCat(stack_trace_str, kJavaInterpreter, " [", num_collapsed, "x]",
suffix, kSeparator);
}

if (!stack_trace_str.empty()) {
Expand Down
10 changes: 7 additions & 3 deletions src/stirling/source_connectors/perf_profiler/stringifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ namespace stringifier {
constexpr std::string_view kSeparator = ";";

// The suffix is attached to each symbol in a folded stack trace string.
static constexpr std::string_view kUserSuffix = "";
static constexpr std::string_view kKernSuffix = "_[k]";
constexpr std::string_view kUserSuffix = "";
constexpr std::string_view kKernSuffix = "_[k]";

// This is the symbol we see for Java interpreter frames. The stringifier
// will collapse repeated instances of this into something like "[j] Interpreter [12x]".
constexpr std::string_view kJavaInterpreter = "[j] Interpreter";

// The drop message indicates that the kernel had a hash table collision
// and dropped tracking of one stack trace.
static constexpr std::string_view kDropMessage = "<stack trace lost>";
constexpr std::string_view kDropMessage = "<stack trace lost>";
} // namespace stringifier

// Stringifier serves two purposes:
Expand Down

0 comments on commit dc168b6

Please sign in to comment.