diff --git a/src/node_perf.cc b/src/node_perf.cc index 253f72157e8a7b..f6637aa97e9d63 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -118,7 +118,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( @@ -155,6 +161,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; @@ -179,6 +189,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); } @@ -186,7 +198,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());