From dcb24e3be5546a9cdbc20d9a8d0efae8ebaf1520 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 4 Sep 2017 03:07:13 +0200 Subject: src: keep track of env properly in node_perf.cc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, measuring GC timing using `node_perf` is somewhat broken, because Isolates and Node Environments do not necessarily match 1:1; each environment adds its own hook, so possibly the hook code runs multiple times, but since it can’t reliably compute its corresponding event loop based on the Isolate, each run targets the same Environment right now. This fixes that problem by using new overloads of the GC tracking APIs that can pass data to the callback through opaque pointers. PR-URL: https://github.com/nodejs/node/pull/15391 Reviewed-By: James M Snell Reviewed-By: Michaël Zasso --- src/node_perf.cc | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'src/node_perf.cc') diff --git a/src/node_perf.cc b/src/node_perf.cc index 098cf35220..95e93259f4 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -170,13 +170,14 @@ void SetupPerformanceObservers(const FunctionCallbackInfo& args) { env->set_performance_entry_callback(args[0].As()); } -inline void PerformanceGCCallback(uv_async_t* handle) { +void PerformanceGCCallback(uv_async_t* handle) { PerformanceEntry::Data* data = static_cast(handle->data); - Isolate* isolate = Isolate::GetCurrent(); + Environment* env = data->env(); + Isolate* isolate = env->isolate(); HandleScope scope(isolate); - Environment* env = Environment::GetCurrent(isolate); Local context = env->context(); + Context::Scope context_scope(context); Local fn; Local obj; PerformanceGCKind kind = static_cast(data->data()); @@ -199,28 +200,31 @@ inline void PerformanceGCCallback(uv_async_t* handle) { uv_close(reinterpret_cast(handle), closeCB); } -inline void MarkGarbageCollectionStart(Isolate* isolate, - v8::GCType type, - v8::GCCallbackFlags flags) { +void MarkGarbageCollectionStart(Isolate* isolate, + v8::GCType type, + v8::GCCallbackFlags flags) { performance_last_gc_start_mark_ = PERFORMANCE_NOW(); performance_last_gc_type_ = type; } -inline void MarkGarbageCollectionEnd(Isolate* isolate, - v8::GCType type, - v8::GCCallbackFlags flags) { +void MarkGarbageCollectionEnd(Isolate* isolate, + v8::GCType type, + v8::GCCallbackFlags flags, + void* data) { + Environment* env = static_cast(data); uv_async_t *async = new uv_async_t; async->data = - new PerformanceEntry::Data("gc", "gc", + new PerformanceEntry::Data(env, "gc", "gc", performance_last_gc_start_mark_, PERFORMANCE_NOW(), type); - uv_async_init(uv_default_loop(), async, PerformanceGCCallback); + uv_async_init(env->event_loop(), async, PerformanceGCCallback); uv_async_send(async); } -inline void SetupGarbageCollectionTracking(Isolate* isolate) { - isolate->AddGCPrologueCallback(MarkGarbageCollectionStart); - isolate->AddGCEpilogueCallback(MarkGarbageCollectionEnd); +inline void SetupGarbageCollectionTracking(Environment* env) { + env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart); + env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd, + static_cast(env)); } inline Local GetName(Local fn) { @@ -376,7 +380,7 @@ void Init(Local target, constants, attr).ToChecked(); - SetupGarbageCollectionTracking(isolate); + SetupGarbageCollectionTracking(env); } } // namespace performance -- cgit v1.2.3