diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2012-01-18 08:51:16 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-01-18 13:20:45 +0400 |
commit | 14175912b9a31dd4dc19402743f6ca74e3d3b4e0 (patch) | |
tree | a771fe5aab5e264c66d297bd1103548140217f53 /fnlz_mlc.c | |
parent | eed89a623b65d6223e5240ba6444e7c7d71799be (diff) | |
download | bdwgc-14175912b9a31dd4dc19402743f6ca74e3d3b4e0.tar.gz |
Fix GC_finalized_malloc for out-of-memory case (and for missing
'const' qualifier)
* fnlz_mlc.c (GC_finalized_disclaim): Add 'const' qualifier for "fc"
pointer.
* fnlz_mlc.c (GC_core_finalized_malloc, GC_finalized_malloc): Cast
"op" to 'const' pointer on "fclos" storing.
* fnlz_mlc.c (GC_finalized_malloc): Use GC_get_oom_fn() instead of
locked read of GC_oom_fn.
* fnlz_mlc.c (GC_core_finalized_malloc): Test GC_generic_malloc result
for NULL (return NULL in this case).
* fnlz_mlc.c (GC_core_finalized_malloc): Add assertion on GC_size
returned value (at least just to outline that it might be bigger than
"lb" value).
Diffstat (limited to 'fnlz_mlc.c')
-rw-r--r-- | fnlz_mlc.c | 27 |
1 files changed, 16 insertions, 11 deletions
@@ -30,7 +30,8 @@ STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj, void *cd GC_ATTR_UNUSED) { void **fc_addr; - struct GC_finalizer_closure *fc; + const struct GC_finalizer_closure *fc; + fc_addr = &((void **)obj)[GC_size(obj) / sizeof(void *) - 1]; fc = *fc_addr; if (fc != NULL) { @@ -89,19 +90,28 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) lg = GC_size_map[lb]; opp = &GC_finalized_objfreelist[lg]; LOCK(); - if (EXPECT((op = *opp) == 0, FALSE)) { + op = *opp; + if (EXPECT(0 == op, FALSE)) { UNLOCK(); op = GC_generic_malloc((word)lb, GC_finalized_kind); + if (NULL == op) + return NULL; } else { *opp = obj_link(op); obj_link(op) = 0; GC_bytes_allocd += GRANULES_TO_BYTES(lg); UNLOCK(); } - ((void **)op)[GRANULES_TO_WORDS(lg) - 1] = fclos; + ((const void **)op)[GRANULES_TO_WORDS(lg) - 1] = fclos; } else { + size_t op_sz; + op = GC_generic_malloc((word)lb, GC_finalized_kind); - ((void **)op)[GC_size(op) / sizeof(void *) - 1] = fclos; + if (NULL == op) + return NULL; + op_sz = GC_size(op); + GC_ASSERT(op_sz >= lb); + ((const void **)op)[op_sz / sizeof(void *) - 1] = fclos; } return GC_clear_stack(op); } @@ -134,12 +144,7 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) GC_finalized_kind, my_fl); my_entry = *my_fl; if (my_entry == 0) { - GC_oom_func oom_fn; - - LOCK(); - oom_fn = GC_oom_fn; - UNLOCK(); - return((*oom_fn)(lb)); + return (*GC_get_oom_fn())(lb); } } } @@ -148,7 +153,7 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) result = (void *)my_entry; *my_fl = next; obj_link(result) = 0; - ((void **)result)[GRANULES_TO_WORDS(lg) - 1] = fclos; + ((const void **)result)[GRANULES_TO_WORDS(lg) - 1] = fclos; PREFETCH_FOR_WRITE(next); return result; } |