From b1580ad25996e9cef24d58559c5ffb4122606766 Mon Sep 17 00:00:00 2001 From: theanarkh Date: Sun, 31 Jul 2022 03:49:22 +0800 Subject: [PATCH] perf_hooks: fix gc elapsed time --- src/node_perf.cc | 15 ++++++++++++++- src/node_perf_common.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/node_perf.cc b/src/node_perf.cc index 2511a71ba2c08c..b8fffa9fcb397c 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -116,7 +116,13 @@ void MarkGarbageCollectionStart( GCCallbackFlags flags, void* data) { Environment* env = static_cast(data); + // Prevent gc callback from reentering with different type + // See https://github.com/nodejs/node/issues/44046 + if (env->performance_state()->current_gc_type != 0) { + return; + } env->performance_state()->performance_last_gc_start_mark = PERFORMANCE_NOW(); + env->performance_state()->current_gc_type = type; } MaybeLocal GCPerformanceEntryTraits::GetDetails( @@ -153,6 +159,10 @@ void MarkGarbageCollectionEnd( void* data) { Environment* env = static_cast(data); PerformanceState* state = env->performance_state(); + if (type != state->current_gc_type) { + return; + } + env->performance_state()->current_gc_type = 0; // If no one is listening to gc performance entries, do not create them. if (LIKELY(!state->observers[NODE_PERFORMANCE_ENTRY_TYPE_GC])) return; @@ -178,6 +188,8 @@ void MarkGarbageCollectionEnd( void GarbageCollectionCleanupHook(void* data) { Environment* env = static_cast(data); + // Reset current_gc_type to 0 + env->performance_state()->current_gc_type = 0; env->isolate()->RemoveGCPrologueCallback(MarkGarbageCollectionStart, data); env->isolate()->RemoveGCEpilogueCallback(MarkGarbageCollectionEnd, data); } @@ -185,7 +197,8 @@ void GarbageCollectionCleanupHook(void* data) { static void InstallGarbageCollectionTracking( const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - + // Reset current_gc_type to 0 + env->performance_state()->current_gc_type = 0; env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart, static_cast(env)); env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd, diff --git a/src/node_perf_common.h b/src/node_perf_common.h index ed520e69153b46..f457d73c579c01 100644 --- a/src/node_perf_common.h +++ b/src/node_perf_common.h @@ -71,6 +71,7 @@ class PerformanceState { AliasedUint32Array observers; uint64_t performance_last_gc_start_mark = 0; + uint16_t current_gc_type = 0; void Mark(enum PerformanceMilestone milestone, uint64_t ts = PERFORMANCE_NOW());