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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 Script* script = Script::cast(shared->script()); | 189 Script* script = Script::cast(shared->script()); |
190 script_id = script->id(); | 190 script_id = script->id(); |
191 } | 191 } |
192 node = FindOrAddChildNode(node, name, script_id, shared->start_position()); | 192 node = FindOrAddChildNode(node, name, script_id, shared->start_position()); |
193 } | 193 } |
194 return node; | 194 return node; |
195 } | 195 } |
196 | 196 |
197 v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode( | 197 v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode( |
198 AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node, | 198 AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node, |
199 const std::map<int, Script*>& scripts) { | 199 const std::map<int, Handle<Script>>& scripts) { |
200 Local<v8::String> script_name = | 200 Local<v8::String> script_name = |
201 ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String("")); | 201 ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String("")); |
202 int line = v8::AllocationProfile::kNoLineNumberInfo; | 202 int line = v8::AllocationProfile::kNoLineNumberInfo; |
203 int column = v8::AllocationProfile::kNoColumnNumberInfo; | 203 int column = v8::AllocationProfile::kNoColumnNumberInfo; |
204 std::vector<v8::AllocationProfile::Allocation> allocations; | 204 std::vector<v8::AllocationProfile::Allocation> allocations; |
205 allocations.reserve(node->allocations_.size()); | 205 allocations.reserve(node->allocations_.size()); |
206 if (node->script_id_ != v8::UnboundScript::kNoScriptId && | 206 if (node->script_id_ != v8::UnboundScript::kNoScriptId && |
207 scripts.find(node->script_id_) != scripts.end()) { | 207 scripts.find(node->script_id_) != scripts.end()) { |
208 // Cannot use std::map<T>::at because it is not available on android. | 208 // Cannot use std::map<T>::at because it is not available on android. |
209 auto non_const_scripts = const_cast<std::map<int, Script*>&>(scripts); | 209 auto non_const_scripts = |
210 Script* script = non_const_scripts[node->script_id_]; | 210 const_cast<std::map<int, Handle<Script>>&>(scripts); |
211 if (script) { | 211 Handle<Script> script = non_const_scripts[node->script_id_]; |
| 212 if (!script.is_null()) { |
212 if (script->name()->IsName()) { | 213 if (script->name()->IsName()) { |
213 Name* name = Name::cast(script->name()); | 214 Name* name = Name::cast(script->name()); |
214 script_name = ToApiHandle<v8::String>( | 215 script_name = ToApiHandle<v8::String>( |
215 isolate_->factory()->InternalizeUtf8String(names_->GetName(name))); | 216 isolate_->factory()->InternalizeUtf8String(names_->GetName(name))); |
216 } | 217 } |
217 Handle<Script> script_handle(script); | 218 line = 1 + Script::GetLineNumber(script, node->script_position_); |
218 line = 1 + Script::GetLineNumber(script_handle, node->script_position_); | 219 column = 1 + Script::GetColumnNumber(script, node->script_position_); |
219 column = | |
220 1 + Script::GetColumnNumber(script_handle, node->script_position_); | |
221 } | 220 } |
222 for (auto alloc : node->allocations_) { | 221 for (auto alloc : node->allocations_) { |
223 allocations.push_back(ScaleSample(alloc.first, alloc.second)); | 222 allocations.push_back(ScaleSample(alloc.first, alloc.second)); |
224 } | 223 } |
225 } | 224 } |
226 | 225 |
227 profile->nodes().push_back(v8::AllocationProfile::Node( | 226 profile->nodes().push_back(v8::AllocationProfile::Node( |
228 {ToApiHandle<v8::String>( | 227 {ToApiHandle<v8::String>( |
229 isolate_->factory()->InternalizeUtf8String(node->name_)), | 228 isolate_->factory()->InternalizeUtf8String(node->name_)), |
230 script_name, node->script_id_, node->script_position_, line, column, | 229 script_name, node->script_id_, node->script_position_, line, column, |
231 std::vector<v8::AllocationProfile::Node*>(), allocations})); | 230 std::vector<v8::AllocationProfile::Node*>(), allocations})); |
232 v8::AllocationProfile::Node* current = &profile->nodes().back(); | 231 v8::AllocationProfile::Node* current = &profile->nodes().back(); |
233 size_t child_len = node->children_.size(); | 232 size_t child_len = node->children_.size(); |
234 // The children vector may have nodes appended to it during translation | 233 // The children vector may have nodes appended to it during translation |
235 // because the translation may allocate strings on the JS heap that have | 234 // because the translation may allocate strings on the JS heap that have |
236 // the potential to be sampled. We cache the length of the vector before | 235 // the potential to be sampled. We cache the length of the vector before |
237 // iteration so that nodes appended to the vector during iteration are | 236 // iteration so that nodes appended to the vector during iteration are |
238 // not processed. | 237 // not processed. |
239 for (size_t i = 0; i < child_len; i++) { | 238 for (size_t i = 0; i < child_len; i++) { |
240 current->children.push_back( | 239 current->children.push_back( |
241 TranslateAllocationNode(profile, node->children_[i], scripts)); | 240 TranslateAllocationNode(profile, node->children_[i], scripts)); |
242 } | 241 } |
243 return current; | 242 return current; |
244 } | 243 } |
245 | 244 |
246 v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() { | 245 v8::AllocationProfile* SamplingHeapProfiler::GetAllocationProfile() { |
247 // To resolve positions to line/column numbers, we will need to look up | 246 // To resolve positions to line/column numbers, we will need to look up |
248 // scripts. Build a map to allow fast mapping from script id to script. | 247 // scripts. Build a map to allow fast mapping from script id to script. |
249 std::map<int, Script*> scripts; | 248 std::map<int, Handle<Script>> scripts; |
250 { | 249 { |
251 Script::Iterator iterator(isolate_); | 250 Script::Iterator iterator(isolate_); |
252 Script* script; | 251 while (Script* script = iterator.Next()) { |
253 while ((script = iterator.Next())) { | 252 scripts[script->id()] = handle(script); |
254 scripts[script->id()] = script; | |
255 } | 253 } |
256 } | 254 } |
257 | |
258 auto profile = new v8::internal::AllocationProfile(); | 255 auto profile = new v8::internal::AllocationProfile(); |
259 | |
260 TranslateAllocationNode(profile, &profile_root_, scripts); | 256 TranslateAllocationNode(profile, &profile_root_, scripts); |
261 | |
262 return profile; | 257 return profile; |
263 } | 258 } |
264 | 259 |
265 | 260 |
266 } // namespace internal | 261 } // namespace internal |
267 } // namespace v8 | 262 } // namespace v8 |
OLD | NEW |