+
+ if (n == 0) return;
+
+ IF_DEBUG(weak,fprintf(stderr,"weak: batching %d finalizers\n", n));
+
+ arr = (StgMutArrPtrs *)allocate(sizeofW(StgMutArrPtrs) + n);
+ SET_HDR(arr, &stg_MUT_ARR_PTRS_FROZEN_info, CCS_SYSTEM);
+ arr->ptrs = n;
+
+ for (n = 0, w = list; w; w = w->link) {
+ if (w->finalizer != &stg_NO_FINALIZER_closure) {
+ arr->payload[n] = w->finalizer;
+ n++;
+ }
+
+#ifdef PROFILING
+ // A weak pointer is inherently used, so we do not need to call
+ // LDV_recordDead().
+ //
+ // Furthermore, when PROFILING is turned on, dead weak
+ // pointers are exactly as large as weak pointers, so there is
+ // no need to fill the slop, either. See stg_DEAD_WEAK_info
+ // in StgMiscClosures.hc.
+#endif
+ SET_HDR(w, &stg_DEAD_WEAK_info, w->header.prof.ccs);
+ }
+
+ t = createIOThread(RtsFlags.GcFlags.initialStkSize,
+ rts_apply(
+ rts_apply(
+ (StgClosure *)runFinalizerBatch_closure,
+ rts_mkInt(n)),
+ (StgClosure *)arr)
+ );
+ scheduleThread(t);