@@ -118,7 +118,13 @@ void MarkGarbageCollectionStart(
118
118
GCCallbackFlags flags,
119
119
void * data) {
120
120
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
+ }
121
126
env->performance_state ()->performance_last_gc_start_mark = PERFORMANCE_NOW ();
127
+ env->performance_state ()->current_gc_type = type;
122
128
}
123
129
124
130
MaybeLocal<Object> GCPerformanceEntryTraits::GetDetails (
@@ -155,6 +161,10 @@ void MarkGarbageCollectionEnd(
155
161
void * data) {
156
162
Environment* env = static_cast <Environment*>(data);
157
163
PerformanceState* state = env->performance_state ();
164
+ if (type != state->current_gc_type ) {
165
+ return ;
166
+ }
167
+ env->performance_state ()->current_gc_type = 0 ;
158
168
// If no one is listening to gc performance entries, do not create them.
159
169
if (LIKELY (!state->observers [NODE_PERFORMANCE_ENTRY_TYPE_GC]))
160
170
return ;
@@ -179,14 +189,17 @@ void MarkGarbageCollectionEnd(
179
189
180
190
void GarbageCollectionCleanupHook (void * data) {
181
191
Environment* env = static_cast <Environment*>(data);
192
+ // Reset current_gc_type to 0
193
+ env->performance_state ()->current_gc_type = 0 ;
182
194
env->isolate ()->RemoveGCPrologueCallback (MarkGarbageCollectionStart, data);
183
195
env->isolate ()->RemoveGCEpilogueCallback (MarkGarbageCollectionEnd, data);
184
196
}
185
197
186
198
static void InstallGarbageCollectionTracking (
187
199
const FunctionCallbackInfo<Value>& args) {
188
200
Environment* env = Environment::GetCurrent (args);
189
-
201
+ // Reset current_gc_type to 0
202
+ env->performance_state ()->current_gc_type = 0 ;
190
203
env->isolate ()->AddGCPrologueCallback (MarkGarbageCollectionStart,
191
204
static_cast <void *>(env));
192
205
env->isolate ()->AddGCEpilogueCallback (MarkGarbageCollectionEnd,
0 commit comments