OLD | NEW |
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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 allocations.push_back(ScaleSample(alloc.first, alloc.second)); | 216 allocations.push_back(ScaleSample(alloc.first, alloc.second)); |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 profile->nodes().push_back(v8::AllocationProfile::Node( | 220 profile->nodes().push_back(v8::AllocationProfile::Node( |
221 {ToApiHandle<v8::String>( | 221 {ToApiHandle<v8::String>( |
222 isolate_->factory()->InternalizeUtf8String(node->name_)), | 222 isolate_->factory()->InternalizeUtf8String(node->name_)), |
223 script_name, node->script_id_, node->script_position_, line, column, | 223 script_name, node->script_id_, node->script_position_, line, column, |
224 std::vector<v8::AllocationProfile::Node*>(), allocations})); | 224 std::vector<v8::AllocationProfile::Node*>(), allocations})); |
225 v8::AllocationProfile::Node* current = &profile->nodes().back(); | 225 v8::AllocationProfile::Node* current = &profile->nodes().back(); |
226 for (auto child : node->children_) { | 226 size_t child_len = node->children_.size(); |
| 227 // The children vector may have nodes appended to it during translation |
| 228 // because the translation may allocate strings on the JS heap that have |
| 229 // the potential to be sampled. We cache the length of the vector before |
| 230 // iteration so that nodes appended to the vector during iteration are |
| 231 // not processed. |
| 232 for (size_t i = 0; i < child_len; i++) { |
227 current->children.push_back( | 233 current->children.push_back( |
228 TranslateAllocationNode(profile, child, scripts)); | 234 TranslateAllocationNode(profile, node->children_[i], scripts)); |
229 } | 235 } |
230 return current; | 236 return current; |
231 } | 237 } |
232 | 238 |
233 v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() { | 239 v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() { |
234 // To resolve positions to line/column numbers, we will need to look up | 240 // To resolve positions to line/column numbers, we will need to look up |
235 // scripts. Build a map to allow fast mapping from script id to script. | 241 // scripts. Build a map to allow fast mapping from script id to script. |
236 std::map<int, Script*> scripts; | 242 std::map<int, Script*> scripts; |
237 { | 243 { |
238 Script::Iterator iterator(isolate_); | 244 Script::Iterator iterator(isolate_); |
239 Script* script; | 245 Script* script; |
240 while ((script = iterator.Next())) { | 246 while ((script = iterator.Next())) { |
241 scripts[script->id()] = script; | 247 scripts[script->id()] = script; |
242 } | 248 } |
243 } | 249 } |
244 | 250 |
245 auto profile = new v8::internal::AllocationProfile(); | 251 auto profile = new v8::internal::AllocationProfile(); |
246 | 252 |
247 TranslateAllocationNode(profile, &profile_root_, scripts); | 253 TranslateAllocationNode(profile, &profile_root_, scripts); |
248 | 254 |
249 return profile; | 255 return profile; |
250 } | 256 } |
251 | 257 |
252 | 258 |
253 } // namespace internal | 259 } // namespace internal |
254 } // namespace v8 | 260 } // namespace v8 |
OLD | NEW |