| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "cpu-profiler-inl.h" | 30 #include "cpu-profiler-inl.h" |
| 31 | 31 |
| 32 #ifdef ENABLE_LOGGING_AND_PROFILING | 32 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 33 | 33 |
| 34 #include "frames-inl.h" | 34 #include "frames-inl.h" |
| 35 #include "hashmap.h" | 35 #include "hashmap.h" |
| 36 #include "log-inl.h" | 36 #include "log-inl.h" |
| 37 #include "vm-state-inl.h" |
| 37 | 38 |
| 38 #include "../include/v8-profiler.h" | 39 #include "../include/v8-profiler.h" |
| 39 | 40 |
| 40 namespace v8 { | 41 namespace v8 { |
| 41 namespace internal { | 42 namespace internal { |
| 42 | 43 |
| 43 static const int kEventsBufferSize = 256*KB; | 44 static const int kEventsBufferSize = 256*KB; |
| 44 static const int kTickSamplesBufferChunkSize = 64*KB; | 45 static const int kTickSamplesBufferChunkSize = 64*KB; |
| 45 static const int kTickSamplesBufferChunksCount = 16; | 46 static const int kTickSamplesBufferChunksCount = 16; |
| 46 | 47 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 rec->start = start; | 219 rec->start = start; |
| 219 rec->entry = generator_->NewCodeEntry(tag, prefix, name); | 220 rec->entry = generator_->NewCodeEntry(tag, prefix, name); |
| 220 rec->size = size; | 221 rec->size = size; |
| 221 events_buffer_.Enqueue(evt_rec); | 222 events_buffer_.Enqueue(evt_rec); |
| 222 } | 223 } |
| 223 | 224 |
| 224 | 225 |
| 225 void ProfilerEventsProcessor::AddCurrentStack() { | 226 void ProfilerEventsProcessor::AddCurrentStack() { |
| 226 TickSampleEventRecord record; | 227 TickSampleEventRecord record; |
| 227 TickSample* sample = &record.sample; | 228 TickSample* sample = &record.sample; |
| 228 sample->state = VMState::current_state(); | 229 sample->state = Isolate::Current()->current_vm_state(); |
| 229 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. | 230 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. |
| 230 sample->frames_count = 0; | 231 sample->frames_count = 0; |
| 231 for (StackTraceFrameIterator it; | 232 for (StackTraceFrameIterator it; |
| 232 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; | 233 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; |
| 233 it.Advance()) { | 234 it.Advance()) { |
| 234 JavaScriptFrame* frame = it.frame(); | 235 JavaScriptFrame* frame = it.frame(); |
| 235 sample->stack[sample->frames_count++] = | 236 sample->stack[sample->frames_count++] = |
| 236 reinterpret_cast<Address>(frame->function()); | 237 reinterpret_cast<Address>(frame->function()); |
| 237 } | 238 } |
| 238 record.order = enqueue_order_; | 239 record.order = enqueue_order_; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 | 358 |
| 358 | 359 |
| 359 CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) { | 360 CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) { |
| 360 ASSERT(Isolate::Current()->cpu_profiler() != NULL); | 361 ASSERT(Isolate::Current()->cpu_profiler() != NULL); |
| 361 CpuProfiler* profiler = Isolate::Current()->cpu_profiler(); | 362 CpuProfiler* profiler = Isolate::Current()->cpu_profiler(); |
| 362 const int token = profiler->token_enumerator_->GetTokenId(security_token); | 363 const int token = profiler->token_enumerator_->GetTokenId(security_token); |
| 363 return profiler->profiles_->GetProfile(token, uid); | 364 return profiler->profiles_->GetProfile(token, uid); |
| 364 } | 365 } |
| 365 | 366 |
| 366 | 367 |
| 367 TickSample* CpuProfiler::TickSampleEvent() { | 368 TickSample* CpuProfiler::TickSampleEvent(Isolate* isolate) { |
| 368 if (CpuProfiler::is_profiling()) { | 369 if (CpuProfiler::is_profiling(isolate)) { |
| 369 return Isolate::Current()->cpu_profiler()->processor_->TickSampleEvent(); | 370 return isolate->cpu_profiler()->processor_->TickSampleEvent(); |
| 370 } else { | 371 } else { |
| 371 return NULL; | 372 return NULL; |
| 372 } | 373 } |
| 373 } | 374 } |
| 374 | 375 |
| 375 | 376 |
| 376 void CpuProfiler::CallbackEvent(String* name, Address entry_point) { | 377 void CpuProfiler::CallbackEvent(String* name, Address entry_point) { |
| 377 Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent( | 378 Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent( |
| 378 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point); | 379 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point); |
| 379 } | 380 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 | 434 |
| 434 void CpuProfiler::FunctionCreateEvent(JSFunction* function) { | 435 void CpuProfiler::FunctionCreateEvent(JSFunction* function) { |
| 435 CpuProfiler* profiler = Isolate::Current()->cpu_profiler(); | 436 CpuProfiler* profiler = Isolate::Current()->cpu_profiler(); |
| 436 int security_token_id = TokenEnumerator::kNoSecurityToken; | 437 int security_token_id = TokenEnumerator::kNoSecurityToken; |
| 437 if (function->unchecked_context()->IsContext()) { | 438 if (function->unchecked_context()->IsContext()) { |
| 438 security_token_id = profiler->token_enumerator_->GetTokenId( | 439 security_token_id = profiler->token_enumerator_->GetTokenId( |
| 439 function->context()->global_context()->security_token()); | 440 function->context()->global_context()->security_token()); |
| 440 } | 441 } |
| 441 profiler->processor_->FunctionCreateEvent( | 442 profiler->processor_->FunctionCreateEvent( |
| 442 function->address(), | 443 function->address(), |
| 443 function->code()->address(), | 444 function->shared()->code()->address(), |
| 444 security_token_id); | 445 security_token_id); |
| 445 } | 446 } |
| 446 | 447 |
| 447 | 448 |
| 448 void CpuProfiler::ProcessMovedFunctions() { | 449 void CpuProfiler::ProcessMovedFunctions() { |
| 449 CpuProfiler* profiler = Isolate::Current()->cpu_profiler(); | 450 CpuProfiler* profiler = Isolate::Current()->cpu_profiler(); |
| 450 profiler->processor_->ProcessMovedFunctions(); | 451 profiler->processor_->ProcessMovedFunctions(); |
| 451 } | 452 } |
| 452 | 453 |
| 453 | 454 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent( | 500 Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent( |
| 500 Logger::CALLBACK_TAG, "set ", name, entry_point); | 501 Logger::CALLBACK_TAG, "set ", name, entry_point); |
| 501 } | 502 } |
| 502 | 503 |
| 503 | 504 |
| 504 CpuProfiler::CpuProfiler() | 505 CpuProfiler::CpuProfiler() |
| 505 : profiles_(new CpuProfilesCollection()), | 506 : profiles_(new CpuProfilesCollection()), |
| 506 next_profile_uid_(1), | 507 next_profile_uid_(1), |
| 507 token_enumerator_(new TokenEnumerator()), | 508 token_enumerator_(new TokenEnumerator()), |
| 508 generator_(NULL), | 509 generator_(NULL), |
| 509 processor_(NULL) { | 510 processor_(NULL), |
| 511 is_profiling_(false) { |
| 510 } | 512 } |
| 511 | 513 |
| 512 | 514 |
| 513 CpuProfiler::~CpuProfiler() { | 515 CpuProfiler::~CpuProfiler() { |
| 514 delete token_enumerator_; | 516 delete token_enumerator_; |
| 515 delete profiles_; | 517 delete profiles_; |
| 516 } | 518 } |
| 517 | 519 |
| 518 | 520 |
| 519 void CpuProfiler::StartCollectingProfile(const char* title) { | 521 void CpuProfiler::StartCollectingProfile(const char* title) { |
| 520 if (profiles_->StartProfiling(title, next_profile_uid_++)) { | 522 if (profiles_->StartProfiling(title, next_profile_uid_++)) { |
| 521 StartProcessorIfNotStarted(); | 523 StartProcessorIfNotStarted(); |
| 522 } | 524 } |
| 523 processor_->AddCurrentStack(); | 525 processor_->AddCurrentStack(); |
| 524 } | 526 } |
| 525 | 527 |
| 526 | 528 |
| 527 void CpuProfiler::StartCollectingProfile(String* title) { | 529 void CpuProfiler::StartCollectingProfile(String* title) { |
| 528 StartCollectingProfile(profiles_->GetName(title)); | 530 StartCollectingProfile(profiles_->GetName(title)); |
| 529 } | 531 } |
| 530 | 532 |
| 531 | 533 |
| 532 void CpuProfiler::StartProcessorIfNotStarted() { | 534 void CpuProfiler::StartProcessorIfNotStarted() { |
| 533 if (processor_ == NULL) { | 535 if (processor_ == NULL) { |
| 534 // Disable logging when using the new implementation. | 536 // Disable logging when using the new implementation. |
| 535 saved_logging_nesting_ = LOGGER->logging_nesting_; | 537 saved_logging_nesting_ = LOGGER->logging_nesting_; |
| 536 LOGGER->logging_nesting_ = 0; | 538 LOGGER->logging_nesting_ = 0; |
| 537 generator_ = new ProfileGenerator(profiles_); | 539 generator_ = new ProfileGenerator(profiles_); |
| 538 processor_ = new ProfilerEventsProcessor(Isolate::Current(), generator_); | 540 processor_ = new ProfilerEventsProcessor(Isolate::Current(), generator_); |
| 541 NoBarrier_Store(&is_profiling_, true); |
| 539 processor_->Start(); | 542 processor_->Start(); |
| 540 // Enumerate stuff we already have in the heap. | 543 // Enumerate stuff we already have in the heap. |
| 541 if (HEAP->HasBeenSetup()) { | 544 if (HEAP->HasBeenSetup()) { |
| 542 if (!FLAG_prof_browser_mode) { | 545 if (!FLAG_prof_browser_mode) { |
| 543 bool saved_log_code_flag = FLAG_log_code; | 546 bool saved_log_code_flag = FLAG_log_code; |
| 544 FLAG_log_code = true; | 547 FLAG_log_code = true; |
| 545 LOGGER->LogCodeObjects(); | 548 LOGGER->LogCodeObjects(); |
| 546 FLAG_log_code = saved_log_code_flag; | 549 FLAG_log_code = saved_log_code_flag; |
| 547 } | 550 } |
| 548 LOGGER->LogCompiledFunctions(); | 551 LOGGER->LogCompiledFunctions(); |
| 549 LOGGER->LogFunctionObjects(); | 552 LOGGER->LogFunctionObjects(); |
| 550 LOGGER->LogAccessorCallbacks(); | 553 LOGGER->LogAccessorCallbacks(); |
| 551 } | 554 } |
| 552 // Enable stack sampling. | 555 // Enable stack sampling. |
| 553 reinterpret_cast<Sampler*>(LOGGER->ticker_)->Start(); | 556 Sampler* sampler = reinterpret_cast<Sampler*>(LOGGER->ticker_); |
| 557 if (!sampler->IsActive()) sampler->Start(); |
| 558 sampler->IncreaseProfilingDepth(); |
| 554 } | 559 } |
| 555 } | 560 } |
| 556 | 561 |
| 557 | 562 |
| 558 CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) { | 563 CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) { |
| 559 const double actual_sampling_rate = generator_->actual_sampling_rate(); | 564 const double actual_sampling_rate = generator_->actual_sampling_rate(); |
| 560 StopProcessorIfLastProfile(title); | 565 StopProcessorIfLastProfile(title); |
| 561 CpuProfile* result = | 566 CpuProfile* result = |
| 562 profiles_->StopProfiling(TokenEnumerator::kNoSecurityToken, | 567 profiles_->StopProfiling(TokenEnumerator::kNoSecurityToken, |
| 563 title, | 568 title, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 574 const double actual_sampling_rate = generator_->actual_sampling_rate(); | 579 const double actual_sampling_rate = generator_->actual_sampling_rate(); |
| 575 const char* profile_title = profiles_->GetName(title); | 580 const char* profile_title = profiles_->GetName(title); |
| 576 StopProcessorIfLastProfile(profile_title); | 581 StopProcessorIfLastProfile(profile_title); |
| 577 int token = token_enumerator_->GetTokenId(security_token); | 582 int token = token_enumerator_->GetTokenId(security_token); |
| 578 return profiles_->StopProfiling(token, profile_title, actual_sampling_rate); | 583 return profiles_->StopProfiling(token, profile_title, actual_sampling_rate); |
| 579 } | 584 } |
| 580 | 585 |
| 581 | 586 |
| 582 void CpuProfiler::StopProcessorIfLastProfile(const char* title) { | 587 void CpuProfiler::StopProcessorIfLastProfile(const char* title) { |
| 583 if (profiles_->IsLastProfile(title)) { | 588 if (profiles_->IsLastProfile(title)) { |
| 584 reinterpret_cast<Sampler*>(LOGGER->ticker_)->Stop(); | 589 Sampler* sampler = reinterpret_cast<Sampler*>(LOGGER->ticker_); |
| 590 sampler->DecreaseProfilingDepth(); |
| 591 sampler->Stop(); |
| 585 processor_->Stop(); | 592 processor_->Stop(); |
| 586 processor_->Join(); | 593 processor_->Join(); |
| 587 delete processor_; | 594 delete processor_; |
| 588 delete generator_; | 595 delete generator_; |
| 589 processor_ = NULL; | 596 processor_ = NULL; |
| 597 NoBarrier_Store(&is_profiling_, false); |
| 590 generator_ = NULL; | 598 generator_ = NULL; |
| 591 LOGGER->logging_nesting_ = saved_logging_nesting_; | 599 LOGGER->logging_nesting_ = saved_logging_nesting_; |
| 592 } | 600 } |
| 593 } | 601 } |
| 594 | 602 |
| 595 } } // namespace v8::internal | 603 } } // namespace v8::internal |
| 596 | 604 |
| 597 #endif // ENABLE_LOGGING_AND_PROFILING | 605 #endif // ENABLE_LOGGING_AND_PROFILING |
| 598 | 606 |
| 599 namespace v8 { | 607 namespace v8 { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 613 #ifdef ENABLE_LOGGING_AND_PROFILING | 621 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 614 Isolate* isolate = Isolate::Current(); | 622 Isolate* isolate = Isolate::Current(); |
| 615 if (isolate->cpu_profiler() != NULL) { | 623 if (isolate->cpu_profiler() != NULL) { |
| 616 delete isolate->cpu_profiler(); | 624 delete isolate->cpu_profiler(); |
| 617 } | 625 } |
| 618 isolate->set_cpu_profiler(NULL); | 626 isolate->set_cpu_profiler(NULL); |
| 619 #endif | 627 #endif |
| 620 } | 628 } |
| 621 | 629 |
| 622 } } // namespace v8::internal | 630 } } // namespace v8::internal |
| OLD | NEW |