// Copyright 2016 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_PROFILER_LISTENER_H_ #define V8_PROFILER_PROFILER_LISTENER_H_ #include <vector> #include "src/code-events.h" #include "src/profiler/profile-generator.h" namespace v8 { namespace internal { class CodeEventsContainer; class CodeEventObserver { public: virtual void CodeEventHandler(const CodeEventsContainer& evt_rec) = 0; virtual ~CodeEventObserver() {} }; class ProfilerListener : public CodeEventListener { public: explicit ProfilerListener(Isolate* isolate); ~ProfilerListener() override; void CallbackEvent(Name* name, Address entry_point) override; void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, const char* comment) override; void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, Name* name) override; void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, SharedFunctionInfo* shared, Name* script_name) override; void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, SharedFunctionInfo* shared, Name* script_name, int line, int column) override; void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, const wasm::WasmCode* code, wasm::WasmName name) override; void CodeMovingGCEvent() override {} void CodeMoveEvent(AbstractCode* from, Address to) override; void CodeDisableOptEvent(AbstractCode* code, SharedFunctionInfo* shared) override; void CodeDeoptEvent(Code* code, DeoptKind kind, Address pc, int fp_to_sp_delta) override; void GetterCallbackEvent(Name* name, Address entry_point) override; void RegExpCodeCreateEvent(AbstractCode* code, String* source) override; void SetterCallbackEvent(Name* name, Address entry_point) override; void SharedFunctionInfoMoveEvent(Address from, Address to) override {} CodeEntry* NewCodeEntry( CodeEventListener::LogEventsAndTags tag, const char* name, const char* name_prefix = CodeEntry::kEmptyNamePrefix, const char* resource_name = CodeEntry::kEmptyResourceName, int line_number = v8::CpuProfileNode::kNoLineNumberInfo, int column_number = v8::CpuProfileNode::kNoColumnNumberInfo, std::unique_ptr<JITLineInfoTable> line_info = nullptr, Address instruction_start = nullptr); void AddObserver(CodeEventObserver* observer); void RemoveObserver(CodeEventObserver* observer); V8_INLINE bool HasObservers() { return !observers_.empty(); } const char* GetName(Name* name) { return function_and_resource_names_.GetName(name); } const char* GetName(int args_count) { return function_and_resource_names_.GetName(args_count); } const char* GetFunctionName(Name* name) { return function_and_resource_names_.GetFunctionName(name); } const char* GetFunctionName(const char* name) { return function_and_resource_names_.GetFunctionName(name); } size_t entries_count_for_test() const { return code_entries_.size(); } private: void RecordInliningInfo(CodeEntry* entry, AbstractCode* abstract_code); void RecordDeoptInlinedFrames(CodeEntry* entry, AbstractCode* abstract_code); Name* InferScriptName(Name* name, SharedFunctionInfo* info); V8_INLINE void DispatchCodeEvent(const CodeEventsContainer& evt_rec) { base::LockGuard<base::Mutex> guard(&mutex_); for (auto observer : observers_) { observer->CodeEventHandler(evt_rec); } } StringsStorage function_and_resource_names_; std::vector<std::unique_ptr<CodeEntry>> code_entries_; std::vector<CodeEventObserver*> observers_; base::Mutex mutex_; DISALLOW_COPY_AND_ASSIGN(ProfilerListener); }; } // namespace internal } // namespace v8 #endif // V8_PROFILER_PROFILER_LISTENER_H_