Commit 1cb19f0e authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[cpu-profiler] Save space in the SourcePositionTable by using a vector.

This map is often quite small and holds small items (ints) so wastes
quite a bit of overhead in the backing tree representation.

This CL changes the std::map to a sorted vector of pairs. This reduces
the size significantly (2.13 MiB -> 598 KiB on the node server example).

Bug: v8:7719
Change-Id: Ic829693f007732ae145fae02850a1ed913cd941e
Reviewed-on: https://chromium-review.googlesource.com/1064233
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarAlexei Filippov <alph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53278}
parent 3fb356bb
......@@ -21,23 +21,25 @@ namespace internal {
void SourcePositionTable::SetPosition(int pc_offset, int line) {
DCHECK_GE(pc_offset, 0);
DCHECK_GT(line, 0); // The 1-based number of the source line.
if (GetSourceLineNumber(pc_offset) != line) {
auto result = pc_offset_to_line_map_.emplace(pc_offset, line);
// Check that a new element was inserted.
USE(result);
DCHECK(result.second);
// Check that we are inserting in ascending order, so that the vector remains
// sorted.
DCHECK(pc_offsets_to_lines_.empty() ||
pc_offsets_to_lines_.back().pc_offset < pc_offset);
if (pc_offsets_to_lines_.empty() ||
pc_offsets_to_lines_.back().line_number != line) {
pc_offsets_to_lines_.push_back({pc_offset, line});
}
}
int SourcePositionTable::GetSourceLineNumber(int pc_offset) const {
if (pc_offset_to_line_map_.empty()) {
if (pc_offsets_to_lines_.empty()) {
return v8::CpuProfileNode::kNoLineNumberInfo;
}
auto it = pc_offset_to_line_map_.upper_bound(pc_offset);
if (it != pc_offset_to_line_map_.begin()) {
return (--it)->second;
}
return it->second;
auto it =
std::upper_bound(pc_offsets_to_lines_.begin(), pc_offsets_to_lines_.end(),
PCOffsetAndLineNumber{pc_offset, 0});
if (it != pc_offsets_to_lines_.begin()) --it;
return it->line_number;
}
const char* const CodeEntry::kEmptyResourceName = "";
......
......@@ -32,7 +32,17 @@ class SourcePositionTable : public Malloced {
int GetSourceLineNumber(int pc_offset) const;
private:
std::map<int, int> pc_offset_to_line_map_;
struct PCOffsetAndLineNumber {
bool operator<(const PCOffsetAndLineNumber& other) const {
return pc_offset < other.pc_offset;
}
int pc_offset;
int line_number;
};
// This is logically a map, but we store it as a vector of pairs, sorted by
// the pc offset, so that we can save space and look up items using binary
// search.
std::vector<PCOffsetAndLineNumber> pc_offsets_to_lines_;
DISALLOW_COPY_AND_ASSIGN(SourcePositionTable);
};
......
......@@ -2424,49 +2424,43 @@ TEST(NativeFrameStackTrace) {
}
TEST(SourcePositionTable) {
std::unique_ptr<i::SourcePositionTable> info(new SourcePositionTable());
i::SourcePositionTable info;
// Newly created tables should return NoLineNumberInfo for any lookup.
int no_info = v8::CpuProfileNode::kNoLineNumberInfo;
CHECK_EQ(no_info, info->GetSourceLineNumber(std::numeric_limits<int>::min()));
CHECK_EQ(no_info, info->GetSourceLineNumber(0));
CHECK_EQ(no_info, info->GetSourceLineNumber(1));
CHECK_EQ(no_info, info->GetSourceLineNumber(9));
CHECK_EQ(no_info, info->GetSourceLineNumber(10));
CHECK_EQ(no_info, info->GetSourceLineNumber(11));
CHECK_EQ(no_info, info->GetSourceLineNumber(19));
CHECK_EQ(no_info, info->GetSourceLineNumber(20));
CHECK_EQ(no_info, info->GetSourceLineNumber(21));
CHECK_EQ(no_info, info->GetSourceLineNumber(100));
CHECK_EQ(no_info, info->GetSourceLineNumber(std::numeric_limits<int>::max()));
info->SetPosition(10, 1);
info->SetPosition(20, 2);
CHECK_EQ(no_info, info.GetSourceLineNumber(std::numeric_limits<int>::min()));
CHECK_EQ(no_info, info.GetSourceLineNumber(0));
CHECK_EQ(no_info, info.GetSourceLineNumber(1));
CHECK_EQ(no_info, info.GetSourceLineNumber(9));
CHECK_EQ(no_info, info.GetSourceLineNumber(10));
CHECK_EQ(no_info, info.GetSourceLineNumber(11));
CHECK_EQ(no_info, info.GetSourceLineNumber(19));
CHECK_EQ(no_info, info.GetSourceLineNumber(20));
CHECK_EQ(no_info, info.GetSourceLineNumber(21));
CHECK_EQ(no_info, info.GetSourceLineNumber(100));
CHECK_EQ(no_info, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
info.SetPosition(10, 1);
info.SetPosition(20, 2);
// The only valid return values are 1 or 2 - every pc maps to a line number.
CHECK_EQ(1, info->GetSourceLineNumber(std::numeric_limits<int>::min()));
CHECK_EQ(1, info->GetSourceLineNumber(0));
CHECK_EQ(1, info->GetSourceLineNumber(1));
CHECK_EQ(1, info->GetSourceLineNumber(9));
CHECK_EQ(1, info->GetSourceLineNumber(10));
CHECK_EQ(1, info->GetSourceLineNumber(11));
CHECK_EQ(1, info->GetSourceLineNumber(19));
CHECK_EQ(2, info->GetSourceLineNumber(20));
CHECK_EQ(2, info->GetSourceLineNumber(21));
CHECK_EQ(2, info->GetSourceLineNumber(100));
CHECK_EQ(2, info->GetSourceLineNumber(std::numeric_limits<int>::max()));
CHECK_EQ(1, info.GetSourceLineNumber(std::numeric_limits<int>::min()));
CHECK_EQ(1, info.GetSourceLineNumber(0));
CHECK_EQ(1, info.GetSourceLineNumber(1));
CHECK_EQ(1, info.GetSourceLineNumber(9));
CHECK_EQ(1, info.GetSourceLineNumber(10));
CHECK_EQ(1, info.GetSourceLineNumber(11));
CHECK_EQ(1, info.GetSourceLineNumber(19));
CHECK_EQ(2, info.GetSourceLineNumber(20));
CHECK_EQ(2, info.GetSourceLineNumber(21));
CHECK_EQ(2, info.GetSourceLineNumber(100));
CHECK_EQ(2, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
// Test SetPosition behavior.
// Setting a position to the same value has no effect.
info->SetPosition(10, 1);
CHECK_EQ(1, info->GetSourceLineNumber(9));
CHECK_EQ(1, info->GetSourceLineNumber(10));
CHECK_EQ(1, info->GetSourceLineNumber(11));
info->SetPosition(25, 3);
CHECK_EQ(2, info->GetSourceLineNumber(21));
CHECK_EQ(3, info->GetSourceLineNumber(100));
CHECK_EQ(3, info->GetSourceLineNumber(std::numeric_limits<int>::max()));
info.SetPosition(25, 3);
CHECK_EQ(2, info.GetSourceLineNumber(21));
CHECK_EQ(3, info.GetSourceLineNumber(100));
CHECK_EQ(3, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
}
TEST(MultipleProfilers) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment