* mark.c (GC_clear_hdr_marks): Don't test USE_MARK_BYTES.
* extra/setjmp_t.c (main): Don't test USE_MARK_BITS.
* include/private/gc_pmark.h (SET_MARK_BIT_EXIT_IF_SET): Ditto.
* include/private/gc_pmark.h (SET_MARK_BIT_EXIT_IF_SET): Remove
"mark_byte" local variable.
* include/private/gc_pmark.h (OR_WORD_EXIT_IF_SET): Add a comment
about that AO_or() is not used by GC unless USE_MARK_BITS
explicitly set.
* include/private/gc_priv.h (OR_WORD): Ditto.
* include/private/gc_pmark.h (INCR_MARKS): Remove trailing ';',
add parentheses.
* include/private/gc_priv.h (ONES): Define before use by
MAKE_COOLER.
* include/private/gc_priv.h (MARK_BITS_SZ): Define where used.
* include/private/gc_priv.h (OR_WORD): Don't define if
USE_MARK_BYTES.
* include/private/gcconfig.h (USE_MARK_BYTES); Remove duplicate
definition; simplify expression.
+2011-04-23 Ivan Maidanski <ivmai@mail.ru>
+
+ * mark.c (GC_clear_hdr_marks): Don't test USE_MARK_BYTES.
+ * extra/setjmp_t.c (main): Don't test USE_MARK_BITS.
+ * include/private/gc_pmark.h (SET_MARK_BIT_EXIT_IF_SET): Ditto.
+ * include/private/gc_pmark.h (SET_MARK_BIT_EXIT_IF_SET): Remove
+ "mark_byte" local variable.
+ * include/private/gc_pmark.h (OR_WORD_EXIT_IF_SET): Add a comment
+ about that AO_or() is not used by GC unless USE_MARK_BITS
+ explicitly set.
+ * include/private/gc_priv.h (OR_WORD): Ditto.
+ * include/private/gc_pmark.h (INCR_MARKS): Remove trailing ';',
+ add parentheses.
+ * include/private/gc_priv.h (ONES): Define before use by
+ MAKE_COOLER.
+ * include/private/gc_priv.h (MARK_BITS_SZ): Define where used.
+ * include/private/gc_priv.h (OR_WORD): Don't define if
+ USE_MARK_BYTES.
+ * include/private/gcconfig.h (USE_MARK_BYTES); Remove duplicate
+ definition; simplify expression.
+
2011-04-22 Ivan Maidanski <ivmai@mail.ru>
* os_dep.c (GC_get_maps): Always close the file.
printf("\tUsing one mark ");
# if defined(USE_MARK_BYTES)
printf("byte");
-# elif defined(USE_MARK_BITS)
+# else
printf("bit");
# endif
printf(" per ");
}
/* Set mark bit, exit if it was already set. */
-
-#ifdef USE_MARK_BITS
+#ifdef USE_MARK_BYTES
+ /* There is a race here, and we may set */
+ /* the bit twice in the concurrent case. This can result in the */
+ /* object being pushed twice. But that's only a performance issue. */
+# define SET_MARK_BIT_EXIT_IF_SET(hhdr,bit_no,exit_label) \
+ { \
+ char * mark_byte_addr = (char *)hhdr -> hb_marks + (bit_no); \
+ if (*mark_byte_addr) goto exit_label; \
+ *mark_byte_addr = 1; \
+ }
+#else
# ifdef PARALLEL_MARK
+ /* This is used only if we explicitly set USE_MARK_BITS. */
/* The following may fail to exit even if the bit was already set. */
/* For our uses, that's benign: */
# define OR_WORD_EXIT_IF_SET(addr, bits, exit_label) \
OR_WORD_EXIT_IF_SET(mark_word_addr, (word)1 << modWORDSZ(bit_no), \
exit_label); \
}
-#endif /* USE_MARK_BITS */
-
-#if defined(I386) && defined(__GNUC__)
-# define LONG_MULT(hprod, lprod, x, y) { \
- __asm__ __volatile__("mull %2" : "=a"(lprod), "=d"(hprod) \
- : "g"(y), "0"(x)); \
- }
-#else /* No in-line X86 assembly code */
-# 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; \
- }
-#endif
-
-#ifdef USE_MARK_BYTES
- /* There is a race here, and we may set */
- /* the bit twice in the concurrent case. This can result in the */
- /* object being pushed twice. But that's only a performance issue. */
-# define SET_MARK_BIT_EXIT_IF_SET(hhdr,bit_no,exit_label) \
- { \
- char * mark_byte_addr = (char *)hhdr -> hb_marks + (bit_no); \
- char mark_byte = *mark_byte_addr; \
- if (mark_byte) goto exit_label; \
- *mark_byte_addr = 1; \
- }
-#endif /* USE_MARK_BYTES */
+#endif /* !USE_MARK_BYTES */
#ifdef PARALLEL_MARK
# define INCR_MARKS(hhdr) \
- AO_store(&(hhdr -> hb_n_marks), AO_load(&(hhdr -> hb_n_marks))+1);
+ AO_store(&hhdr->hb_n_marks, AO_load(&hhdr->hb_n_marks) + 1)
#else
-# define INCR_MARKS(hhdr) ++(hhdr -> hb_n_marks)
+# define INCR_MARKS(hhdr) (void)(++hhdr->hb_n_marks)
#endif
#ifdef ENABLE_TRACE
# define TRACE_TARGET(source, cmd)
#endif
+#if defined(I386) && defined(__GNUC__)
+# define LONG_MULT(hprod, lprod, x, y) { \
+ __asm__ __volatile__("mull %2" : "=a"(lprod), "=d"(hprod) \
+ : "g"(y), "0"(x)); \
+ }
+#else
+# 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; \
+ }
+#endif /* !I386 */
+
/* If the mark bit corresponding to current is not set, set it, and */
/* push the contents of the object on the mark stack. Current points */
/* to the beginning of the object. We rely on the fact that the */
# include "gc_locks.h"
#endif
+#define ONES ((word)(signed_word)(-1))
+
# ifdef STACK_GROWS_DOWN
# define COOLER_THAN >
# define HOTTER_THAN <
#define WORDSZ ((word)CPP_WORDSZ)
#define SIGNB ((word)1 << (WORDSZ-1))
#define BYTES_PER_WORD ((word)(sizeof (word)))
-#define ONES ((word)(signed_word)(-1))
#define divWORDSZ(n) ((n) >> LOGWL) /* divide n by size of word */
#if GRANULE_BYTES == 8
/* initial group of mark bits, and it is safe */
/* to allocate smaller header for large objects. */
-# ifdef USE_MARK_BYTES
-# define MARK_BITS_SZ (MARK_BITS_PER_HBLK + 1)
- /* Unlike the other case, this is in units of bytes. */
- /* Since we force doubleword alignment, we need at most one */
- /* mark bit per 2 words. But we do allocate and set one */
- /* extra mark bit to avoid an explicit check for the */
- /* partial object at the end of each block. */
-# else
-# define MARK_BITS_SZ (MARK_BITS_PER_HBLK/CPP_WORDSZ + 1)
-# endif
-
#ifdef PARALLEL_MARK
# include "atomic_ops.h"
typedef AO_t counter_t;
/* Without parallel marking, the count */
/* is accurate. */
# ifdef USE_MARK_BYTES
+# define MARK_BITS_SZ (MARK_BITS_PER_HBLK + 1)
+ /* Unlike the other case, this is in units of bytes. */
+ /* Since we force doubleword alignment, we need at most one */
+ /* mark bit per 2 words. But we do allocate and set one */
+ /* extra mark bit to avoid an explicit check for the */
+ /* partial object at the end of each block. */
union {
char _hb_marks[MARK_BITS_SZ];
/* The i'th byte is 1 if the object */
} _mark_byte_union;
# define hb_marks _mark_byte_union._hb_marks
# else
+# define MARK_BITS_SZ (MARK_BITS_PER_HBLK/CPP_WORDSZ + 1)
word hb_marks[MARK_BITS_SZ];
# endif /* !USE_MARK_BYTES */
};
/* with it. Only those corresponding to the beginning of an */
/* object are used. */
-/* Set mark bit correctly, even if mark bits may be concurrently */
-/* accessed. */
-#ifdef PARALLEL_MARK
-# define OR_WORD(addr, bits) AO_or((volatile AO_t *)(addr), (AO_t)(bits))
-#else
-# define OR_WORD(addr, bits) (void)(*(addr) |= (bits))
-#endif
-
/* Mark bit operations */
/*
# 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
+/* Set mark bit correctly, even if mark bits may be concurrently */
+/* accessed. */
+# ifdef PARALLEL_MARK
+ /* This is used only if we explicitly set USE_MARK_BITS. */
+# define OR_WORD(addr, bits) AO_or((volatile AO_t *)(addr), (AO_t)(bits))
+# else
+# define OR_WORD(addr, bits) (void)(*(addr) |= (bits))
+# endif
# define mark_bit_from_hdr(hhdr,n) \
(((hhdr)->hb_marks[divWORDSZ(n)] >> modWORDSZ(n)) & (word)1)
# define set_mark_bit_from_hdr(hhdr,n) \
# define ALIGNMENT 4
# endif
# if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) \
- && !defined(OPENBSD)
-# ifndef LINUX /* For now. */
-# define MPROTECT_VDB
-# endif
-# else
-# ifdef PARALLEL_MARK
-# define USE_MARK_BYTES
- /* Minimize compare-and-swap usage. */
-# endif
+ && !defined(OPENBSD) && !defined(LINUX) /* For now. */
+# define MPROTECT_VDB
# endif
# define STACK_GROWS_UP
# ifdef HPUX
# define IF_CANCEL(x) /* empty */
#endif
-#if !defined(USE_MARK_BITS) && !defined(USE_MARK_BYTES)
-# if defined(THREADS) && defined(PARALLEL_MARK)
-# define USE_MARK_BYTES
-# else
-# define USE_MARK_BITS
-# endif
+#if !defined(USE_MARK_BITS) && !defined(USE_MARK_BYTES) \
+ && defined(PARALLEL_MARK)
+ /* Minimize compare-and-swap usage. */
+# define USE_MARK_BYTES
#endif
#if defined(MSWINCE) && !defined(__CEGCC__) && !defined(NO_GETENV)
GC_INNER void GC_clear_hdr_marks(hdr *hhdr)
{
size_t last_bit = FINAL_MARK_BIT(hhdr -> hb_sz);
-
-# ifdef USE_MARK_BYTES
- BZERO(hhdr -> hb_marks, MARK_BITS_SZ);
- hhdr -> hb_marks[last_bit] = 1;
-# else
- BZERO(hhdr -> hb_marks, MARK_BITS_SZ*sizeof(word));
- set_mark_bit_from_hdr(hhdr, last_bit);
-# endif
+ BZERO(hhdr -> hb_marks, sizeof(hhdr->hb_marks));
+ set_mark_bit_from_hdr(hhdr, last_bit);
hhdr -> hb_n_marks = 0;
}
qcontents = (q)[3]; \
GC_PUSH_ONE_HEAP(qcontents, (q)+3); }
# endif
-#endif
+#endif /* !USE_MARK_BYTES && MARK_BIT_PER_GRANULE */
#ifdef USE_PUSH_MARKED_ACCELERATORS
/* Push all objects reachable from marked objects in the given block */