diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-06-09 08:24:53 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-06-09 08:24:53 +0300 |
commit | 1e6c80be32fd95f3c2015db0e76a6bae99d5ba0c (patch) | |
tree | 730e1abbc43148a61fc8e55a153fb9cda5c2bf3f /typd_mlc.c | |
parent | 85e15f54e4d7f326200562ba7f9ca4a96e420164 (diff) | |
download | bdwgc-1e6c80be32fd95f3c2015db0e76a6bae99d5ba0c.tar.gz |
Fix non-atomic write to *lp in GC_calloc_explicitly_typed
(fix of commit 4e020ef3c)
Issue #449 (bdwgc).
* typd_mlc.c (LeafDescriptor.ld_size, LeafDescriptor.ld_nelements,
ComplexArrayDescriptor.ad_nelements): Change type from size_t to word.
* typd_mlc.c (GC_make_leaf_descriptor): Change type of size and
nelements arguments from size_t to word.
* typd_mlc.c [AO_HAVE_store] (GC_calloc_explicitly_typed): Use AO_store
to set fields of *lp.
Diffstat (limited to 'typd_mlc.c')
-rw-r--r-- | typd_mlc.c | 25 |
1 files changed, 17 insertions, 8 deletions
@@ -59,9 +59,9 @@ STATIC int GC_array_kind = 0; struct LeafDescriptor { /* Describes simple array. */ word ld_tag; # define LEAF_TAG 1 - size_t ld_size; /* bytes per element */ + word ld_size; /* Bytes per element; */ /* multiple of ALIGNMENT. */ - size_t ld_nelements; /* Number of elements. */ + word ld_nelements; /* Number of elements. */ GC_descr ld_descriptor; /* A simple length, bitmap, */ /* or procedure descriptor. */ }; @@ -69,7 +69,7 @@ struct LeafDescriptor { /* Describes simple array. */ struct ComplexArrayDescriptor { word ad_tag; # define ARRAY_TAG 2 - size_t ad_nelements; + word ad_nelements; union ComplexDescriptor * ad_element_descr; }; @@ -168,8 +168,8 @@ STATIC GC_descr GC_double_descr(GC_descr descriptor, size_t nwords) return descriptor; } -STATIC complex_descriptor *GC_make_leaf_descriptor(size_t size, - size_t nelements, +STATIC complex_descriptor *GC_make_leaf_descriptor(word size, + word nelements, GC_descr descriptor) { complex_descriptor *result = (complex_descriptor *) @@ -662,16 +662,25 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_calloc_explicitly_typed(size_t n, return NULL; nwords = GRANULES_TO_WORDS(BYTES_TO_GRANULES(GC_size(op))); if (descr_type == LEAF) { - /* Set up the descriptor inside the object itself. */ - volatile struct LeafDescriptor * lp = + /* Set up the descriptor inside the object itself. */ + volatile struct LeafDescriptor * lp = (struct LeafDescriptor *)((word *)op + nwords - (BYTES_TO_WORDS(sizeof(struct LeafDescriptor)) + 1)); +# ifdef AO_HAVE_store + AO_store((volatile AO_t *)&(lp -> ld_tag), LEAF_TAG); + AO_store((volatile AO_t *)&(lp -> ld_size), (AO_t)leaf.ld_size); + AO_store((volatile AO_t *)&(lp -> ld_nelements), + (AO_t)leaf.ld_nelements); + AO_store((volatile AO_t *)&(lp -> ld_descriptor), + (AO_t)leaf.ld_descriptor); +# else lp -> ld_tag = LEAF_TAG; lp -> ld_size = leaf.ld_size; lp -> ld_nelements = leaf.ld_nelements; lp -> ld_descriptor = leaf.ld_descriptor; - set_complex_descr(op, nwords, lp); +# endif + set_complex_descr(op, nwords, lp); } else { # ifndef GC_NO_FINALIZATION set_complex_descr(op, nwords, complex_descr); |