@@ -118,7 +118,13 @@ void MarkGarbageCollectionStart(
118118 GCCallbackFlags flags,
119119 void * data) {
120120 Environment* env = static_cast <Environment*>(data);
121+ // Prevent gc callback from reentering with different type
122+ // See https://github.com/nodejs/node/issues/44046
123+ if (env->performance_state ()->current_gc_type != 0 ) {
124+ return ;
125+ }
121126 env->performance_state ()->performance_last_gc_start_mark = PERFORMANCE_NOW ();
127+ env->performance_state ()->current_gc_type = type;
122128}
123129
124130MaybeLocal<Object> GCPerformanceEntryTraits::GetDetails (
@@ -155,6 +161,10 @@ void MarkGarbageCollectionEnd(
155161 void * data) {
156162 Environment* env = static_cast <Environment*>(data);
157163 PerformanceState* state = env->performance_state ();
164+ if (type != state->current_gc_type ) {
165+ return ;
166+ }
167+ env->performance_state ()->current_gc_type = 0 ;
158168 // If no one is listening to gc performance entries, do not create them.
159169 if (LIKELY (!state->observers [NODE_PERFORMANCE_ENTRY_TYPE_GC]))
160170 return ;
@@ -179,14 +189,17 @@ void MarkGarbageCollectionEnd(
179189
180190void GarbageCollectionCleanupHook (void * data) {
181191 Environment* env = static_cast <Environment*>(data);
192+ // Reset current_gc_type to 0
193+ env->performance_state ()->current_gc_type = 0 ;
182194 env->isolate ()->RemoveGCPrologueCallback (MarkGarbageCollectionStart, data);
183195 env->isolate ()->RemoveGCEpilogueCallback (MarkGarbageCollectionEnd, data);
184196}
185197
186198static void InstallGarbageCollectionTracking (
187199 const FunctionCallbackInfo<Value>& args) {
188200 Environment* env = Environment::GetCurrent (args);
189-
201+ // Reset current_gc_type to 0
202+ env->performance_state ()->current_gc_type = 0 ;
190203 env->isolate ()->AddGCPrologueCallback (MarkGarbageCollectionStart,
191204 static_cast <void *>(env));
192205 env->isolate ()->AddGCEpilogueCallback (MarkGarbageCollectionEnd,
0 commit comments