From: Ivan Maidanski Date: Thu, 14 Jun 2018 23:27:11 +0000 (+0300) Subject: Fix large object base computation in PUSH_CONTENTS() if MARK_BIT_PER_OBJ X-Git-Tag: v8.0.0~120 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=38b46be3ed7dd89bcda5418a67b01edc6dfd4a9c;p=gc Fix large object base computation in PUSH_CONTENTS() if MARK_BIT_PER_OBJ 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. --- diff --git a/include/private/gc_pmark.h b/include/private/gc_pmark.h index f12851a5..8cd61b16 100644 --- a/include/private/gc_pmark.h +++ b/include/private/gc_pmark.h @@ -325,14 +325,10 @@ GC_INNER mse * GC_signal_mark_stack_overflow(mse *msp); source, 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 = (ptr_t)(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; \ @@ -348,8 +344,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)); \