/* GC_enable_incremental once more). */
#endif /* !GC_DISABLE_INCREMENTAL */
+#ifdef MANUAL_VDB
+ GC_INNER void GC_dirty_async_inner(const void *p);
+# define GC_dirty_async(p) \
+ (GC_incremental ? GC_dirty_async_inner(p) : (void)0)
+#else
+# define GC_dirty_async(p) (void)(p)
+#endif
+
/* Same as GC_base but excepts and returns a pointer to const object. */
#define GC_base_C(p) ((const void *)GC_base((/* no const */ void *)(p)))
/* Empty. */
}
-#if defined(MANUAL_VDB)
- void GC_dirty(ptr_t p);
-#endif
-
-GC_API void GC_CALL GC_end_stubborn_change(const void *p GC_ATTR_UNUSED)
+GC_API void GC_CALL GC_end_stubborn_change(const void *p)
{
-# ifdef MANUAL_VDB
- GC_dirty((ptr_t)p);
-# endif
+ GC_dirty_async(p); /* entire object */
}
return mark_stack_ptr;
}
-#if defined(MANUAL_VDB) && defined(THREADS)
- void GC_dirty(ptr_t p);
-#endif
-
/* Mark and push (i.e. gray) a single object p onto the main */
/* mark stack. Consider p to be valid if it is an interior */
/* pointer. */
GC_ADD_TO_BLACK_LIST_NORMAL(p, source);
return;
}
-# if defined(MANUAL_VDB) && defined(THREADS)
+# ifdef THREADS
/* Pointer is on the stack. We may have dirtied the object */
- /* it points to, but not yet have called GC_dirty(); */
- GC_dirty(p); /* Implicitly affects entire object. */
+ /* it points to, but have not called GC_dirty yet. */
+ GC_dirty_async(p); /* entire object */
# endif
PUSH_CONTENTS_HDR(r, GC_mark_stack_top, GC_mark_stack_limit,
source, hhdr, FALSE);
/* Mark the page containing p as dirty. Logically, this dirties the */
/* entire object. */
- void GC_dirty(ptr_t p)
+ GC_INNER void GC_dirty_async_inner(const void *p)
{
word index = PHT_HASH(p);
async_set_pht_entry_from_index(GC_dirty_pages, index);