summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/node_perf.cc24
-rw-r--r--test/parallel/test-performance-gc.js10
2 files changed, 27 insertions, 7 deletions
diff --git a/src/node_perf.cc b/src/node_perf.cc
index 6a59d50fb6..97d3a2d995 100644
--- a/src/node_perf.cc
+++ b/src/node_perf.cc
@@ -182,8 +182,9 @@ void SetupPerformanceObservers(const FunctionCallbackInfo<Value>& args) {
}
// Creates a GC Performance Entry and passes it to observers
-void PerformanceGCCallback(Environment* env, void* ptr) {
- GCPerformanceEntry* entry = static_cast<GCPerformanceEntry*>(ptr);
+void PerformanceGCCallback(uv_async_t* handle) {
+ GCPerformanceEntry* entry = static_cast<GCPerformanceEntry*>(handle->data);
+ Environment* env = entry->env();
HandleScope scope(env->isolate());
Local<Context> context = env->context();
@@ -200,6 +201,10 @@ void PerformanceGCCallback(Environment* env, void* ptr) {
}
delete entry;
+ auto closeCB = [](uv_handle_t* handle) {
+ delete reinterpret_cast<uv_async_t*>(handle);
+ };
+ uv_close(reinterpret_cast<uv_handle_t*>(handle), closeCB);
}
// Marks the start of a GC cycle
@@ -216,11 +221,16 @@ void MarkGarbageCollectionEnd(Isolate* isolate,
v8::GCCallbackFlags flags,
void* data) {
Environment* env = static_cast<Environment*>(data);
- env->SetImmediate(PerformanceGCCallback,
- new GCPerformanceEntry(env,
- static_cast<PerformanceGCKind>(type),
- performance_last_gc_start_mark_,
- PERFORMANCE_NOW()));
+ uv_async_t* async = new uv_async_t();
+ if (uv_async_init(env->event_loop(), async, PerformanceGCCallback))
+ return delete async;
+ uv_unref(reinterpret_cast<uv_handle_t*>(async));
+ async->data =
+ new GCPerformanceEntry(env,
+ static_cast<PerformanceGCKind>(type),
+ performance_last_gc_start_mark_,
+ PERFORMANCE_NOW());
+ CHECK_EQ(0, uv_async_send(async));
}
diff --git a/test/parallel/test-performance-gc.js b/test/parallel/test-performance-gc.js
index 89a9041c1c..ec0714ea50 100644
--- a/test/parallel/test-performance-gc.js
+++ b/test/parallel/test-performance-gc.js
@@ -51,3 +51,13 @@ const kinds = [
// Keep the event loop alive to witness the GC async callback happen.
setImmediate(() => setImmediate(() => 0));
}
+
+// GC should not keep the event loop alive
+{
+ let didCall = false;
+ process.on('beforeExit', () => {
+ assert(!didCall);
+ didCall = true;
+ global.gc();
+ });
+}