Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(375)

Side by Side Diff: src/profiler/sampling-heap-profiler.cc

Issue 1919223003: Sampling heap profiler: remove empty nodes from profile. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressing comment Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/profiler/sampling-heap-profiler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/profiler/sampling-heap-profiler.h" 5 #include "src/profiler/sampling-heap-profiler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <memory> 8 #include <memory>
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/utils/random-number-generator.h" 10 #include "src/base/utils/random-number-generator.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 uint64_t rate, int stack_depth) 51 uint64_t rate, int stack_depth)
52 : isolate_(heap->isolate()), 52 : isolate_(heap->isolate()),
53 heap_(heap), 53 heap_(heap),
54 new_space_observer_(new SamplingAllocationObserver( 54 new_space_observer_(new SamplingAllocationObserver(
55 heap_, static_cast<intptr_t>(rate), rate, this, 55 heap_, static_cast<intptr_t>(rate), rate, this,
56 heap->isolate()->random_number_generator())), 56 heap->isolate()->random_number_generator())),
57 other_spaces_observer_(new SamplingAllocationObserver( 57 other_spaces_observer_(new SamplingAllocationObserver(
58 heap_, static_cast<intptr_t>(rate), rate, this, 58 heap_, static_cast<intptr_t>(rate), rate, this,
59 heap->isolate()->random_number_generator())), 59 heap->isolate()->random_number_generator())),
60 names_(names), 60 names_(names),
61 profile_root_("(root)", v8::UnboundScript::kNoScriptId, 0), 61 profile_root_(nullptr, "(root)", v8::UnboundScript::kNoScriptId, 0),
62 samples_(), 62 samples_(),
63 stack_depth_(stack_depth), 63 stack_depth_(stack_depth),
64 rate_(rate) { 64 rate_(rate) {
65 CHECK_GT(rate_, 0); 65 CHECK_GT(rate_, 0);
66 heap->new_space()->AddAllocationObserver(new_space_observer_.get()); 66 heap->new_space()->AddAllocationObserver(new_space_observer_.get());
67 AllSpaces spaces(heap); 67 AllSpaces spaces(heap);
68 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 68 for (Space* space = spaces.next(); space != nullptr; space = spaces.next()) {
69 if (space != heap->new_space()) { 69 if (space != heap->new_space()) {
70 space->AddAllocationObserver(other_spaces_observer_.get()); 70 space->AddAllocationObserver(other_spaces_observer_.get());
71 } 71 }
72 } 72 }
73 } 73 }
74 74
75 75
76 SamplingHeapProfiler::~SamplingHeapProfiler() { 76 SamplingHeapProfiler::~SamplingHeapProfiler() {
77 heap_->new_space()->RemoveAllocationObserver(new_space_observer_.get()); 77 heap_->new_space()->RemoveAllocationObserver(new_space_observer_.get());
78 AllSpaces spaces(heap_); 78 AllSpaces spaces(heap_);
79 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 79 for (Space* space = spaces.next(); space != nullptr; space = spaces.next()) {
80 if (space != heap_->new_space()) { 80 if (space != heap_->new_space()) {
81 space->RemoveAllocationObserver(other_spaces_observer_.get()); 81 space->RemoveAllocationObserver(other_spaces_observer_.get());
82 } 82 }
83 } 83 }
84 84
85 for (auto sample : samples_) { 85 for (auto sample : samples_) {
86 delete sample; 86 delete sample;
87 } 87 }
88 std::set<Sample*> empty; 88 std::set<Sample*> empty;
89 samples_.swap(empty); 89 samples_.swap(empty);
(...skipping 22 matching lines...) Expand all
112 } 112 }
113 113
114 void SamplingHeapProfiler::OnWeakCallback( 114 void SamplingHeapProfiler::OnWeakCallback(
115 const WeakCallbackInfo<Sample>& data) { 115 const WeakCallbackInfo<Sample>& data) {
116 Sample* sample = data.GetParameter(); 116 Sample* sample = data.GetParameter();
117 AllocationNode* node = sample->owner; 117 AllocationNode* node = sample->owner;
118 DCHECK(node->allocations_[sample->size] > 0); 118 DCHECK(node->allocations_[sample->size] > 0);
119 node->allocations_[sample->size]--; 119 node->allocations_[sample->size]--;
120 if (node->allocations_[sample->size] == 0) { 120 if (node->allocations_[sample->size] == 0) {
121 node->allocations_.erase(sample->size); 121 node->allocations_.erase(sample->size);
122 while (node->allocations_.empty() && node->children_.empty() &&
123 node->parent_ && !node->parent_->pinned_) {
124 AllocationNode* parent = node->parent_;
125 parent->children_.erase(
126 std::find(parent->children_.begin(), parent->children_.end(), node));
127 delete node;
128 node = parent;
129 }
122 } 130 }
123 sample->profiler->samples_.erase(sample); 131 sample->profiler->samples_.erase(sample);
124 delete sample; 132 delete sample;
125 } 133 }
126 134
127 SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::FindOrAddChildNode( 135 SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::FindOrAddChildNode(
128 AllocationNode* parent, const char* name, int script_id, 136 AllocationNode* parent, const char* name, int script_id,
129 int start_position) { 137 int start_position) {
130 for (AllocationNode* child : parent->children_) { 138 for (AllocationNode* child : parent->children_) {
131 if (child->script_id_ == script_id && 139 if (child->script_id_ == script_id &&
132 child->script_position_ == start_position && 140 child->script_position_ == start_position &&
133 strcmp(child->name_, name) == 0) { 141 strcmp(child->name_, name) == 0) {
134 return child; 142 return child;
135 } 143 }
136 } 144 }
137 AllocationNode* child = new AllocationNode(name, script_id, start_position); 145 AllocationNode* child =
146 new AllocationNode(parent, name, script_id, start_position);
138 parent->children_.push_back(child); 147 parent->children_.push_back(child);
139 return child; 148 return child;
140 } 149 }
141 150
142 SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() { 151 SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() {
143 AllocationNode* node = &profile_root_; 152 AllocationNode* node = &profile_root_;
144 153
145 std::vector<SharedFunctionInfo*> stack; 154 std::vector<SharedFunctionInfo*> stack;
146 StackTraceFrameIterator it(isolate_); 155 StackTraceFrameIterator it(isolate_);
147 int frames_captured = 0; 156 int frames_captured = 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 script_id = script->id(); 199 script_id = script->id();
191 } 200 }
192 node = FindOrAddChildNode(node, name, script_id, shared->start_position()); 201 node = FindOrAddChildNode(node, name, script_id, shared->start_position());
193 } 202 }
194 return node; 203 return node;
195 } 204 }
196 205
197 v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode( 206 v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode(
198 AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node, 207 AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node,
199 const std::map<int, Handle<Script>>& scripts) { 208 const std::map<int, Handle<Script>>& scripts) {
209 // By pinning the node we make sure its children won't get disposed if
210 // a GC kicks in during the tree retrieval.
211 node->pinned_ = true;
200 Local<v8::String> script_name = 212 Local<v8::String> script_name =
201 ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String("")); 213 ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String(""));
202 int line = v8::AllocationProfile::kNoLineNumberInfo; 214 int line = v8::AllocationProfile::kNoLineNumberInfo;
203 int column = v8::AllocationProfile::kNoColumnNumberInfo; 215 int column = v8::AllocationProfile::kNoColumnNumberInfo;
204 std::vector<v8::AllocationProfile::Allocation> allocations; 216 std::vector<v8::AllocationProfile::Allocation> allocations;
205 allocations.reserve(node->allocations_.size()); 217 allocations.reserve(node->allocations_.size());
206 if (node->script_id_ != v8::UnboundScript::kNoScriptId && 218 if (node->script_id_ != v8::UnboundScript::kNoScriptId &&
207 scripts.find(node->script_id_) != scripts.end()) { 219 scripts.find(node->script_id_) != scripts.end()) {
208 // Cannot use std::map<T>::at because it is not available on android. 220 // Cannot use std::map<T>::at because it is not available on android.
209 auto non_const_scripts = 221 auto non_const_scripts =
(...skipping 22 matching lines...) Expand all
232 size_t child_len = node->children_.size(); 244 size_t child_len = node->children_.size();
233 // The children vector may have nodes appended to it during translation 245 // The children vector may have nodes appended to it during translation
234 // because the translation may allocate strings on the JS heap that have 246 // because the translation may allocate strings on the JS heap that have
235 // the potential to be sampled. We cache the length of the vector before 247 // the potential to be sampled. We cache the length of the vector before
236 // iteration so that nodes appended to the vector during iteration are 248 // iteration so that nodes appended to the vector during iteration are
237 // not processed. 249 // not processed.
238 for (size_t i = 0; i < child_len; i++) { 250 for (size_t i = 0; i < child_len; i++) {
239 current->children.push_back( 251 current->children.push_back(
240 TranslateAllocationNode(profile, node->children_[i], scripts)); 252 TranslateAllocationNode(profile, node->children_[i], scripts));
241 } 253 }
254 node->pinned_ = false;
242 return current; 255 return current;
243 } 256 }
244 257
245 v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() { 258 v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() {
246 // To resolve positions to line/column numbers, we will need to look up 259 // To resolve positions to line/column numbers, we will need to look up
247 // scripts. Build a map to allow fast mapping from script id to script. 260 // scripts. Build a map to allow fast mapping from script id to script.
248 std::map<int, Handle<Script>> scripts; 261 std::map<int, Handle<Script>> scripts;
249 { 262 {
250 Script::Iterator iterator(isolate_); 263 Script::Iterator iterator(isolate_);
251 while (Script* script = iterator.Next()) { 264 while (Script* script = iterator.Next()) {
252 scripts[script->id()] = handle(script); 265 scripts[script->id()] = handle(script);
253 } 266 }
254 } 267 }
255 auto profile = new v8::internal::AllocationProfile(); 268 auto profile = new v8::internal::AllocationProfile();
256 TranslateAllocationNode(profile, &profile_root_, scripts); 269 TranslateAllocationNode(profile, &profile_root_, scripts);
257 return profile; 270 return profile;
258 } 271 }
259 272
260 273
261 } // namespace internal 274 } // namespace internal
262 } // namespace v8 275 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/sampling-heap-profiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698