From: ivmai Date: Sat, 23 Apr 2011 08:51:53 +0000 (+0000) Subject: 2011-04-23 Ivan Maidanski X-Git-Tag: gc7_2alpha6~54 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f88d2556bba359dcf086600e625fe2a33313123;p=gc 2011-04-23 Ivan Maidanski * 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. --- diff --git a/ChangeLog b/ChangeLog index a61a85ff..8fa4db2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2011-04-23 Ivan Maidanski + + * 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 * os_dep.c (GC_get_maps): Always close the file. diff --git a/extra/setjmp_t.c b/extra/setjmp_t.c index 5f4519b2..0952fb03 100644 --- a/extra/setjmp_t.c +++ b/extra/setjmp_t.c @@ -112,7 +112,7 @@ int main(void) printf("\tUsing one mark "); # if defined(USE_MARK_BYTES) printf("byte"); -# elif defined(USE_MARK_BITS) +# else printf("bit"); # endif printf(" per "); diff --git a/include/private/gc_pmark.h b/include/private/gc_pmark.h index 05b082b4..d99e0b7f 100644 --- a/include/private/gc_pmark.h +++ b/include/private/gc_pmark.h @@ -164,9 +164,19 @@ exit_label: ; \ } /* 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) \ @@ -192,40 +202,13 @@ 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 @@ -238,6 +221,20 @@ exit_label: ; \ # 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 */ diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 7168c147..ad6699e9 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -172,6 +172,8 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ # include "gc_locks.h" #endif +#define ONES ((word)(signed_word)(-1)) + # ifdef STACK_GROWS_DOWN # define COOLER_THAN > # define HOTTER_THAN < @@ -579,7 +581,6 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc; #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 @@ -768,17 +769,6 @@ typedef word page_hash_table[PHT_SIZE]; /* 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; @@ -860,6 +850,12 @@ struct hblkhdr { /* 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 */ @@ -872,6 +868,7 @@ struct hblkhdr { } _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 */ }; @@ -1335,14 +1332,6 @@ struct GC_traced_stack_sect_s { /* 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 */ /* @@ -1357,6 +1346,14 @@ struct GC_traced_stack_sect_s { # 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) \ diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index ec5e96ed..894f31d6 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -1576,15 +1576,8 @@ # 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 @@ -2515,12 +2508,10 @@ # 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) diff --git a/mark.c b/mark.c index deb3cdf7..99fa4327 100644 --- a/mark.c +++ b/mark.c @@ -144,14 +144,8 @@ GC_INNER GC_bool GC_collection_in_progress(void) 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; } @@ -1570,7 +1564,7 @@ GC_INNER void GC_push_all_stack(ptr_t bottom, ptr_t top) 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 */