+ if (!GC_is_initialized) GC_init_inner();
+ /* Do our share of marking work */
+ if (GC_incremental && !GC_dont_gc) {
+ ENTER_GC();
+ GC_collect_a_little_inner(1);
+ EXIT_GC();
+ }
+ /* First see if we can reclaim a page of objects waiting to be */
+ /* reclaimed. */
+ {
+ struct hblk ** rlh = ok -> ok_reclaim_list;
+ struct hblk * hbp;
+ hdr * hhdr;
+
+ rlh += lw;
+ while ((hbp = *rlh) != 0) {
+ hhdr = HDR(hbp);
+ *rlh = hhdr -> hb_next;
+ hhdr -> hb_last_reclaimed = (unsigned short) GC_gc_no;
+# ifdef PARALLEL_MARK
+ {
+ signed_word my_words_allocd_tmp = GC_words_allocd_tmp;
+
+ GC_ASSERT(my_words_allocd_tmp >= 0);
+ /* We only decrement it while holding the GC lock. */
+ /* Thus we can't accidentally adjust it down in more */
+ /* than one thread simultaneously. */
+ if (my_words_allocd_tmp != 0) {
+ (void)GC_atomic_add(
+ (volatile GC_word *)(&GC_words_allocd_tmp),
+ (GC_word)(-my_words_allocd_tmp));
+ GC_words_allocd += my_words_allocd_tmp;
+ }
+ }
+ GC_acquire_mark_lock();
+ ++ GC_fl_builder_count;
+ UNLOCK();
+ ENABLE_SIGNALS();
+ GC_release_mark_lock();
+# endif
+ op = GC_reclaim_generic(hbp, hhdr, lw,
+ ok -> ok_init, 0 COUNT_ARG);
+ if (op != 0) {
+# ifdef NEED_TO_COUNT
+ /* We are neither gathering statistics, nor marking in */
+ /* parallel. Thus GC_reclaim_generic doesn't count */
+ /* for us. */
+ for (p = op; p != 0; p = obj_link(p)) {
+ my_words_allocd += lw;
+ }
+# endif
+# if defined(GATHERSTATS)
+ /* We also reclaimed memory, so we need to adjust */
+ /* that count. */
+ /* This should be atomic, so the results may be */
+ /* inaccurate. */
+ GC_mem_found += my_words_allocd;
+# endif
+# ifdef PARALLEL_MARK
+ *result = op;
+ (void)GC_atomic_add(
+ (volatile GC_word *)(&GC_words_allocd_tmp),
+ (GC_word)(my_words_allocd));
+ GC_acquire_mark_lock();
+ -- GC_fl_builder_count;
+ if (GC_fl_builder_count == 0) GC_notify_all_builder();
+ GC_release_mark_lock();
+ (void) GC_clear_stack(0);
+ return;
+# else
+ GC_words_allocd += my_words_allocd;
+ goto out;
+# endif
+ }
+# ifdef PARALLEL_MARK
+ GC_acquire_mark_lock();
+ -- GC_fl_builder_count;
+ if (GC_fl_builder_count == 0) GC_notify_all_builder();
+ GC_release_mark_lock();
+ DISABLE_SIGNALS();
+ LOCK();
+ /* GC lock is needed for reclaim list access. We */
+ /* must decrement fl_builder_count before reaquiring GC */
+ /* lock. Hopefully this path is rare. */
+# endif
+ }