// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_PROFILER_CPU_PROFILER_H_ #define V8_PROFILER_CPU_PROFILER_H_ #include <atomic> #include <memory> #include "src/base/platform/condition-variable.h" #include "src/base/platform/mutex.h" #include "src/base/platform/time.h" #include "src/profiler/circular-queue.h" #include "src/profiler/profiler-listener.h" #include "src/profiler/tick-sample.h" #include "src/utils/locked-queue.h" #if V8_OS_WIN #include "src/base/platform/platform-win32.h" #endif namespace v8 { namespace sampler { class Sampler; } // namespace sampler namespace internal { // Forward declarations. class CodeEntry; class InstructionStreamMap; class CpuProfilesCollection; class Isolate; class Symbolizer; #define CODE_EVENTS_TYPE_LIST(V) … #define VM_EVENTS_TYPE_LIST(V) … class CodeEventRecord { … }; class CodeCreateEventRecord : public CodeEventRecord { … }; class CodeMoveEventRecord : public CodeEventRecord { … }; class CodeDisableOptEventRecord : public CodeEventRecord { … }; class CodeDeoptEventRecord : public CodeEventRecord { … }; class ReportBuiltinEventRecord : public CodeEventRecord { … }; // Signals that a native context's address has changed. class NativeContextMoveEventRecord : public CodeEventRecord { … }; // A record type for sending samples from the main thread/signal handler to the // profiling thread. class TickSampleEventRecord { … }; class CodeDeleteEventRecord : public CodeEventRecord { … }; // A record type for sending code events (e.g. create, move, delete) to the // profiling thread. class CodeEventsContainer { … }; // Maintains the number of active CPU profilers in an isolate, and routes // logging to a given ProfilerListener. class V8_NODISCARD ProfilingScope { … }; class ProfilerCodeObserver; // This class implements both the profile events processor thread and // methods called by event producers: VM and stack sampler threads. class V8_EXPORT_PRIVATE ProfilerEventsProcessor : public base::Thread, public CodeEventObserver { … }; class V8_EXPORT_PRIVATE SamplingEventsProcessor : public ProfilerEventsProcessor { … }; // Builds and maintains an InstructionStreamMap tracking code objects on the VM // heap. While alive, logs generated code, callbacks, and builtins from the // isolate. Redirects events to the profiler events processor when present. // CodeEntry lifetime is associated with the given CodeEntryStorage. class V8_EXPORT_PRIVATE ProfilerCodeObserver : public CodeEventObserver { … }; // The CpuProfiler is a sampling CPU profiler for JS frames. It corresponds to // v8::CpuProfiler at the API level. It spawns an additional thread which is // responsible for triggering samples and then symbolizing the samples with // function names. To symbolize on a background thread, the profiler copies // metadata about generated code off-heap. // // Sampling is done using posix signals (except on Windows). The profiling // thread sends a signal to the main thread, based on a timer. The signal // handler can interrupt the main thread between any abitrary instructions. // This means we are very careful about reading stack values during the signal // handler as we could be in the middle of an operation that is modifying the // stack. // // The story on Windows is similar except we use thread suspend and resume. // // Samples are passed to the profiling thread via a circular buffer. The // profiling thread symbolizes the samples by looking up the code pointers // against its own list of code objects. The profiling thread also listens for // code creation/move/deletion events (from the GC), to maintain its list of // code objects accurately. class V8_EXPORT_PRIVATE CpuProfiler { … }; } // namespace internal } // namespace v8 #endif // V8_PROFILER_CPU_PROFILER_H_