diff options
author | Jonathan Chambers <joncham@gmail.com> | 2019-10-03 17:24:41 +0300 |
---|---|---|
committer | Jonathan Chambers <joncham@gmail.com> | 2019-10-03 18:06:38 +0300 |
commit | 62b9f95bb31a8ec34f1471f6231a9e8b69a3c496 (patch) | |
tree | ccbc294a537318ec6018ec9d83841a7835e1d924 | |
parent | d962884ab8ae4e7b48d9f77b6512c6b580098dc3 (diff) |
Fix marking of value types too large to process in bulk (case 1188407).
-rw-r--r-- | vector_mlc.c | 167 |
1 files changed, 100 insertions, 67 deletions
diff --git a/vector_mlc.c b/vector_mlc.c index 6f9b08a1..ba5c28b5 100644 --- a/vector_mlc.c +++ b/vector_mlc.c @@ -141,74 +141,107 @@ GC_API void GC_CALL GC_init_gcj_vector (int mp_index, } #define ELEMENT_CHUNK_SIZE 256 -GC_API mse * GC_CALL - GC_gcj_vector_mark_proc (mse *mark_stack_ptr, GC_descr element_desc, word *start, word *end, int words_per_element) +GC_API mse *GC_CALL +GC_gcj_vector_mark_proc (mse *mark_stack_ptr, GC_descr element_desc, word *start, word *end, int words_per_element) { - /* create new descriptor that is shifted two bits to account - * for lack of object header. Descriptors for value types include - * the object header for boxed values */ - - /* remove tags */ - GC_descr element_desc_shifted = element_desc & ~(GC_DS_TAGS); - /* shift actual bits */ - element_desc_shifted = element_desc_shifted << 2; - /* shifted and unmasked desc to use for bulk processing */ - GC_descr element_desc_shifted_unmasked = element_desc_shifted; - /* add back tag to indicate descriptor is a bitmap */ - element_desc_shifted |= GC_DS_BITMAP; - - /* attempt to bulk process multiple elements with single descriptor */ - size_t elements_per_desc = (CPP_WORDSZ - GC_DS_TAG_BITS) / words_per_element; - - size_t remaining_elements = (end - start) / words_per_element; - size_t bulk_count = remaining_elements / elements_per_desc; - size_t remainder_count = remaining_elements % elements_per_desc; - - word *current = start; - - size_t i; - - // bulk - if (bulk_count) { - size_t bulk_stride = elements_per_desc * words_per_element; - - if (bulk_count > ELEMENT_CHUNK_SIZE) { - bulk_count = ELEMENT_CHUNK_SIZE; - /* clear remainder as we have more bulk to process next time */ - remainder_count = 0; - - /* only process chunk number of items */ - end = start + bulk_count * bulk_stride; - - mark_stack_ptr++; - mark_stack_ptr->mse_descr.w = GC_MAKE_PROC (GC_gcj_vector_mp_index, 1 /* continue processing */); - mark_stack_ptr->mse_start = (ptr_t)end; - } - - GC_descr bulk_desc = 0; - for (i = 0; i < elements_per_desc; ++i) { - bulk_desc |= element_desc_shifted_unmasked >> (i * words_per_element); - } - bulk_desc |= GC_DS_BITMAP; - - for (i = 0; i < bulk_count; ++i, current += bulk_stride) { - mark_stack_ptr++; - - mark_stack_ptr->mse_start = (ptr_t) (current); - mark_stack_ptr->mse_descr.w = bulk_desc; - } - } - - size_t remainder_stride = words_per_element; - // remainder - for (i = 0; i < remainder_count; ++i, current += remainder_stride) { - mark_stack_ptr++; - - mark_stack_ptr->mse_start = (ptr_t) (current); - mark_stack_ptr->mse_descr.w = element_desc_shifted; - } - - return (mark_stack_ptr); + /* create new descriptor that is shifted two bits to account + * for lack of object header. Descriptors for value types include + * the object header for boxed values */ + + /* remove tags */ + GC_descr element_desc_shifted = element_desc & ~(GC_DS_TAGS); + /* shift actual bits */ + element_desc_shifted = element_desc_shifted << 2; + /* shifted and unmasked desc to use for bulk processing */ + GC_descr element_desc_shifted_unmasked = element_desc_shifted; + /* add back tag to indicate descriptor is a bitmap */ + element_desc_shifted |= GC_DS_BITMAP; + + size_t remaining_elements = (end - start) / words_per_element; + + /* attempt to bulk process multiple elements with single descriptor */ + size_t elements_per_desc = (CPP_WORDSZ - GC_DS_TAG_BITS) / words_per_element; + + + /* setup bulk processing */ + if (elements_per_desc > 1) { + word *current = start; + size_t bulk_count = remaining_elements / elements_per_desc; + size_t remainder_count = remaining_elements % elements_per_desc; + + /* bulk processing */ + if (bulk_count) { + size_t bulk_stride = elements_per_desc * words_per_element; + GC_descr bulk_desc = 0; + size_t i; + for (i = 0; i < elements_per_desc; ++i) { + bulk_desc |= element_desc_shifted_unmasked >> (i * words_per_element); + } + bulk_desc |= GC_DS_BITMAP; + + if (bulk_count > ELEMENT_CHUNK_SIZE) { + bulk_count = ELEMENT_CHUNK_SIZE; + + /* only process chunk number of items */ + end = start + bulk_count * bulk_stride; + + remainder_count = 0; + + mark_stack_ptr++; + mark_stack_ptr->mse_descr.w = GC_MAKE_PROC (GC_gcj_vector_mp_index, 1 /* continue processing */); + mark_stack_ptr->mse_start = (ptr_t)end; + } + + while (bulk_count > 0) { + mark_stack_ptr++; + + mark_stack_ptr->mse_start = (ptr_t) (current); + mark_stack_ptr->mse_descr.w = bulk_desc; + + current += bulk_stride; + + bulk_count--; + } + } + + while (remainder_count > 0) { + mark_stack_ptr++; + + mark_stack_ptr->mse_start = (ptr_t) (current); + mark_stack_ptr->mse_descr.w = element_desc_shifted; + + current += words_per_element; + + remainder_count--; + } + } else { + size_t remainder_count = remaining_elements; + + if (remainder_count > ELEMENT_CHUNK_SIZE) { + remainder_count = ELEMENT_CHUNK_SIZE; + + /* only process chunk number of items */ + end = start + remainder_count * words_per_element; + + mark_stack_ptr++; + mark_stack_ptr->mse_descr.w = GC_MAKE_PROC (GC_gcj_vector_mp_index, 1 /* continue processing */); + mark_stack_ptr->mse_start = (ptr_t)end; + } + + word *current = start; + while (remainder_count > 0) { + mark_stack_ptr++; + + mark_stack_ptr->mse_start = (ptr_t) (current); + mark_stack_ptr->mse_descr.w = element_desc_shifted; + + current += words_per_element; + + remainder_count--; + } + } + + return (mark_stack_ptr); } #endif |