* backgraph.c (add_edge): Recognize DEBUG_PRINT_BIG_N_EDGES macro.
* os_dep.c (GC_set_and_save_fault_handler): Recognize
SIGACTION_FLAGS_NODEFER_HACK macro.
* pthread_support.c (mark_mutex): Recognize GLIBC_2_1_MUTEX_HACK
macro.
* pthread_support.c (GC_acquire_mark_lock): Remove commented out
code.
* include/gc_inline.h (GC_MALLOC_WORDS, GC_MALLOC_ATOMIC_WORDS,
GC_CONS): Remove trailing space (before back-slash).
* include/private/gc_hdrs.h (GET_BI, GET_HDR_ADDR): Ditto.
* include/private/gc_pmark.h (PUSH_OBJ, PUSH_CONTENTS,
SET_MARK_BIT_EXIT_IF_SET, LONG_MULT, PUSH_CONTENTS_HDR,
GC_PUSH_ONE_STACK, GC_PUSH_ONE_HEAP): Ditto.
* include/private/thread_local_alloc.h (GC_key_create): Ditto.
* include/private/gc_priv.h (SUNOS5SIGS): Don't include
sys/siginfo.h on Linux.
* include/private/gcconfig.h: Reformat comments (and some code).
* include/private/gcconfig.h (FORCE_WRITE_PREFETCH): New macro
recognized, force PREFETCH_FOR_WRITE to be defined on x86.
* include/private/gcconfig.h (USE_HPUX_FIXED_STACKBOTTOM): New
macro recognized (for HP/UX).
+2011-05-11 Ivan Maidanski <ivmai@mail.ru>
+
+ * backgraph.c (add_edge): Recognize DEBUG_PRINT_BIG_N_EDGES macro.
+ * os_dep.c (GC_set_and_save_fault_handler): Recognize
+ SIGACTION_FLAGS_NODEFER_HACK macro.
+ * pthread_support.c (mark_mutex): Recognize GLIBC_2_1_MUTEX_HACK
+ macro.
+ * pthread_support.c (GC_acquire_mark_lock): Remove commented out
+ code.
+ * include/gc_inline.h (GC_MALLOC_WORDS, GC_MALLOC_ATOMIC_WORDS,
+ GC_CONS): Remove trailing space (before back-slash).
+ * include/private/gc_hdrs.h (GET_BI, GET_HDR_ADDR): Ditto.
+ * include/private/gc_pmark.h (PUSH_OBJ, PUSH_CONTENTS,
+ SET_MARK_BIT_EXIT_IF_SET, LONG_MULT, PUSH_CONTENTS_HDR,
+ GC_PUSH_ONE_STACK, GC_PUSH_ONE_HEAP): Ditto.
+ * include/private/thread_local_alloc.h (GC_key_create): Ditto.
+ * include/private/gc_priv.h (SUNOS5SIGS): Don't include
+ sys/siginfo.h on Linux.
+ * include/private/gcconfig.h: Reformat comments (and some code).
+ * include/private/gcconfig.h (FORCE_WRITE_PREFETCH): New macro
+ recognized, force PREFETCH_FOR_WRITE to be defined on x86.
+ * include/private/gcconfig.h (USE_HPUX_FIXED_STACKBOTTOM): New
+ macro recognized (for HP/UX).
+
2011-05-11 Ivan Maidanski <ivmai@mail.ru>
* os_dep.c (GC_gww_page_was_ever_dirty): Fix comment (for
}
be_cont -> edges[i] = p;
be -> n_edges++;
- if (be -> n_edges == 100) {
-# if 0
- if (GC_print_stats) {
- GC_err_printf("The following object has in-degree >= 100:\n");
- GC_print_heap_obj(q);
- }
-# endif
- }
+# ifdef DEBUG_PRINT_BIG_N_EDGES
+ if (GC_print_stats == VERBOSE && be -> n_edges == 100) {
+ GC_err_printf("The following object has big in-degree:\n");
+ GC_print_heap_obj(q);
+ }
+# endif
}
typedef void (*per_object_func)(ptr_t p, size_t n_bytes, word gc_descr);
/* free list array. For single-threaded applications, this may be */
/* a global array. */
# define GC_MALLOC_WORDS(result,n,tiny_fl) \
-{ \
+{ \
size_t grans = GC_WORDS_TO_WHOLE_GRANULES(n); \
GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
NORMAL, GC_malloc(grans*GC_GRANULE_BYTES), \
}
# define GC_MALLOC_ATOMIC_WORDS(result,n,tiny_fl) \
-{ \
+{ \
size_t grans = GC_WORDS_TO_WHOLE_GRANULES(n); \
GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
PTRFREE, GC_malloc_atomic(grans*GC_GRANULE_BYTES), \
/* And once more for two word initialized objects: */
# define GC_CONS(result, first, second, tiny_fl) \
-{ \
+{ \
size_t grans = GC_WORDS_TO_WHOLE_GRANULES(2); \
GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
NORMAL, GC_malloc(grans*GC_GRANULE_BYTES), \
*(void **)(result) = (void *)(first)); \
- ((void **)(result))[1] = (void *)(second); \
+ ((void **)(result))[1] = (void *)(second); \
}
#endif /* !GC_INLINE_H */
register word hi = \
(word)(p) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); \
register bottom_index * _bi = GC_top_index[TL_HASH(hi)]; \
- \
while (_bi -> key != hi && _bi != GC_all_nils) \
_bi = _bi -> hash_link; \
(bottom_indx) = _bi; \
# define GET_HDR_ADDR(p, ha) \
{ \
register bottom_index * bi; \
- \
- GET_BI(p, bi); \
+ GET_BI(p, bi); \
(ha) = &(HDR_FROM_BI(bi, p)); \
}
# define GET_HDR(p, hhdr) { register hdr ** _ha; GET_HDR_ADDR(p, _ha); \
#define PUSH_OBJ(obj, hhdr, mark_stack_top, mark_stack_limit) \
{ \
register word _descr = (hhdr) -> hb_descr; \
- \
GC_ASSERT(!HBLK_IS_FREE(hhdr)); \
if (_descr != 0) { \
mark_stack_top++; \
source, exit_label) \
{ \
hdr * my_hhdr; \
- \
HC_GET_HDR(current, my_hhdr, source, exit_label); \
PUSH_CONTENTS_HDR(current, mark_stack_top, mark_stack_limit, \
- source, exit_label, my_hhdr, TRUE); \
+ source, exit_label, my_hhdr, TRUE); \
exit_label: ; \
}
{ \
char * mark_byte_addr = (char *)hhdr -> hb_marks + (bit_no); \
if (*mark_byte_addr) goto exit_label; \
- *mark_byte_addr = 1; \
+ *mark_byte_addr = 1; \
}
#else
# ifdef PARALLEL_MARK
# define LONG_MULT(hprod, lprod, x, y) { \
unsigned long long prod = (unsigned long long)(x) \
* (unsigned long long)(y); \
- hprod = prod >> 32; \
- lprod = (unsigned32)prod; \
+ hprod = prod >> 32; \
+ lprod = (unsigned32)prod; \
}
#endif /* !I386 */
/* first block, then we are in the all_interior_pointers case, and */ \
/* it is safe to use any displacement value. */ \
size_t gran_displ = BYTES_TO_GRANULES(displ); \
- size_t gran_offset = hhdr -> hb_map[gran_displ]; \
+ size_t gran_offset = hhdr -> hb_map[gran_displ]; \
size_t byte_offset = displ & (GRANULE_BYTES - 1); \
- ptr_t base = current; \
+ ptr_t base = current; \
/* The following always fails for large block references. */ \
if (EXPECT((gran_offset | byte_offset) != 0, FALSE)) { \
if (hhdr -> hb_large_block) { \
/* gran_offset is bogus. */ \
size_t obj_displ; \
base = (ptr_t)(hhdr -> hb_block); \
- obj_displ = (ptr_t)(current) - base; \
+ obj_displ = (ptr_t)(current) - base; \
if (obj_displ != displ) { \
GC_ASSERT(obj_displ < hhdr -> hb_sz); \
/* Must be in all_interior_pointer case, not first block */ \
size_t displ = HBLKDISPL(current); /* Displacement in block; in bytes. */\
unsigned32 low_prod, high_prod; \
unsigned32 inv_sz = hhdr -> hb_inv_sz; \
- ptr_t base = current; \
+ ptr_t base = current; \
LONG_MULT(high_prod, low_prod, displ, inv_sz); \
/* product is > and within sz_in_bytes of displ * sz_in_bytes * 2**32 */ \
if (EXPECT(low_prod >> 16 != 0, FALSE)) { \
if (inv_sz == LARGE_INV_SZ) { \
size_t obj_displ; \
base = (ptr_t)(hhdr -> hb_block); \
- obj_displ = (ptr_t)(current) - base; \
+ obj_displ = (ptr_t)(current) - base; \
if (obj_displ != displ) { \
GC_ASSERT(obj_displ < hhdr -> hb_sz); \
/* Must be in all_interior_pointer case, not first block */ \
#if NEED_FIXUP_POINTER
/* Try both the raw version and the fixed up one. */
# define GC_PUSH_ONE_STACK(p, source) \
- if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
- && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
- PUSH_ONE_CHECKED_STACK(p, source); \
+ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
+ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
+ PUSH_ONE_CHECKED_STACK(p, source); \
} \
FIXUP_POINTER(p); \
- if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
- && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
- PUSH_ONE_CHECKED_STACK(p, source); \
+ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
+ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
+ PUSH_ONE_CHECKED_STACK(p, source); \
}
#else /* !NEED_FIXUP_POINTER */
# define GC_PUSH_ONE_STACK(p, source) \
- if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
- && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
- PUSH_ONE_CHECKED_STACK(p, source); \
+ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
+ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
+ PUSH_ONE_CHECKED_STACK(p, source); \
}
#endif
*/
#define GC_PUSH_ONE_HEAP(p,source) \
FIXUP_POINTER(p); \
- if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
- && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
- GC_mark_stack_top = GC_mark_and_push( \
+ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
+ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
+ GC_mark_stack_top = GC_mark_and_push( \
(void *)(p), GC_mark_stack_top, \
GC_mark_stack_limit, (void * *)(source)); \
}
/* possible/needed. */
#if defined(UNIX_LIKE) || (defined(NEED_FIND_LIMIT) && defined(CYGWIN32))
# include <setjmp.h>
-# if defined(SUNOS5SIGS) && !defined(FREEBSD)
+# if defined(SUNOS5SIGS) && !defined(FREEBSD) && !defined(LINUX)
# include <sys/siginfo.h>
# endif
/* Define SETJMP and friends to be the version that restores */
# endif
/* And one for FreeBSD: */
-# if (defined(__FreeBSD__) || defined(__DragonFly__) || \
- defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
+# if (defined(__FreeBSD__) || defined(__DragonFly__) \
+ || defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
# define FREEBSD
# endif
# endif
# define mach_type_known
# endif
-# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) || \
- defined(powerpc64) || defined(__powerpc64__))
+# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) \
+ || defined(powerpc64) || defined(__powerpc64__))
# define POWERPC
# define mach_type_known
# endif
* allocation.
*/
-/* If we are using a recent version of gcc, we can use __builtin_unwind_init()
- * to push the relevant registers onto the stack.
- */
-# if defined(__GNUC__) && ((__GNUC__ >= 3) || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \
+/* If we are using a recent version of gcc, we can use */
+/* __builtin_unwind_init() to push the relevant registers onto the stack. */
+# if defined(__GNUC__) && ((__GNUC__ >= 3) \
+ || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \
&& !defined(__INTEL_COMPILER) && !defined(__PATHCC__)
# define HAVE_BUILTIN_UNWIND_INIT
# endif
# include <LowMem.h>
# endif
# define OS_TYPE "MACOS"
- /* see os_dep.c for details of global data segments. */
+ /* see os_dep.c for details of global data segments. */
# define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
# define DATAEND /* not needed */
# define GETPAGESIZE() 4096
# define ALIGNMENT 4
# define STACKBOTTOM ((ptr_t) 0xc0000000)
# endif
- /* XXX: see get_end(3), get_etext() and get_end() should not be used.
- These aren't used when dyld support is enabled (it is by default) */
+ /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
+ /* These aren't used when dyld support is enabled (it is by default). */
# define DATASTART ((ptr_t) get_etext())
# define DATAEND ((ptr_t) get_end())
# ifndef USE_MMAP
# define PREFETCH_FOR_WRITE(x) \
__asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
# endif
- /* There seems to be some issues with trylock hanging on darwin. This
- should be looked into some more */
+ /* There seems to be some issues with trylock hanging on darwin. */
+ /* This should be looked into some more. */
# define NO_PTHREAD_TRYLOCK
# endif
# ifdef OPENBSD
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
# endif
# ifdef USE_I686_PREFETCH
- /* FIXME: Thus should use __builtin_prefetch, but we'll leave that */
- /* for the next rtelease. */
+ /* FIXME: Thus should use __builtin_prefetch, but we'll leave that */
+ /* for the next rtelease. */
# define PREFETCH(x) \
- __asm__ __volatile__ (" prefetchnta %0": : "m"(*(char *)(x)))
- /* Empirically prefetcht0 is much more effective at reducing */
- /* cache miss stalls for the targeted load instructions. But it */
- /* seems to interfere enough with other cache traffic that the net */
- /* result is worse than prefetchnta. */
-# if 0
- /* Using prefetches for write seems to have a slight negative */
- /* impact on performance, at least for a PIII/500. */
+ __asm__ __volatile__ ("prefetchnta %0" : : "m"(*(char *)(x)))
+ /* Empirically prefetcht0 is much more effective at reducing */
+ /* cache miss stalls for the targeted load instructions. But it */
+ /* seems to interfere enough with other cache traffic that the */
+ /* net result is worse than prefetchnta. */
+# ifdef FORCE_WRITE_PREFETCH
+ /* Using prefetches for write seems to have a slight negative */
+ /* impact on performance, at least for a PIII/500. */
# define PREFETCH_FOR_WRITE(x) \
- __asm__ __volatile__ (" prefetcht0 %0": : "m"(*(char *)(x)))
+ __asm__ __volatile__ ("prefetcht0 %0" : : "m"(*(char *)(x)))
# endif
# endif
# ifdef USE_3DNOW_PREFETCH
# define PREFETCH(x) \
- __asm__ __volatile__ (" prefetch %0": : "m"(*(char *)(x)))
+ __asm__ __volatile__ ("prefetch %0" : : "m"(*(char *)(x)))
# define PREFETCH_FOR_WRITE(x) \
- __asm__ __volatile__ (" prefetchw %0": : "m"(*(char *)(x)))
+ __asm__ __volatile__ ("prefetchw %0" : : "m"(*(char *)(x)))
# endif
# endif
# ifdef CYGWIN32
extern int _stklen;
extern int __djgpp_stack_limit;
# define DATASTART ((ptr_t)((((word) (etext)) + 0x1ff) & ~0x1ff))
-/* # define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \
- + _stklen)) */
+/* #define STACKBOTTOM ((ptr_t)((word)_stubinfo+_stubinfo->size+_stklen)) */
# define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen))
/* This may not be right. */
# endif
extern long __nullarea;
extern char _end;
extern char *_STACKTOP;
- /* Depending on calling conventions Watcom C either precedes
- or does not precedes with underscore names of C-variables.
- Make sure startup code variables always have the same names. */
+ /* Depending on calling conventions Watcom C either precedes */
+ /* or does not precedes with underscore names of C-variables. */
+ /* Make sure startup code variables always have the same names. */
#pragma aux __nullarea "*";
#pragma aux _end "*";
# define STACKBOTTOM ((ptr_t) _STACKTOP)
# define OS_TYPE "DARWIN"
# define DARWIN_DONT_PARSE_STACK
# define DYNAMIC_LOADING
- /* XXX: see get_end(3), get_etext() and get_end() should not be used.
- These aren't used when dyld support is enabled (it is by default) */
+ /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
+ /* These aren't used when dyld support is enabled (it is by default). */
# define DATASTART ((ptr_t) get_etext())
# define DATAEND ((ptr_t) get_end())
# define STACKBOTTOM ((ptr_t) 0xc0000000)
# define MPROTECT_VDB
# include <unistd.h>
# define GETPAGESIZE() getpagesize()
- /* There seems to be some issues with trylock hanging on darwin. This
- should be looked into some more */
+ /* There seems to be some issues with trylock hanging on darwin. */
+ /* This should be looked into some more. */
# define NO_PTHREAD_TRYLOCK
# endif /* DARWIN */
# endif
# define OS_TYPE "HPUX"
extern int __data_start[];
# define DATASTART ((ptr_t)(__data_start))
-# if 0
+# ifdef USE_HPUX_FIXED_STACKBOTTOM
/* The following appears to work for 7xx systems running HP/UX */
/* 9.xx Furthermore, it might result in much faster */
/* collections than HEURISTIC2, which may involve scanning */
# define OS_TYPE "DARWIN"
# define DARWIN_DONT_PARSE_STACK
# define DYNAMIC_LOADING
- /* XXX: see get_end(3), get_etext() and get_end() should not be used.
- These aren't used when dyld support is enabled (it is by default) */
+ /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
+ /* These aren't used when dyld support is enabled (it is by default) */
# define DATASTART ((ptr_t) get_etext())
# define DATAEND ((ptr_t) get_end())
# define STACKBOTTOM ((ptr_t) 0x7fff5fc00000)
# define MPROTECT_VDB
# include <unistd.h>
# define GETPAGESIZE() getpagesize()
- /* There seems to be some issues with trylock hanging on darwin. This
- should be looked into some more */
+ /* There seems to be some issues with trylock hanging on darwin. */
+ /* This should be looked into some more. */
# define NO_PTHREAD_TRYLOCK
# endif
# ifdef FREEBSD
/* this is currently missing in WinCE */
# define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
# endif
-# define GC_key_create(key, d) \
+# define GC_key_create(key, d) \
((d) != 0 || (*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? -1 : 0)
/* Need TlsFree on process exit/detach ? */
typedef DWORD GC_key_t;
GC_INNER void GC_set_and_save_fault_handler(GC_fault_handler_t h)
{
-# if defined(SUNOS5SIGS) || defined(IRIX5) \
+# if defined(SUNOS5SIGS) || defined(IRIX5) \
|| defined(OSF1) || defined(HURD) || defined(NETBSD)
- struct sigaction act;
+ struct sigaction act;
- act.sa_handler = h;
-# if 0 /* Was necessary for Solaris 2.3 and very temporary */
- /* NetBSD bugs. */
- act.sa_flags = SA_RESTART | SA_NODEFER;
+ act.sa_handler = h;
+# ifdef SIGACTION_FLAGS_NODEFER_HACK
+ /* Was necessary for Solaris 2.3 and very temporary */
+ /* NetBSD bugs. */
+ act.sa_flags = SA_RESTART | SA_NODEFER;
# else
- act.sa_flags = SA_RESTART;
+ act.sa_flags = SA_RESTART;
# endif
(void) sigemptyset(&act.sa_mask);
}
# endif /* NEED_FIND_LIMIT || UNIX_LIKE */
-# if defined(NEED_FIND_LIMIT) || \
- defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS)
+# if defined(NEED_FIND_LIMIT) \
+ || (defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS))
/* Some tools to implement HEURISTIC2 */
# define MIN_PAGE_SIZE 256 /* Smallest conceivable page size, bytes */
GC_INNER unsigned long GC_mark_lock_holder = NO_THREAD;
#endif
-#if 0
+#ifdef GLIBC_2_1_MUTEX_HACK
/* Ugly workaround for a linux threads bug in the final versions */
/* of glibc2.1. Pthread_mutex_trylock sets the mutex owner */
/* field even when it fails to acquire the mutex. This causes */
GC_INNER void GC_acquire_mark_lock(void)
{
-/*
- if (pthread_mutex_lock(&mark_mutex) != 0) {
- ABORT("pthread_mutex_lock failed");
- }
-*/
GC_generic_lock(&mark_mutex);
# ifdef GC_ASSERTIONS
GC_mark_lock_holder = NUMERIC_THREAD_ID(pthread_self());