+2011-04-18 Ivan Maidanski <ivmai@mail.ru>
+
+ * dbg_mlc.c (GC_store_debug_info_inner): Always define; add
+ "const" to its string argument.
+ * dbg_mlc.c (GC_store_debug_info): Call GC_store_debug_info_inner.
+ * dbg_mlc.c (GC_debug_free): Set GC_have_errors in case of
+ smashed or previously deallocated found.
+ * dbg_mlc.c (GC_check_heap_block): Replace while loop with a for
+ one.
+ * reclaim.c (GC_reclaim_check): Ditto.
+ * dbg_mlc.c (GC_check_heap_proc): Remove redundant cast to word.
+ * os_dep.c (GC_get_stack_base): Don't initialize
+ stackbase_main_self/ss_sp on Solaris if thr_main() is zero (thus
+ calling GC_INIT() from a non-primordial thread is possible now).
+ * reclaim.c (GC_add_leaked): Turn into an inline one.
+ * reclaim.c (GC_reclaim_small_nonempty_block):
+ Change report_if_found type from int/word to boolean.
+ * include/private/gc_priv.h (GC_start_reclaim): Ditto.
+ * include/private/gc_priv.h (set_mark_bit_from_hdr,
+ clear_mark_bit_from_hdr): Place closing parenthesis properly;
+ reformat the code.
+
2011-04-16 Ivan Maidanski <ivmai@mail.ru>
* os_dep.c (GC_get_main_stack_base): Try to use
# define CROSSES_HBLK(p, sz) \
(((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE)
-/* Store debugging info into p. Return displaced pointer. */
-/* Assumes we don't hold allocation lock. */
-GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *string,
- word integer)
-{
- word * result = (word *)((oh *)p + 1);
- DCL_LOCK_STATE;
-
- LOCK();
- GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
- GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
-# ifdef KEEP_BACK_PTRS
- ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
-# endif
-# ifdef MAKE_BACK_GRAPH
- ((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0);
-# endif
- ((oh *)p) -> oh_string = string;
- ((oh *)p) -> oh_int = integer;
-# ifndef SHORT_DBG_HDRS
- ((oh *)p) -> oh_sz = sz;
- ((oh *)p) -> oh_sf = START_FLAG ^ (word)result;
- ((word *)p)[BYTES_TO_WORDS(GC_size(p))-1] =
- result[SIMPLE_ROUNDED_UP_WORDS(sz)] = END_FLAG ^ (word)result;
-# endif
- UNLOCK();
- return((ptr_t)result);
-}
-#ifdef DBG_HDRS_ALL
/* Store debugging info into p. Return displaced pointer. */
/* This version assumes we do hold the allocation lock. */
-STATIC ptr_t GC_store_debug_info_inner(ptr_t p, word sz, char *string,
+STATIC ptr_t GC_store_debug_info_inner(ptr_t p, word sz, const char *string,
word integer)
{
word * result = (word *)((oh *)p + 1);
# endif
return((ptr_t)result);
}
-#endif
+
+GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *string,
+ word integer)
+{
+ ptr_t result;
+ DCL_LOCK_STATE;
+
+ LOCK();
+ result = GC_store_debug_info_inner(p, sz, string, integer);
+ UNLOCK();
+ return result;
+}
#ifndef SHORT_DBG_HDRS
/* Check the object with debugging info at ohdr */
GC_API void GC_CALL GC_debug_free(void * p)
{
ptr_t base;
-# ifndef SHORT_DBG_HDRS
- ptr_t clobbered;
-# endif
if (0 == p) return;
base = GC_base(p);
}
if ((ptr_t)p - (ptr_t)base != sizeof(oh)) {
GC_err_printf(
- "GC_debug_free called on pointer %p w/o debugging info\n", p);
+ "GC_debug_free called on pointer %p w/o debugging info\n", p);
} else {
# ifndef SHORT_DBG_HDRS
- clobbered = GC_check_annotated_obj((oh *)base);
+ ptr_t clobbered = GC_check_annotated_obj((oh *)base);
if (clobbered != 0) {
if (((oh *)base) -> oh_sz == GC_size(base)) {
GC_err_printf(
- "GC_debug_free: found previously deallocated (?) object at ");
+ "GC_debug_free: found previously deallocated (?) object at ");
} else {
GC_err_printf("GC_debug_free: found smashed location at ");
}
GC_print_smashed_obj(p, clobbered);
+ GC_have_errors = TRUE;
}
/* Invalidate size */
((oh *)base) -> oh_sz = GC_size(base);
if (clobbered != 0) {
GC_err_printf("GC_debug_realloc: found smashed location at ");
GC_print_smashed_obj(p, clobbered);
+ GC_have_errors = TRUE;
}
old_sz = ((oh *)base) -> oh_sz;
# endif
char *p, *plim;
p = hbp->hb_body;
- bit_no = 0;
if (sz > MAXOBJBYTES) {
- plim = p;
+ plim = p;
} else {
- plim = hbp->hb_body + HBLKSIZE - sz;
+ plim = hbp->hb_body + HBLKSIZE - sz;
}
/* go through all words in block */
- while( p <= plim ) {
- if( mark_bit_from_hdr(hhdr, bit_no)
- && GC_HAS_DEBUG_INFO((ptr_t)p)) {
- ptr_t clobbered = GC_check_annotated_obj((oh *)p);
-
- if (clobbered != 0) GC_add_smashed(clobbered);
- }
- bit_no += MARK_BIT_OFFSET(sz);
- p += sz;
+ for (bit_no = 0; p <= plim; bit_no += MARK_BIT_OFFSET(sz), p += sz) {
+ if (mark_bit_from_hdr(hhdr, bit_no) && GC_HAS_DEBUG_INFO((ptr_t)p)) {
+ ptr_t clobbered = GC_check_annotated_obj((oh *)p);
+ if (clobbered != 0)
+ GC_add_smashed(clobbered);
+ }
}
}
{
GC_STATIC_ASSERT((sizeof(oh) & (GRANULE_BYTES - 1)) == 0);
/* FIXME: Should we check for twice that alignment? */
- GC_apply_to_all_blocks(GC_check_heap_block, (word)0);
+ GC_apply_to_all_blocks(GC_check_heap_block, 0);
}
#endif /* !SHORT_DBG_HDRS */
#ifdef USE_MARK_BYTES
# define mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n])
-# define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n]) = 1
-# define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n]) = 0
+# define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] = 1)
+# define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] = 0)
#else /* !USE_MARK_BYTES */
-# define mark_bit_from_hdr(hhdr,n) (((hhdr)->hb_marks[divWORDSZ(n)] \
- >> (modWORDSZ(n))) & (word)1)
+# define mark_bit_from_hdr(hhdr,n) \
+ (((hhdr)->hb_marks[divWORDSZ(n)] >> (modWORDSZ(n))) & (word)1)
# define set_mark_bit_from_hdr(hhdr,n) \
- OR_WORD((hhdr)->hb_marks+divWORDSZ(n), \
- (word)1 << modWORDSZ(n))
-# define clear_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
- &= ~((word)1 << modWORDSZ(n))
+ OR_WORD((hhdr)->hb_marks+divWORDSZ(n), (word)1 << modWORDSZ(n))
+# define clear_mark_bit_from_hdr(hhdr,n) \
+ ((hhdr)->hb_marks[divWORDSZ(n)] &= ~((word)1 << modWORDSZ(n)))
#endif /* !USE_MARK_BYTES */
#ifdef MARK_BIT_PER_OBJ
# define MARK_BIT_OFFSET(sz) BYTES_TO_GRANULES(sz)
# define IF_PER_OBJ(x)
# define FINAL_MARK_BIT(sz) \
- ((sz) > MAXOBJBYTES? MARK_BITS_PER_HBLK \
- : BYTES_TO_GRANULES((sz) * HBLK_OBJS(sz)))
+ ((sz) > MAXOBJBYTES ? MARK_BITS_PER_HBLK \
+ : BYTES_TO_GRANULES((sz) * HBLK_OBJS(sz)))
#endif
/* Important internal collector routines */
/* Misc GC: */
GC_INNER GC_bool GC_expand_hp_inner(word n);
-GC_INNER void GC_start_reclaim(int abort_if_found);
+GC_INNER void GC_start_reclaim(GC_bool abort_if_found);
/* Restore unmarked objects to free */
/* lists, or (if abort_if_found is */
/* TRUE) report them. */
/* s.ss_sp holds the pointer to the stack bottom. */
GC_ASSERT((void *)&s HOTTER_THAN s.ss_sp);
- if (!stackbase_main_self)
+ if (!stackbase_main_self && thr_main() != 0)
{
/* Cache the stack base value for the primordial thread (this */
/* is done during GC_init, so there is no race). */
GC_INNER GC_bool GC_have_errors = FALSE;
-STATIC void GC_add_leaked(ptr_t leaked)
+GC_INLINE void GC_add_leaked(ptr_t leaked)
{
GC_have_errors = TRUE;
/* FIXME: Prevent adding an object while printing leaked ones. */
/* Don't really reclaim objects, just check for unmarked ones: */
STATIC void GC_reclaim_check(struct hblk *hbp, hdr *hhdr, word sz)
{
- word bit_no = 0;
+ word bit_no;
ptr_t p, plim;
-
GC_ASSERT(sz == hhdr -> hb_sz);
- p = hbp->hb_body;
- plim = p + HBLKSIZE - sz;
/* go through all words in block */
- while (p <= plim) {
- if( !mark_bit_from_hdr(hhdr, bit_no) ) {
- GC_add_leaked(p);
- }
- p += sz;
- bit_no += MARK_BIT_OFFSET(sz);
- }
+ p = hbp->hb_body;
+ plim = p + HBLKSIZE - sz;
+ for (bit_no = 0; p <= plim; p += sz, bit_no += MARK_BIT_OFFSET(sz)) {
+ if (!mark_bit_from_hdr(hhdr, bit_no)) {
+ GC_add_leaked(p);
+ }
+ }
}
-
/*
* Generic procedure to rebuild a free list in hbp.
* Also called directly from GC_malloc_many.
* caller should perform that check.
*/
STATIC void GC_reclaim_small_nonempty_block(struct hblk *hbp,
- int report_if_found)
+ GC_bool report_if_found)
{
hdr *hhdr = HDR(hbp);
size_t sz = hhdr -> hb_sz;
GC_atomic_in_use += sz * hhdr -> hb_n_marks;
}
if (report_if_found) {
- GC_reclaim_small_nonempty_block(hbp, (int)report_if_found);
+ GC_reclaim_small_nonempty_block(hbp, (GC_bool)report_if_found);
} else if (empty) {
GC_bytes_found += HBLKSIZE;
GC_freehblk(hbp);