#pragma once #include #include #include #include #include "executor.h" #include "v8-profiler.h" #include #include #include #include #include #include namespace ivm { class IVMCpuProfile { public: explicit IVMCpuProfile(const std::shared_ptr& cpuProfile); ~IVMCpuProfile() = default; class CallFrame { public: explicit CallFrame(const v8::CpuProfileNode* node); ~CallFrame() = default; auto ToJSObject(v8::Isolate *iso) -> v8::Local; private: const char* function_name; const char* url; int script_id; int line_number; int column_number; }; class ProfileNode { public: explicit ProfileNode(const v8::CpuProfileNode* node); ~ProfileNode() = default; auto ToJSObject(v8::Isolate *iso) -> v8::Local; private: unsigned int hit_count; unsigned int node_id; const char* bailout_reason; std::vector children; CallFrame call_frame; }; auto GetStartTime() const -> int64_t { return start_time; } auto ToJSObject(v8::Isolate *iso) -> v8::Local; private: std::thread::id profile_thread; int64_t start_time; int64_t end_time; int64_t samples_count; std::vector samples; std::vector timestamps; std::vector profileNodes; auto GetTidValue(v8::Isolate *iso) -> v8::Local; auto BuildCpuProfile(v8::Isolate *iso) -> v8::Local; void FlatNodes(const v8::CpuProfileNode* node, std::vector* nodes) { // NOLINT(misc-no-recursion) nodes->emplace_back(node); const int childrenCount = node->GetChildrenCount(); for (int index = 0; index < childrenCount; ++index) { FlatNodes(node->GetChild(index), nodes); } } }; class CpuProfileManager { public: CpuProfileManager(); void StartProfiling(const char* title); auto StopProfiling(const char* title) -> std::vector; auto IsProfiling() -> bool; auto InjestCpuProfile(const std::shared_ptr& cpuProfile) -> void; CpuProfileManager(const CpuProfileManager&) = delete; auto operator= (const CpuProfileManager) = delete; ~CpuProfileManager() = default; private: void CleanProfiles(); std::set profile_titles{}; std::list profile_items{}; std::unordered_map::iterator> profile_begin_ptrs{}; std::mutex mutex; }; }