diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2012-01-29 22:52:30 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-01-29 22:52:30 +0400 |
commit | 9ef4c276203929afd9a9e4c9796f2a04efbb740c (patch) | |
tree | 348572e0ac62f0ca4541d3fb608cedd7c471a44b /mark.c | |
parent | 0589e7c42dc7c884c49081f829309ecccd1c63f0 (diff) | |
download | bdwgc-9ef4c276203929afd9a9e4c9796f2a04efbb740c.tar.gz |
Use union of AO_t and word for mse_descr to avoid type casting
(which breaks 'strict-aliasing' compiler optimization)
* include/private/gc_pmark.h (GC_ms_entry): Change type of mse_descr
from word to word_ptr_ao_u.
* include/private/gc_pmark.h (GC_mark_stack_top): Add FIXME.
* include/private/gc_pmark.h (OR_WORD_EXIT_IF_SET): Add 'volatile'
keyword to type cast for AO_or argument.
* include/private/gc_priv.h (counter_t): Add 'volatile' in case of
defining as AO_t (replace typedef with a macro).
* include/private/gc_priv.h (word_ptr_ao_u): New union type.
* include/private/gc_pmark.h (PUSH_OBJ): Add ".w" suffix to mse_descr.
* mark.c (GC_mark_from, GC_steal_mark_stack, GC_push_all): Likewise.
* mark.c (GC_steal_mark_stack): Use "ao" element of union to load and
clear mse_descr atomically; remove pointer type casts.
Diffstat (limited to 'mark.c')
-rw-r--r-- | mark.c | 20 |
1 files changed, 10 insertions, 10 deletions
@@ -645,7 +645,7 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, # endif { current_p = mark_stack_top -> mse_start; - descr = mark_stack_top -> mse_descr; + descr = mark_stack_top -> mse_descr.w; retry: /* current_p and descr describe the current object. */ /* *mark_stack_top is vacant. */ @@ -675,7 +675,7 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, && mark_stack_top < mark_stack_limit - 1) { int new_size = (descr/2) & ~(sizeof(word)-1); mark_stack_top -> mse_start = current_p; - mark_stack_top -> mse_descr = new_size + sizeof(word); + mark_stack_top -> mse_descr.w = new_size + sizeof(word); /* makes sure we handle */ /* misaligned pointers. */ mark_stack_top++; @@ -693,8 +693,8 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, # endif /* PARALLEL_MARK */ mark_stack_top -> mse_start = limit = current_p + WORDS_TO_BYTES(SPLIT_RANGE_WORDS-1); - mark_stack_top -> mse_descr = - descr - WORDS_TO_BYTES(SPLIT_RANGE_WORDS-1); + mark_stack_top -> mse_descr.w = + descr - WORDS_TO_BYTES(SPLIT_RANGE_WORDS-1); # ifdef ENABLE_TRACE if (GC_trace_addr >= current_p && GC_trace_addr < current_p + descr) { @@ -915,17 +915,17 @@ STATIC mse * GC_steal_mark_stack(mse * low, mse * high, mse * local, GC_ASSERT(high >= low-1 && (word)(high - low + 1) <= GC_mark_stack_size); for (p = low; p <= high && i <= max; ++p) { - word descr = AO_load((volatile AO_t *) &(p -> mse_descr)); + word descr = (word)AO_load(&p->mse_descr.ao); if (descr != 0) { /* Must be ordered after read of descr: */ - AO_store_release_write((volatile AO_t *) &(p -> mse_descr), 0); + AO_store_release_write(&p->mse_descr.ao, 0); /* More than one thread may get this entry, but that's only */ /* a minor performance problem. */ ++top; - top -> mse_descr = descr; + top -> mse_descr.w = descr; top -> mse_start = p -> mse_start; - GC_ASSERT((top -> mse_descr & GC_DS_TAGS) != GC_DS_LENGTH || - top -> mse_descr < (word)GC_greatest_plausible_heap_addr + GC_ASSERT((top->mse_descr.w & GC_DS_TAGS) != GC_DS_LENGTH || + top->mse_descr.w < (word)GC_greatest_plausible_heap_addr - (word)GC_least_plausible_heap_addr); /* If this is a big object, count it as */ /* size/256 + 1 objects. */ @@ -1276,7 +1276,7 @@ GC_INNER void GC_push_all(ptr_t bottom, ptr_t top) length &= ~GC_DS_TAGS; # endif GC_mark_stack_top -> mse_start = bottom; - GC_mark_stack_top -> mse_descr = length; + GC_mark_stack_top -> mse_descr.w = length; } #ifndef GC_DISABLE_INCREMENTAL |