1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/profiler/tracing-cpu-profiler.h" 6 7 #include "src/profiler/cpu-profiler.h" 8 #include "src/tracing/trace-event.h" 9 #include "src/v8.h" 10 11 #define PROFILER_TRACE_CATEGORY_ENABLED(cat) \ 12 (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT(cat))) 13 14 namespace v8 { 15 Create(v8::Isolate * isolate)16std::unique_ptr<TracingCpuProfiler> TracingCpuProfiler::Create( 17 v8::Isolate* isolate) { 18 return std::unique_ptr<TracingCpuProfiler>( 19 new internal::TracingCpuProfilerImpl( 20 reinterpret_cast<internal::Isolate*>(isolate))); 21 } 22 23 namespace internal { 24 TracingCpuProfilerImpl(Isolate * isolate)25TracingCpuProfilerImpl::TracingCpuProfilerImpl(Isolate* isolate) 26 : isolate_(isolate), profiling_enabled_(false) { 27 // Make sure tracing system notices profiler categories. 28 PROFILER_TRACE_CATEGORY_ENABLED("v8.cpu_profiler"); 29 PROFILER_TRACE_CATEGORY_ENABLED("v8.cpu_profiler.hires"); 30 V8::GetCurrentPlatform()->AddTraceStateObserver(this); 31 } 32 ~TracingCpuProfilerImpl()33TracingCpuProfilerImpl::~TracingCpuProfilerImpl() { 34 StopProfiling(); 35 V8::GetCurrentPlatform()->RemoveTraceStateObserver(this); 36 } 37 OnTraceEnabled()38void TracingCpuProfilerImpl::OnTraceEnabled() { 39 if (!PROFILER_TRACE_CATEGORY_ENABLED("v8.cpu_profiler")) return; 40 profiling_enabled_ = true; 41 isolate_->RequestInterrupt( 42 [](v8::Isolate*, void* data) { 43 reinterpret_cast<TracingCpuProfilerImpl*>(data)->StartProfiling(); 44 }, 45 this); 46 } 47 OnTraceDisabled()48void TracingCpuProfilerImpl::OnTraceDisabled() { 49 base::LockGuard<base::Mutex> lock(&mutex_); 50 if (!profiling_enabled_) return; 51 profiling_enabled_ = false; 52 isolate_->RequestInterrupt( 53 [](v8::Isolate*, void* data) { 54 reinterpret_cast<TracingCpuProfilerImpl*>(data)->StopProfiling(); 55 }, 56 this); 57 } 58 StartProfiling()59void TracingCpuProfilerImpl::StartProfiling() { 60 base::LockGuard<base::Mutex> lock(&mutex_); 61 if (!profiling_enabled_ || profiler_) return; 62 int sampling_interval_us = 63 PROFILER_TRACE_CATEGORY_ENABLED("v8.cpu_profiler.hires") ? 100 : 1000; 64 profiler_.reset(new CpuProfiler(isolate_)); 65 profiler_->set_sampling_interval( 66 base::TimeDelta::FromMicroseconds(sampling_interval_us)); 67 profiler_->StartProfiling("", true); 68 } 69 StopProfiling()70void TracingCpuProfilerImpl::StopProfiling() { 71 base::LockGuard<base::Mutex> lock(&mutex_); 72 if (!profiler_) return; 73 profiler_->StopProfiling(""); 74 profiler_.reset(); 75 } 76 77 } // namespace internal 78 } // namespace v8 79