Commit a4fa471a authored by alph's avatar alph Committed by Commit bot

Sampling heap profiler: remove empty nodes from profile.

Review-Url: https://codereview.chromium.org/1919223003
Cr-Commit-Position: refs/heads/master@{#35884}
parent 7961e2e9
...@@ -58,14 +58,14 @@ SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names, ...@@ -58,14 +58,14 @@ SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names,
heap_, static_cast<intptr_t>(rate), rate, this, heap_, static_cast<intptr_t>(rate), rate, this,
heap->isolate()->random_number_generator())), heap->isolate()->random_number_generator())),
names_(names), names_(names),
profile_root_("(root)", v8::UnboundScript::kNoScriptId, 0), profile_root_(nullptr, "(root)", v8::UnboundScript::kNoScriptId, 0),
samples_(), samples_(),
stack_depth_(stack_depth), stack_depth_(stack_depth),
rate_(rate) { rate_(rate) {
CHECK_GT(rate_, 0); CHECK_GT(rate_, 0);
heap->new_space()->AddAllocationObserver(new_space_observer_.get()); heap->new_space()->AddAllocationObserver(new_space_observer_.get());
AllSpaces spaces(heap); AllSpaces spaces(heap);
for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { for (Space* space = spaces.next(); space != nullptr; space = spaces.next()) {
if (space != heap->new_space()) { if (space != heap->new_space()) {
space->AddAllocationObserver(other_spaces_observer_.get()); space->AddAllocationObserver(other_spaces_observer_.get());
} }
...@@ -76,7 +76,7 @@ SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names, ...@@ -76,7 +76,7 @@ SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names,
SamplingHeapProfiler::~SamplingHeapProfiler() { SamplingHeapProfiler::~SamplingHeapProfiler() {
heap_->new_space()->RemoveAllocationObserver(new_space_observer_.get()); heap_->new_space()->RemoveAllocationObserver(new_space_observer_.get());
AllSpaces spaces(heap_); AllSpaces spaces(heap_);
for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { for (Space* space = spaces.next(); space != nullptr; space = spaces.next()) {
if (space != heap_->new_space()) { if (space != heap_->new_space()) {
space->RemoveAllocationObserver(other_spaces_observer_.get()); space->RemoveAllocationObserver(other_spaces_observer_.get());
} }
...@@ -119,6 +119,14 @@ void SamplingHeapProfiler::OnWeakCallback( ...@@ -119,6 +119,14 @@ void SamplingHeapProfiler::OnWeakCallback(
node->allocations_[sample->size]--; node->allocations_[sample->size]--;
if (node->allocations_[sample->size] == 0) { if (node->allocations_[sample->size] == 0) {
node->allocations_.erase(sample->size); node->allocations_.erase(sample->size);
while (node->allocations_.empty() && node->children_.empty() &&
node->parent_ && !node->parent_->pinned_) {
AllocationNode* parent = node->parent_;
parent->children_.erase(
std::find(parent->children_.begin(), parent->children_.end(), node));
delete node;
node = parent;
}
} }
sample->profiler->samples_.erase(sample); sample->profiler->samples_.erase(sample);
delete sample; delete sample;
...@@ -134,7 +142,8 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::FindOrAddChildNode( ...@@ -134,7 +142,8 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::FindOrAddChildNode(
return child; return child;
} }
} }
AllocationNode* child = new AllocationNode(name, script_id, start_position); AllocationNode* child =
new AllocationNode(parent, name, script_id, start_position);
parent->children_.push_back(child); parent->children_.push_back(child);
return child; return child;
} }
...@@ -197,6 +206,9 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() { ...@@ -197,6 +206,9 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() {
v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode( v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode(
AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node, AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node,
const std::map<int, Handle<Script>>& scripts) { const std::map<int, Handle<Script>>& scripts) {
// By pinning the node we make sure its children won't get disposed if
// a GC kicks in during the tree retrieval.
node->pinned_ = true;
Local<v8::String> script_name = Local<v8::String> script_name =
ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String("")); ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String(""));
int line = v8::AllocationProfile::kNoLineNumberInfo; int line = v8::AllocationProfile::kNoLineNumberInfo;
...@@ -239,6 +251,7 @@ v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode( ...@@ -239,6 +251,7 @@ v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode(
current->children.push_back( current->children.push_back(
TranslateAllocationNode(profile, node->children_[i], scripts)); TranslateAllocationNode(profile, node->children_[i], scripts));
} }
node->pinned_ = false;
return current; return current;
} }
......
...@@ -71,11 +71,13 @@ class SamplingHeapProfiler { ...@@ -71,11 +71,13 @@ class SamplingHeapProfiler {
class AllocationNode { class AllocationNode {
public: public:
AllocationNode(const char* const name, int script_id, AllocationNode(AllocationNode* parent, const char* name, int script_id,
const int start_position) int start_position)
: script_id_(script_id), : parent_(parent),
script_id_(script_id),
script_position_(start_position), script_position_(start_position),
name_(name) {} name_(name),
pinned_(false) {}
~AllocationNode() { ~AllocationNode() {
for (auto child : children_) { for (auto child : children_) {
delete child; delete child;
...@@ -85,9 +87,11 @@ class SamplingHeapProfiler { ...@@ -85,9 +87,11 @@ class SamplingHeapProfiler {
private: private:
std::map<size_t, unsigned int> allocations_; std::map<size_t, unsigned int> allocations_;
std::vector<AllocationNode*> children_; std::vector<AllocationNode*> children_;
AllocationNode* const parent_;
const int script_id_; const int script_id_;
const int script_position_; const int script_position_;
const char* const name_; const char* const name_;
bool pinned_;
friend class SamplingHeapProfiler; friend class SamplingHeapProfiler;
......
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