| Index: src/cpu-profiler.cc
|
| diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
|
| index 153aa76bfcc0287af4788e2c0a1735c00ff880eb..4869e76beda4913b767142b81f6ea77a42317494 100644
|
| --- a/src/cpu-profiler.cc
|
| +++ b/src/cpu-profiler.cc
|
| @@ -25,12 +25,14 @@
|
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
| -#ifdef ENABLE_CPP_PROFILES_PROCESSOR
|
| -
|
| #include "v8.h"
|
|
|
| #include "cpu-profiler-inl.h"
|
|
|
| +#ifdef ENABLE_CPP_PROFILES_PROCESSOR
|
| +
|
| +#include "log-inl.h"
|
| +
|
| namespace v8 {
|
| namespace internal {
|
|
|
| @@ -49,6 +51,21 @@ ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
|
| enqueue_order_(0) { }
|
|
|
|
|
| +void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
|
| + const char* prefix,
|
| + String* name,
|
| + Address start) {
|
| + CodeEventsContainer evt_rec;
|
| + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
|
| + rec->type = CodeEventRecord::CODE_CREATION;
|
| + rec->order = ++enqueue_order_;
|
| + rec->start = start;
|
| + rec->entry = generator_->NewCodeEntry(tag, prefix, name);
|
| + rec->size = 1;
|
| + events_buffer_.Enqueue(evt_rec);
|
| +}
|
| +
|
| +
|
| void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
|
| String* name,
|
| String* resource_name,
|
| @@ -196,6 +213,254 @@ void ProfilerEventsProcessor::Run() {
|
| while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { }
|
| }
|
|
|
| +
|
| +CpuProfiler* CpuProfiler::singleton_ = NULL;
|
| +
|
| +void CpuProfiler::StartProfiling(const char* title) {
|
| + ASSERT(singleton_ != NULL);
|
| + singleton_->StartCollectingProfile(title);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::StartProfiling(String* title) {
|
| + ASSERT(singleton_ != NULL);
|
| + singleton_->StartCollectingProfile(title);
|
| +}
|
| +
|
| +
|
| +CpuProfile* CpuProfiler::StopProfiling(const char* title) {
|
| + ASSERT(singleton_ != NULL);
|
| + return singleton_->StopCollectingProfile(title);
|
| +}
|
| +
|
| +
|
| +CpuProfile* CpuProfiler::StopProfiling(String* title) {
|
| + ASSERT(singleton_ != NULL);
|
| + return singleton_->StopCollectingProfile(title);
|
| +}
|
| +
|
| +
|
| +int CpuProfiler::GetProfilesCount() {
|
| + ASSERT(singleton_ != NULL);
|
| + return singleton_->profiles_->profiles()->length();
|
| +}
|
| +
|
| +
|
| +CpuProfile* CpuProfiler::GetProfile(int index) {
|
| + ASSERT(singleton_ != NULL);
|
| + return singleton_->profiles_->profiles()->at(index);
|
| +}
|
| +
|
| +
|
| +CpuProfile* CpuProfiler::FindProfile(unsigned uid) {
|
| + ASSERT(singleton_ != NULL);
|
| + return singleton_->profiles_->GetProfile(uid);
|
| +}
|
| +
|
| +
|
| +TickSample* CpuProfiler::TickSampleEvent() {
|
| + ASSERT(singleton_ != NULL);
|
| + if (singleton_->is_profiling()) {
|
| + return singleton_->processor_->TickSampleEvent();
|
| + } else {
|
| + return NULL;
|
| + }
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::CallbackEvent(String* name, Address entry_point) {
|
| + singleton_->processor_->CallbackCreateEvent(
|
| + Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
|
| + Code* code, const char* comment) {
|
| + singleton_->processor_->CodeCreateEvent(
|
| + tag, comment, code->address(), code->ExecutableSize());
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
|
| + Code* code, String* name) {
|
| + singleton_->processor_->CodeCreateEvent(
|
| + tag,
|
| + name,
|
| + Heap::empty_string(),
|
| + CodeEntry::kNoLineNumberInfo,
|
| + code->address(),
|
| + code->ExecutableSize());
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
|
| + Code* code, String* name,
|
| + String* source, int line) {
|
| + singleton_->processor_->CodeCreateEvent(
|
| + tag,
|
| + name,
|
| + source,
|
| + line,
|
| + code->address(),
|
| + code->ExecutableSize());
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
|
| + Code* code, int args_count) {
|
| + singleton_->processor_->CodeCreateEvent(
|
| + tag,
|
| + args_count,
|
| + code->address(),
|
| + code->ExecutableSize());
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::CodeMoveEvent(Address from, Address to) {
|
| + singleton_->processor_->CodeMoveEvent(from, to);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::CodeDeleteEvent(Address from) {
|
| + singleton_->processor_->CodeDeleteEvent(from);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::FunctionCreateEvent(JSFunction* function) {
|
| + singleton_->processor_->FunctionCreateEvent(
|
| + function->address(), function->code()->address());
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::FunctionMoveEvent(Address from, Address to) {
|
| + singleton_->processor_->FunctionMoveEvent(from, to);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::FunctionDeleteEvent(Address from) {
|
| + singleton_->processor_->FunctionDeleteEvent(from);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) {
|
| + singleton_->processor_->CallbackCreateEvent(
|
| + Logger::CALLBACK_TAG, "get ", name, entry_point);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
|
| + singleton_->processor_->CodeCreateEvent(
|
| + Logger::REG_EXP_TAG,
|
| + source,
|
| + Heap::empty_string(),
|
| + CodeEntry::kNoLineNumberInfo,
|
| + code->address(),
|
| + code->ExecutableSize());
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::SetterCallbackEvent(String* name, Address entry_point) {
|
| + singleton_->processor_->CallbackCreateEvent(
|
| + Logger::CALLBACK_TAG, "set ", name, entry_point);
|
| +}
|
| +
|
| +
|
| +CpuProfiler::CpuProfiler()
|
| + : profiles_(new CpuProfilesCollection()),
|
| + next_profile_uid_(1),
|
| + generator_(NULL),
|
| + processor_(NULL) {
|
| +}
|
| +
|
| +
|
| +CpuProfiler::~CpuProfiler() {
|
| + delete profiles_;
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::StartCollectingProfile(const char* title) {
|
| + if (profiles_->StartProfiling(title, ++next_profile_uid_)) {
|
| + StartProcessorIfNotStarted();
|
| + }
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::StartCollectingProfile(String* title) {
|
| + if (profiles_->StartProfiling(title, ++next_profile_uid_)) {
|
| + StartProcessorIfNotStarted();
|
| + }
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::StartProcessorIfNotStarted() {
|
| + if (processor_ == NULL) {
|
| + generator_ = new ProfileGenerator(profiles_);
|
| + processor_ = new ProfilerEventsProcessor(generator_);
|
| + processor_->Start();
|
| + // Enumerate stuff we already have in the heap.
|
| + if (Heap::HasBeenSetup()) {
|
| + Logger::LogCodeObjects();
|
| + Logger::LogCompiledFunctions();
|
| + Logger::LogFunctionObjects();
|
| + Logger::LogAccessorCallbacks();
|
| + }
|
| + // Enable stack sampling.
|
| + Logger::ticker_->Start();
|
| + }
|
| +}
|
| +
|
| +
|
| +CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
|
| + StopProcessorIfLastProfile();
|
| + CpuProfile* result = profiles_->StopProfiling(title);
|
| + if (result != NULL) {
|
| + result->Print();
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +
|
| +CpuProfile* CpuProfiler::StopCollectingProfile(String* title) {
|
| + StopProcessorIfLastProfile();
|
| + return profiles_->StopProfiling(title);
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::StopProcessorIfLastProfile() {
|
| + if (profiles_->is_last_profile()) {
|
| + Logger::ticker_->Stop();
|
| + processor_->Stop();
|
| + processor_->Join();
|
| + delete processor_;
|
| + delete generator_;
|
| + processor_ = NULL;
|
| + generator_ = NULL;
|
| + }
|
| +}
|
| +
|
| } } // namespace v8::internal
|
|
|
| #endif // ENABLE_CPP_PROFILES_PROCESSOR
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +
|
| +void CpuProfiler::Setup() {
|
| +#ifdef ENABLE_CPP_PROFILES_PROCESSOR
|
| + if (singleton_ == NULL) {
|
| + singleton_ = new CpuProfiler();
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +
|
| +void CpuProfiler::TearDown() {
|
| +#ifdef ENABLE_CPP_PROFILES_PROCESSOR
|
| + if (singleton_ != NULL) {
|
| + delete singleton_;
|
| + }
|
| + singleton_ = NULL;
|
| +#endif
|
| +}
|
| +
|
| +} } // namespace v8::internal
|
|
|