Workaround 'label handle_thr_start is not used' cppcheck style warning
[platform/upstream/libgc.git] / finalize.c
index 64a0ec2..c8708b9 100644 (file)
@@ -124,7 +124,9 @@ STATIC void GC_grow_table(struct hash_chain_entry ***table,
     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);
@@ -634,8 +636,27 @@ GC_API GC_await_finalize_proc GC_CALL GC_get_await_finalize_proc(void)
 /* 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.        */
@@ -754,10 +775,8 @@ STATIC void GC_register_finalizer_inner(void * obj,
             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;
         }
@@ -1326,7 +1345,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void)
 #       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.         */
@@ -1366,8 +1385,8 @@ GC_INNER void GC_notify_or_invoke_finalizers(void)
 
     /* 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)