diff options
author | Petter Urkedal <paurkedal@gmail.com> | 2012-01-17 04:51:35 +0800 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-01-18 14:47:24 +0800 |
commit | 63fd11df9468ac94373ba74e7bd4a97b9cc4044b (patch) | |
tree | 5dc088f624b53ac2375f4b9e4a31b7c9a3d3b35c /fnlz_mlc.c | |
parent | 293d927f27280b8e371384dd530d5df3e8536672 (diff) | |
download | bdwgc-63fd11df9468ac94373ba74e7bd4a97b9cc4044b.tar.gz |
Move finalizer closure to the end of objects.
* fnlz_mlc.c: Move finalizer closure for finalized object kinds to the end
of objects. This way, we don't require all interior pointers, and GC_base
returns the expected address.
* tests/disclaim_test.c: Improve test coverage.
Diffstat (limited to 'fnlz_mlc.c')
-rw-r--r-- | fnlz_mlc.c | 21 |
1 files changed, 13 insertions, 8 deletions
@@ -29,8 +29,11 @@ STATIC int GC_finalized_kind = 0; STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj, void *cd GC_ATTR_UNUSED) { - struct GC_finalizer_closure *fc = *(void **)obj; - if (((word)fc & 1) != 0) { + void **fc_addr; + struct GC_finalizer_closure *fc; + fc_addr = &((void **)obj)[GC_size(obj) / sizeof(void *) - 1]; + fc = *fc_addr; + if (fc != NULL) { /* [1] The disclaim function may be passed fragments from the */ /* free-list, on which it should not run finalization. */ /* To recognize this case, we use the fact that the first word */ @@ -39,8 +42,8 @@ STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj, /* which does not use the first word for storing finalization */ /* info, GC_reclaim_with_finalization must be extended to clear */ /* fragments so that the assumption holds for the selected word. */ - fc = (void *)((word)fc & ~(word)1); - (*fc->proc)((void **)obj + 1, fc->cd); + (*fc->proc)(obj, fc->cd); + *fc_addr = NULL; } return 0; } @@ -95,11 +98,12 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) GC_bytes_allocd += GRANULES_TO_BYTES(lg); UNLOCK(); } + ((void **)op)[GRANULES_TO_WORDS(lg) - 1] = fclos; } else { op = GC_generic_malloc((word)lb, GC_finalized_kind); + ((void **)op)[GC_size(op) / sizeof(void *) - 1] = fclos; } - *(void **)op = (ptr_t)fclos + 1; /* See [1] */ - return GC_clear_stack(op + sizeof(void *)); + return GC_clear_stack(op); } #ifdef THREAD_LOCAL_ALLOC @@ -143,9 +147,10 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) next = obj_link(my_entry); result = (void *)my_entry; *my_fl = next; - *(void **)result = (ptr_t)fclos + 1; + obj_link(result) = 0; + ((void **)result)[GRANULES_TO_WORDS(lg) - 1] = fclos; PREFETCH_FOR_WRITE(next); - return (void **)result + 1; + return result; } #endif /* THREAD_LOCAL_ALLOC */ |