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