diff options
author | Anna Henningsen <anna@addaleax.net> | 2017-09-04 04:07:13 +0300 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2017-09-15 22:42:22 +0300 |
commit | dcb24e3be5546a9cdbc20d9a8d0efae8ebaf1520 (patch) | |
tree | cd3b94d1d92e3e437fd4abb26c8bd5a28ea48ff8 /src/node_perf.cc | |
parent | 8403d6b99965cfe5b387690eb5e12ab2d0f3750e (diff) |
src: keep track of env properly in node_perf.cc
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 <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Diffstat (limited to 'src/node_perf.cc')
-rw-r--r-- | src/node_perf.cc | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/src/node_perf.cc b/src/node_perf.cc index 098cf35220a..95e93259f47 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -170,13 +170,14 @@ void SetupPerformanceObservers(const FunctionCallbackInfo<Value>& args) { env->set_performance_entry_callback(args[0].As<Function>()); } -inline void PerformanceGCCallback(uv_async_t* handle) { +void PerformanceGCCallback(uv_async_t* handle) { PerformanceEntry::Data* data = static_cast<PerformanceEntry::Data*>(handle->data); - Isolate* isolate = Isolate::GetCurrent(); + Environment* env = data->env(); + Isolate* isolate = env->isolate(); HandleScope scope(isolate); - Environment* env = Environment::GetCurrent(isolate); Local<Context> context = env->context(); + Context::Scope context_scope(context); Local<Function> fn; Local<Object> obj; PerformanceGCKind kind = static_cast<PerformanceGCKind>(data->data()); @@ -199,28 +200,31 @@ inline void PerformanceGCCallback(uv_async_t* handle) { uv_close(reinterpret_cast<uv_handle_t*>(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<Environment*>(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<void*>(env)); } inline Local<Value> GetName(Local<Function> fn) { @@ -376,7 +380,7 @@ void Init(Local<Object> target, constants, attr).ToChecked(); - SetupGarbageCollectionTracking(isolate); + SetupGarbageCollectionTracking(env); } } // namespace performance |