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

Side by Side Diff: src/profiler/cpu-profiler.cc

Issue 2053523003: Refactor CpuProfiler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Move CpuProfilerManager to .cc Created 4 years, 6 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/cpu-profiler.h ('k') | src/profiler/profile-generator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/cpu-profiler.h" 5 #include "src/profiler/cpu-profiler.h"
6 6
7 #include "src/debug/debug.h" 7 #include "src/debug/debug.h"
8 #include "src/deoptimizer.h" 8 #include "src/deoptimizer.h"
9 #include "src/frames-inl.h" 9 #include "src/frames-inl.h"
10 #include "src/locked-queue-inl.h" 10 #include "src/locked-queue-inl.h"
11 #include "src/log-inl.h" 11 #include "src/log-inl.h"
12 #include "src/profiler/cpu-profiler-inl.h" 12 #include "src/profiler/cpu-profiler-inl.h"
13 #include "src/profiler/profiler-listener.h"
13 #include "src/vm-state-inl.h" 14 #include "src/vm-state-inl.h"
14 15
15 #include "include/v8-profiler.h" 16 #include "include/v8-profiler.h"
16 17
17 namespace v8 { 18 namespace v8 {
18 namespace internal { 19 namespace internal {
19 20
21 namespace {
22
23 class CpuProfilerManager {
24 public:
25 CpuProfilerManager() : registered_(false) {}
26
27 static CpuProfilerManager* instance() { return instance_.Pointer(); }
28 static void DispatchCodeEvents(const CodeEventsContainer& evt_rec) {
alph 2016/06/10 22:00:24 Hmm, not sure how is supposed to work? The class i
29 CpuProfilerManager* instance = CpuProfilerManager::instance();
30 for (int i = 0, length = instance->cpu_profilers_.length(); i < length;
31 ++i) {
32 instance->cpu_profilers_.at(i)->CodeEventHandler(evt_rec);
33 }
34 }
35 void RegisterCpuProfiler(CpuProfiler* cpu_profiler) {
36 if (cpu_profilers_.Contains(cpu_profiler)) return;
37 cpu_profilers_.Add(cpu_profiler);
38 if (registered_) return;
39 ProfilerListener* profiler_listener =
40 cpu_profiler->isolate()->logger()->profiler_listener();
41 if (!profiler_listener) return;
42 profiler_listener->RegisterCodeEventHandler(&DispatchCodeEvents);
43 registered_ = true;
44 }
45
46 void RemoveCpuProfiler(CpuProfiler* cpu_profiler) {
47 cpu_profilers_.RemoveElement(cpu_profiler);
48 }
49
50 private:
51 static base::LazyDynamicInstance<CpuProfilerManager>::type instance_;
52 List<CpuProfiler*> cpu_profilers_;
53 bool registered_;
54
55 DISALLOW_COPY_AND_ASSIGN(CpuProfilerManager);
56 };
57
58 base::LazyDynamicInstance<CpuProfilerManager>::type
59 CpuProfilerManager::instance_ = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
60
61 } // namespace
62
20 static const int kProfilerStackSize = 64 * KB; 63 static const int kProfilerStackSize = 64 * KB;
21 64
22 65
23 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator, 66 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator,
24 sampler::Sampler* sampler, 67 sampler::Sampler* sampler,
25 base::TimeDelta period) 68 base::TimeDelta period)
26 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), 69 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)),
27 generator_(generator), 70 generator_(generator),
28 sampler_(sampler), 71 sampler_(sampler),
29 running_(1), 72 running_(1),
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 void* ProfilerEventsProcessor::operator new(size_t size) { 209 void* ProfilerEventsProcessor::operator new(size_t size) {
167 return AlignedAlloc(size, V8_ALIGNOF(ProfilerEventsProcessor)); 210 return AlignedAlloc(size, V8_ALIGNOF(ProfilerEventsProcessor));
168 } 211 }
169 212
170 213
171 void ProfilerEventsProcessor::operator delete(void* ptr) { 214 void ProfilerEventsProcessor::operator delete(void* ptr) {
172 AlignedFree(ptr); 215 AlignedFree(ptr);
173 } 216 }
174 217
175 218
219
176 int CpuProfiler::GetProfilesCount() { 220 int CpuProfiler::GetProfilesCount() {
177 // The count of profiles doesn't depend on a security token. 221 // The count of profiles doesn't depend on a security token.
178 return profiles_->profiles()->length(); 222 return profiles_->profiles()->length();
179 } 223 }
180 224
181 225
182 CpuProfile* CpuProfiler::GetProfile(int index) { 226 CpuProfile* CpuProfiler::GetProfile(int index) {
183 return profiles_->profiles()->at(index); 227 return profiles_->profiles()->at(index);
184 } 228 }
185 229
186 230
187 void CpuProfiler::DeleteAllProfiles() { 231 void CpuProfiler::DeleteAllProfiles() {
188 if (is_profiling_) StopProcessor(); 232 if (is_profiling_) StopProcessor();
189 ResetProfiles(); 233 ResetProfiles();
190 } 234 }
191 235
192 236
193 void CpuProfiler::DeleteProfile(CpuProfile* profile) { 237 void CpuProfiler::DeleteProfile(CpuProfile* profile) {
194 profiles_->RemoveProfile(profile); 238 profiles_->RemoveProfile(profile);
195 delete profile; 239 delete profile;
196 if (profiles_->profiles()->is_empty() && !is_profiling_) { 240 if (profiles_->profiles()->is_empty() && !is_profiling_) {
197 // If this was the last profile, clean up all accessory data as well. 241 // If this was the last profile, clean up all accessory data as well.
198 ResetProfiles(); 242 ResetProfiles();
199 } 243 }
200 } 244 }
201 245
202 246 void CpuProfiler::CodeEventHandler(const CodeEventsContainer& evt_rec) {
203 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { 247 if (!is_profiling_ && !is_testing_) return;
204 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); 248 switch (evt_rec.generic.type) {
205 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 249 case CodeEventRecord::CODE_CREATION:
206 rec->start = entry_point; 250 case CodeEventRecord::CODE_MOVE:
207 rec->entry = profiles_->NewCodeEntry( 251 case CodeEventRecord::CODE_DISABLE_OPT: {
208 Logger::CALLBACK_TAG, 252 processor_->Enqueue(evt_rec);
209 profiles_->GetName(name)); 253 break;
210 rec->size = 1;
211 processor_->Enqueue(evt_rec);
212 }
213
214 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
215 AbstractCode* code, const char* name) {
216 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
217 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
218 rec->start = code->address();
219 rec->entry = profiles_->NewCodeEntry(
220 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
221 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
222 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
223 RecordInliningInfo(rec->entry, code);
224 rec->size = code->ExecutableSize();
225 processor_->Enqueue(evt_rec);
226 }
227
228 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
229 AbstractCode* code, Name* name) {
230 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
231 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
232 rec->start = code->address();
233 rec->entry = profiles_->NewCodeEntry(
234 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
235 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
236 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
237 RecordInliningInfo(rec->entry, code);
238 rec->size = code->ExecutableSize();
239 processor_->Enqueue(evt_rec);
240 }
241
242 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
243 AbstractCode* code,
244 SharedFunctionInfo* shared,
245 Name* script_name) {
246 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
247 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
248 rec->start = code->address();
249 rec->entry = profiles_->NewCodeEntry(
250 tag, profiles_->GetFunctionName(shared->DebugName()),
251 CodeEntry::kEmptyNamePrefix,
252 profiles_->GetName(InferScriptName(script_name, shared)),
253 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
254 NULL, code->instruction_start());
255 RecordInliningInfo(rec->entry, code);
256 rec->entry->FillFunctionInfo(shared);
257 rec->size = code->ExecutableSize();
258 processor_->Enqueue(evt_rec);
259 }
260
261 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
262 AbstractCode* abstract_code,
263 SharedFunctionInfo* shared, Name* script_name,
264 int line, int column) {
265 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
266 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
267 rec->start = abstract_code->address();
268 Script* script = Script::cast(shared->script());
269 JITLineInfoTable* line_table = NULL;
270 if (script) {
271 if (abstract_code->IsCode()) {
272 Code* code = abstract_code->GetCode();
273 int start_position = shared->start_position();
274 int end_position = shared->end_position();
275 line_table = new JITLineInfoTable();
276 for (RelocIterator it(code); !it.done(); it.next()) {
277 RelocInfo* reloc_info = it.rinfo();
278 if (!RelocInfo::IsPosition(reloc_info->rmode())) continue;
279 int position = static_cast<int>(reloc_info->data());
280 // TODO(alph): in case of inlining the position may correspond
281 // to an inlined function source code. Do not collect positions
282 // that fall beyond the function source code. There's however a
283 // chance the inlined function has similar positions but in another
284 // script. So the proper fix is to store script_id in some form
285 // along with the inlined function positions.
286 if (position < start_position || position >= end_position) continue;
287 int pc_offset = static_cast<int>(reloc_info->pc() - code->address());
288 int line_number = script->GetLineNumber(position) + 1;
289 line_table->SetPosition(pc_offset, line_number);
290 }
291 } else {
292 BytecodeArray* bytecode = abstract_code->GetBytecodeArray();
293 line_table = new JITLineInfoTable();
294 interpreter::SourcePositionTableIterator it(
295 bytecode->source_position_table());
296 for (; !it.done(); it.Advance()) {
297 int line_number = script->GetLineNumber(it.source_position()) + 1;
298 int pc_offset = it.bytecode_offset() + BytecodeArray::kHeaderSize;
299 line_table->SetPosition(pc_offset, line_number);
300 }
301 } 254 }
302 } 255 case CodeEventRecord::CODE_DEOPT: {
303 rec->entry = profiles_->NewCodeEntry( 256 processor_->Enqueue(evt_rec);
304 tag, profiles_->GetFunctionName(shared->DebugName()), 257 CodeDeoptEventRecord* rec =
305 CodeEntry::kEmptyNamePrefix, 258 const_cast<CodeDeoptEventRecord*>(&evt_rec.CodeDeoptEventRecord_);
306 profiles_->GetName(InferScriptName(script_name, shared)), line, column, 259 processor_->AddDeoptStack(isolate_, reinterpret_cast<Address>(rec->pc),
307 line_table, abstract_code->instruction_start()); 260 rec->fp_to_sp_delta);
308 RecordInliningInfo(rec->entry, abstract_code); 261 break;
309 RecordDeoptInlinedFrames(rec->entry, abstract_code);
310 rec->entry->FillFunctionInfo(shared);
311 rec->size = abstract_code->ExecutableSize();
312 processor_->Enqueue(evt_rec);
313 }
314
315 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
316 AbstractCode* code, int args_count) {
317 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
318 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
319 rec->start = code->address();
320 rec->entry = profiles_->NewCodeEntry(
321 tag, profiles_->GetName(args_count), "args_count: ",
322 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
323 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
324 RecordInliningInfo(rec->entry, code);
325 rec->size = code->ExecutableSize();
326 processor_->Enqueue(evt_rec);
327 }
328
329 void CpuProfiler::CodeMoveEvent(AbstractCode* from, Address to) {
330 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
331 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
332 rec->from = from->address();
333 rec->to = to;
334 processor_->Enqueue(evt_rec);
335 }
336
337 void CpuProfiler::CodeDisableOptEvent(AbstractCode* code,
338 SharedFunctionInfo* shared) {
339 CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
340 CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
341 rec->start = code->address();
342 rec->bailout_reason = GetBailoutReason(shared->disable_optimization_reason());
343 processor_->Enqueue(evt_rec);
344 }
345
346 void CpuProfiler::CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) {
347 CodeEventsContainer evt_rec(CodeEventRecord::CODE_DEOPT);
348 CodeDeoptEventRecord* rec = &evt_rec.CodeDeoptEventRecord_;
349 Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(code, pc);
350 rec->start = code->address();
351 rec->deopt_reason = Deoptimizer::GetDeoptReason(info.deopt_reason);
352 rec->position = info.position;
353 rec->deopt_id = info.deopt_id;
354 processor_->Enqueue(evt_rec);
355 processor_->AddDeoptStack(isolate_, pc, fp_to_sp_delta);
356 }
357
358 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) {
359 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
360 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
361 rec->start = entry_point;
362 rec->entry = profiles_->NewCodeEntry(
363 Logger::CALLBACK_TAG,
364 profiles_->GetName(name),
365 "get ");
366 rec->size = 1;
367 processor_->Enqueue(evt_rec);
368 }
369
370 void CpuProfiler::RegExpCodeCreateEvent(AbstractCode* code, String* source) {
371 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
372 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
373 rec->start = code->address();
374 rec->entry = profiles_->NewCodeEntry(
375 Logger::REG_EXP_TAG, profiles_->GetName(source), "RegExp: ",
376 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
377 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
378 rec->size = code->ExecutableSize();
379 processor_->Enqueue(evt_rec);
380 }
381
382
383 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) {
384 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
385 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
386 rec->start = entry_point;
387 rec->entry = profiles_->NewCodeEntry(
388 Logger::CALLBACK_TAG,
389 profiles_->GetName(name),
390 "set ");
391 rec->size = 1;
392 processor_->Enqueue(evt_rec);
393 }
394
395 Name* CpuProfiler::InferScriptName(Name* name, SharedFunctionInfo* info) {
396 if (name->IsString() && String::cast(name)->length()) return name;
397 if (!info->script()->IsScript()) return name;
398 Object* source_url = Script::cast(info->script())->source_url();
399 return source_url->IsName() ? Name::cast(source_url) : name;
400 }
401
402 void CpuProfiler::RecordInliningInfo(CodeEntry* entry,
403 AbstractCode* abstract_code) {
404 if (!abstract_code->IsCode()) return;
405 Code* code = abstract_code->GetCode();
406 if (code->kind() != Code::OPTIMIZED_FUNCTION) return;
407 DeoptimizationInputData* deopt_input_data =
408 DeoptimizationInputData::cast(code->deoptimization_data());
409 int deopt_count = deopt_input_data->DeoptCount();
410 for (int i = 0; i < deopt_count; i++) {
411 int pc_offset = deopt_input_data->Pc(i)->value();
412 if (pc_offset == -1) continue;
413 int translation_index = deopt_input_data->TranslationIndex(i)->value();
414 TranslationIterator it(deopt_input_data->TranslationByteArray(),
415 translation_index);
416 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
417 DCHECK_EQ(Translation::BEGIN, opcode);
418 it.Skip(Translation::NumberOfOperandsFor(opcode));
419 int depth = 0;
420 std::vector<CodeEntry*> inline_stack;
421 while (it.HasNext() &&
422 Translation::BEGIN !=
423 (opcode = static_cast<Translation::Opcode>(it.Next()))) {
424 if (opcode != Translation::JS_FRAME &&
425 opcode != Translation::INTERPRETED_FRAME) {
426 it.Skip(Translation::NumberOfOperandsFor(opcode));
427 continue;
428 }
429 it.Next(); // Skip ast_id
430 int shared_info_id = it.Next();
431 it.Next(); // Skip height
432 SharedFunctionInfo* shared_info = SharedFunctionInfo::cast(
433 deopt_input_data->LiteralArray()->get(shared_info_id));
434 if (!depth++) continue; // Skip the current function itself.
435 CodeEntry* inline_entry = new CodeEntry(
436 entry->tag(), profiles_->GetFunctionName(shared_info->DebugName()),
437 CodeEntry::kEmptyNamePrefix, entry->resource_name(),
438 CpuProfileNode::kNoLineNumberInfo,
439 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
440 inline_entry->FillFunctionInfo(shared_info);
441 inline_stack.push_back(inline_entry);
442 } 262 }
443 if (!inline_stack.empty()) { 263 default:
444 entry->AddInlineStack(pc_offset, inline_stack); 264 UNREACHABLE();
445 DCHECK(inline_stack.empty());
446 }
447 } 265 }
448 } 266 }
449 267
450 void CpuProfiler::RecordDeoptInlinedFrames(CodeEntry* entry,
451 AbstractCode* abstract_code) {
452 if (abstract_code->kind() != AbstractCode::OPTIMIZED_FUNCTION) return;
453 Code* code = abstract_code->GetCode();
454 DeoptimizationInputData* deopt_input_data =
455 DeoptimizationInputData::cast(code->deoptimization_data());
456 int const mask = RelocInfo::ModeMask(RelocInfo::DEOPT_ID);
457 for (RelocIterator rit(code, mask); !rit.done(); rit.next()) {
458 RelocInfo* reloc_info = rit.rinfo();
459 DCHECK(RelocInfo::IsDeoptId(reloc_info->rmode()));
460 int deopt_id = static_cast<int>(reloc_info->data());
461 int translation_index =
462 deopt_input_data->TranslationIndex(deopt_id)->value();
463 TranslationIterator it(deopt_input_data->TranslationByteArray(),
464 translation_index);
465 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
466 DCHECK_EQ(Translation::BEGIN, opcode);
467 it.Skip(Translation::NumberOfOperandsFor(opcode));
468 std::vector<CodeEntry::DeoptInlinedFrame> inlined_frames;
469 while (it.HasNext() &&
470 Translation::BEGIN !=
471 (opcode = static_cast<Translation::Opcode>(it.Next()))) {
472 if (opcode != Translation::JS_FRAME &&
473 opcode != Translation::INTERPRETED_FRAME) {
474 it.Skip(Translation::NumberOfOperandsFor(opcode));
475 continue;
476 }
477 BailoutId ast_id = BailoutId(it.Next());
478 int shared_info_id = it.Next();
479 it.Next(); // Skip height
480 SharedFunctionInfo* shared = SharedFunctionInfo::cast(
481 deopt_input_data->LiteralArray()->get(shared_info_id));
482 int source_position = Deoptimizer::ComputeSourcePosition(shared, ast_id);
483 int script_id = v8::UnboundScript::kNoScriptId;
484 if (shared->script()->IsScript()) {
485 Script* script = Script::cast(shared->script());
486 script_id = script->id();
487 }
488 CodeEntry::DeoptInlinedFrame frame = {source_position, script_id};
489 inlined_frames.push_back(frame);
490 }
491 if (!inlined_frames.empty() && !entry->HasDeoptInlinedFramesFor(deopt_id)) {
492 entry->AddDeoptInlinedFrames(deopt_id, inlined_frames);
493 DCHECK(inlined_frames.empty());
494 }
495 }
496 }
497
498 CpuProfiler::CpuProfiler(Isolate* isolate) 268 CpuProfiler::CpuProfiler(Isolate* isolate)
499 : isolate_(isolate), 269 : isolate_(isolate),
500 sampling_interval_(base::TimeDelta::FromMicroseconds( 270 sampling_interval_(base::TimeDelta::FromMicroseconds(
501 FLAG_cpu_profiler_sampling_interval)), 271 FLAG_cpu_profiler_sampling_interval)),
502 profiles_(new CpuProfilesCollection(isolate->heap())), 272 profiles_(new CpuProfilesCollection(isolate->heap())),
503 generator_(NULL), 273 generator_(NULL),
504 processor_(NULL), 274 processor_(NULL),
505 is_profiling_(false) { 275 is_profiling_(false),
276 is_testing_(false) {
277 CpuProfilerManager::instance()->RegisterCpuProfiler(this);
506 } 278 }
507 279
508 280 CpuProfiler::CpuProfiler(Isolate* isolate, CpuProfilesCollection* test_profiles,
509 CpuProfiler::CpuProfiler(Isolate* isolate,
510 CpuProfilesCollection* test_profiles,
511 ProfileGenerator* test_generator, 281 ProfileGenerator* test_generator,
512 ProfilerEventsProcessor* test_processor) 282 ProfilerEventsProcessor* test_processor)
513 : isolate_(isolate), 283 : isolate_(isolate),
514 sampling_interval_(base::TimeDelta::FromMicroseconds( 284 sampling_interval_(base::TimeDelta::FromMicroseconds(
515 FLAG_cpu_profiler_sampling_interval)), 285 FLAG_cpu_profiler_sampling_interval)),
516 profiles_(test_profiles), 286 profiles_(test_profiles),
517 generator_(test_generator), 287 generator_(test_generator),
518 processor_(test_processor), 288 processor_(test_processor),
519 is_profiling_(false) { 289 is_profiling_(false),
290 is_testing_(true) {
291 CpuProfilerManager::instance()->RegisterCpuProfiler(this);
520 } 292 }
521 293
522 294
523 CpuProfiler::~CpuProfiler() { 295 CpuProfiler::~CpuProfiler() {
296 CpuProfilerManager::instance()->RemoveCpuProfiler(this);
524 DCHECK(!is_profiling_); 297 DCHECK(!is_profiling_);
525 delete profiles_; 298 delete profiles_;
526 } 299 }
527 300
528 301
529 void CpuProfiler::set_sampling_interval(base::TimeDelta value) { 302 void CpuProfiler::set_sampling_interval(base::TimeDelta value) {
530 DCHECK(!is_profiling_); 303 DCHECK(!is_profiling_);
531 sampling_interval_ = value; 304 sampling_interval_ = value;
532 } 305 }
533 306
(...skipping 28 matching lines...) Expand all
562 return; 335 return;
563 } 336 }
564 Logger* logger = isolate_->logger(); 337 Logger* logger = isolate_->logger();
565 // Disable logging when using the new implementation. 338 // Disable logging when using the new implementation.
566 saved_is_logging_ = logger->is_logging_; 339 saved_is_logging_ = logger->is_logging_;
567 logger->is_logging_ = false; 340 logger->is_logging_ = false;
568 generator_ = new ProfileGenerator(profiles_); 341 generator_ = new ProfileGenerator(profiles_);
569 sampler::Sampler* sampler = logger->sampler(); 342 sampler::Sampler* sampler = logger->sampler();
570 processor_ = new ProfilerEventsProcessor( 343 processor_ = new ProfilerEventsProcessor(
571 generator_, sampler, sampling_interval_); 344 generator_, sampler, sampling_interval_);
345 RESOLVE_CODE_EVENT(isolate_);
572 is_profiling_ = true; 346 is_profiling_ = true;
573 isolate_->set_is_profiling(true); 347 isolate_->set_is_profiling(true);
574 // Enumerate stuff we already have in the heap. 348 // Enumerate stuff we already have in the heap.
575 DCHECK(isolate_->heap()->HasBeenSetUp()); 349 DCHECK(isolate_->heap()->HasBeenSetUp());
576 if (!FLAG_prof_browser_mode) { 350 if (!FLAG_prof_browser_mode) {
577 logger->LogCodeObjects(); 351 logger->LogCodeObjects();
578 } 352 }
579 logger->LogCompiledFunctions(); 353 logger->LogCompiledFunctions();
580 logger->LogAccessorCallbacks(); 354 logger->LogAccessorCallbacks();
581 LogBuiltins(); 355 LogBuiltins();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 for (int i = 0; i < Builtins::builtin_count; i++) { 408 for (int i = 0; i < Builtins::builtin_count; i++) {
635 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); 409 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN);
636 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; 410 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
637 Builtins::Name id = static_cast<Builtins::Name>(i); 411 Builtins::Name id = static_cast<Builtins::Name>(i);
638 rec->start = builtins->builtin(id)->address(); 412 rec->start = builtins->builtin(id)->address();
639 rec->builtin_id = id; 413 rec->builtin_id = id;
640 processor_->Enqueue(evt_rec); 414 processor_->Enqueue(evt_rec);
641 } 415 }
642 } 416 }
643 417
644
645 } // namespace internal 418 } // namespace internal
646 } // namespace v8 419 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/cpu-profiler.h ('k') | src/profiler/profile-generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698