GC_ASSERT(I_HOLD_LOCK());
/* Avoid growing the table in case of at least 25% of entries can */
/* be deleted by enforcing a collection. Ignored for small tables. */
- if (log_old_size >= GC_ON_GROW_LOG_SIZE_MIN) {
+ /* In incremental mode we skip this optimization, as we want to */
+ /* avoid triggering a full GC whenever possible. */
+ if (log_old_size >= GC_ON_GROW_LOG_SIZE_MIN && !GC_incremental) {
IF_CANCEL(int cancel_state;)
DISABLE_CANCEL(cancel_state);
/* overflow is handled by the caller, and is not a disaster. */
STATIC void GC_normal_finalize_mark_proc(ptr_t p)
{
+# if defined(_MSC_VER) && defined(I386)
+ hdr * hhdr = HDR(p);
+ /* This is a manually inlined variant of GC_push_obj(). Otherwise */
+ /* some optimizer bug is tickled in VC for X86 (v19, at least). */
+# define mark_stack_top GC_mark_stack_top
+ mse * mark_stack_limit = GC_mark_stack + GC_mark_stack_size;
+ word descr = hhdr -> hb_descr;
+
+ if (descr != 0) {
+ mark_stack_top++;
+ if ((word)mark_stack_top >= (word)mark_stack_limit) {
+ mark_stack_top = GC_signal_mark_stack_overflow(mark_stack_top);
+ }
+ mark_stack_top -> mse_start = p;
+ mark_stack_top -> mse_descr.w = descr;
+ }
+# undef mark_stack_top
+# else
GC_mark_stack_top = GC_push_obj(p, HDR(p), GC_mark_stack_top,
GC_mark_stack + GC_mark_stack_size);
+# endif
}
/* This only pays very partial attention to the mark descriptor. */
GC_dirty(GC_fnlz_roots.fo_head + index);
UNLOCK();
# ifndef DBG_HDRS_ALL
- if (EXPECT(new_fo != 0, FALSE)) {
/* Free unused new_fo returned by GC_oom_fn() */
GC_free((void *)new_fo);
- }
# endif
return;
}
# ifdef KEEP_BACK_PTRS
long i;
/* Stops when GC_gc_no wraps; that's OK. */
- last_back_trace_gc_no = (word)(-1); /* disable others. */
+ last_back_trace_gc_no = GC_WORD_MAX; /* disable others. */
for (i = 0; i < GC_backtraces; ++i) {
/* FIXME: This tolerates concurrent heap mutation, */
/* which may cause occasional mysterious results. */
/* These variables require synchronization to avoid data races. */
if (last_finalizer_notification != GC_gc_no) {
- last_finalizer_notification = GC_gc_no;
notifier_fn = GC_finalizer_notifier;
+ last_finalizer_notification = GC_gc_no;
}
UNLOCK();
if (notifier_fn != 0)