Index: src/profiler/sampling-heap-profiler.cc |
diff --git a/src/profiler/sampling-heap-profiler.cc b/src/profiler/sampling-heap-profiler.cc |
index 942562dca18c16d0f6322497664a163b6c1f2b3b..337a9af90a802ddbe7f4449e67147894f9600157 100644 |
--- a/src/profiler/sampling-heap-profiler.cc |
+++ b/src/profiler/sampling-heap-profiler.cc |
@@ -58,7 +58,7 @@ SamplingHeapProfiler::SamplingHeapProfiler(Heap* heap, StringsStorage* names, |
heap_, static_cast<intptr_t>(rate), rate, this, |
heap->isolate()->random_number_generator())), |
names_(names), |
- profile_root_("(root)", v8::UnboundScript::kNoScriptId, 0), |
+ profile_root_(NULL, "(root)", v8::UnboundScript::kNoScriptId, 0), |
ulan
2016/04/28 09:11:57
nullptr
alph
2016/04/28 22:14:39
Thanks. Fixed other places as well.
|
samples_(), |
stack_depth_(stack_depth), |
rate_(rate) { |
@@ -119,6 +119,14 @@ void SamplingHeapProfiler::OnWeakCallback( |
node->allocations_[sample->size]--; |
if (node->allocations_[sample->size] == 0) { |
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); |
delete sample; |
@@ -134,7 +142,8 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::FindOrAddChildNode( |
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); |
return child; |
} |
@@ -197,6 +206,9 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() { |
v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode( |
AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node, |
const std::map<int, 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 = |
ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String("")); |
int line = v8::AllocationProfile::kNoLineNumberInfo; |
@@ -240,6 +252,7 @@ v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode( |
current->children.push_back( |
TranslateAllocationNode(profile, node->children_[i], scripts)); |
} |
+ node->pinned_ = false; |
return current; |
} |