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

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

Issue 1929813002: Sampling heap profiler: Fix potential crash on accessing scripts. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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