]> granicus.if.org Git - gc/commitdiff
Fix large object base computation in PUSH_CONTENTS() if MARK_BIT_PER_OBJ
authorIvan Maidanski <ivmai@mail.ru>
Thu, 14 Jun 2018 23:27:11 +0000 (02:27 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 17 Jul 2018 06:04:15 +0000 (09:04 +0300)
(a cherry-pick of commit 38b46be3 from 'master')

Issue #177 (bdwgc).

* include/private/gc_pmark.h [MARK_BIT_PER_OBJ] (PUSH_CONTENTS_HDR):
Do not call LONG_MULT() if inv_sz == LARGE_INV_SZ; set base to
hhdr->hb_block if inv_sz == LARGE_INV_SZ regardless of low_prod>>16
value; use EXPECT(FALSE) for inv_sz == LARGE_INV_SZ expression;
remove FIXME about offset; adjust assertion to allow hb_block==current.

include/private/gc_pmark.h

index 00524df52137566563584cfff23532a74306f565..1e70d07a6f653a14f441e15953b00c4d2412fbf4 100644 (file)
@@ -297,14 +297,10 @@ GC_INNER mse * GC_signal_mark_stack_overflow(mse *msp);
                            source, exit_label, hhdr, do_offset_check) \
   do { \
     size_t displ = HBLKDISPL(current); /* Displacement in block; in bytes. */\
-    unsigned32 low_prod, high_prod; \
+    unsigned32 high_prod; \
     unsigned32 inv_sz = hhdr -> hb_inv_sz; \
-    ptr_t base = current; \
-    LONG_MULT(high_prod, low_prod, (unsigned32)displ, inv_sz); \
-    /* product is > and within sz_in_bytes of displ * sz_in_bytes * 2**32 */ \
-    if (EXPECT(low_prod >> 16 != 0, FALSE)) { \
-      /* FIXME: fails if offset is a multiple of HBLKSIZE which becomes 0 */ \
-        if (inv_sz == LARGE_INV_SZ) { \
+    ptr_t base; \
+    if (EXPECT(inv_sz == LARGE_INV_SZ, FALSE)) { \
           size_t obj_displ; \
           base = (ptr_t)(hhdr -> hb_block); \
           obj_displ = (ptr_t)(current) - base; \
@@ -320,8 +316,13 @@ GC_INNER mse * GC_signal_mark_stack_overflow(mse *msp);
           } \
           GC_ASSERT(hhdr -> hb_sz > HBLKSIZE || \
                     hhdr -> hb_block == HBLKPTR(current)); \
-          GC_ASSERT((word)hhdr->hb_block < (word)(current)); \
-        } else { \
+          GC_ASSERT((word)(hhdr)->hb_block <= (word)(current)); \
+          high_prod = 0; \
+    } else { \
+        unsigned32 low_prod; \
+        base = (ptr_t)(current); \
+        LONG_MULT(high_prod, low_prod, (unsigned32)displ, inv_sz); \
+        if ((low_prod >> 16) != 0) { \
           size_t obj_displ; \
           /* Accurate enough if HBLKSIZE <= 2**15.      */ \
           GC_STATIC_ASSERT(HBLKSIZE <= (1 << 15)); \