@@ -1058,6 +1058,13 @@ Environment::~Environment() {
|
1058 | 1058 | } |
1059 | 1059 | |
1060 | 1060 | delete external_memory_accounter_; |
| 1061 | +if (cpu_profiler_) { |
| 1062 | +for (auto& it : pending_profiles_) { |
| 1063 | + cpu_profiler_->Stop(it.second); |
| 1064 | + } |
| 1065 | + cpu_profiler_->Dispose(); |
| 1066 | + cpu_profiler_ = nullptr; |
| 1067 | + } |
1061 | 1068 | } |
1062 | 1069 | |
1063 | 1070 | void Environment::InitializeLibuv() { |
@@ -2221,4 +2228,33 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const {
|
2221 | 2228 | void Environment::RunWeakRefCleanup() { |
2222 | 2229 | isolate()->ClearKeptObjects(); |
2223 | 2230 | } |
| 2231 | + |
| 2232 | +v8::CpuProfilingResult Environment::StartCpuProfile(std::string_view name) { |
| 2233 | + HandleScope handle_scope(isolate()); |
| 2234 | +if (!cpu_profiler_) { |
| 2235 | + cpu_profiler_ = v8::CpuProfiler::New(isolate()); |
| 2236 | + } |
| 2237 | + Local<Value> title = |
| 2238 | +node::ToV8Value(context(), name, isolate()).ToLocalChecked(); |
| 2239 | + v8::CpuProfilingResult result = |
| 2240 | + cpu_profiler_->Start(title.As<String>(), true); |
| 2241 | +if (result.status == v8::CpuProfilingStatus::kStarted) { |
| 2242 | + pending_profiles_.emplace(name, result.id); |
| 2243 | + } |
| 2244 | +return result; |
| 2245 | +} |
| 2246 | + |
| 2247 | +v8::CpuProfile* Environment::StopCpuProfile(std::string_view name) { |
| 2248 | +if (!cpu_profiler_) { |
| 2249 | +return nullptr; |
| 2250 | + } |
| 2251 | +auto it = pending_profiles_.find(std::string(name)); |
| 2252 | +if (it == pending_profiles_.end()) { |
| 2253 | +return nullptr; |
| 2254 | + } |
| 2255 | + v8::CpuProfile* profile = cpu_profiler_->Stop(it->second); |
| 2256 | + pending_profiles_.erase(it); |
| 2257 | +return profile; |
| 2258 | +} |
| 2259 | + |
2224 | 2260 | } // namespace node |