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 namespace v8 { 12 Create(v8::Isolate * isolate)13std::unique_ptr<TracingCpuProfiler> TracingCpuProfiler::Create( 14 v8::Isolate* isolate) { 15 return std::unique_ptr<TracingCpuProfiler>( 16 new internal::TracingCpuProfilerImpl( 17 reinterpret_cast<internal::Isolate*>(isolate))); 18 } 19 20 namespace internal { 21 TracingCpuProfilerImpl(Isolate * isolate)22TracingCpuProfilerImpl::TracingCpuProfilerImpl(Isolate* isolate) 23 : isolate_(isolate), profiling_enabled_(false) { 24 // Make sure tracing system notices profiler categories. 25 TRACE_EVENT_WARMUP_CATEGORY(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler")); 26 TRACE_EVENT_WARMUP_CATEGORY( 27 TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler.hires")); 28 V8::GetCurrentPlatform()->AddTraceStateObserver(this); 29 } 30 ~TracingCpuProfilerImpl()31TracingCpuProfilerImpl::~TracingCpuProfilerImpl() { 32 StopProfiling(); 33 V8::GetCurrentPlatform()->RemoveTraceStateObserver(this); 34 } 35 OnTraceEnabled()36void TracingCpuProfilerImpl::OnTraceEnabled() { 37 bool enabled; 38 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 39 TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"), &enabled); 40 if (!enabled) return; 41 profiling_enabled_ = true; 42 isolate_->RequestInterrupt( 43 [](v8::Isolate*, void* data) { 44 reinterpret_cast<TracingCpuProfilerImpl*>(data)->StartProfiling(); 45 }, 46 this); 47 } 48 OnTraceDisabled()49void TracingCpuProfilerImpl::OnTraceDisabled() { 50 base::LockGuard<base::Mutex> lock(&mutex_); 51 if (!profiling_enabled_) return; 52 profiling_enabled_ = false; 53 isolate_->RequestInterrupt( 54 [](v8::Isolate*, void* data) { 55 reinterpret_cast<TracingCpuProfilerImpl*>(data)->StopProfiling(); 56 }, 57 this); 58 } 59 StartProfiling()60void TracingCpuProfilerImpl::StartProfiling() { 61 base::LockGuard<base::Mutex> lock(&mutex_); 62 if (!profiling_enabled_ || profiler_) return; 63 bool enabled; 64 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 65 TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler.hires"), &enabled); 66 int sampling_interval_us = enabled ? 100 : 1000; 67 profiler_.reset(new CpuProfiler(isolate_)); 68 profiler_->set_sampling_interval( 69 base::TimeDelta::FromMicroseconds(sampling_interval_us)); 70 profiler_->StartProfiling("", true); 71 } 72 StopProfiling()73void TracingCpuProfilerImpl::StopProfiling() { 74 base::LockGuard<base::Mutex> lock(&mutex_); 75 if (!profiler_) return; 76 profiler_->StopProfiling(""); 77 profiler_.reset(); 78 } 79 80 } // namespace internal 81 } // namespace v8 82