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 |