diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2011-11-11 17:55:13 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-11-11 17:55:13 +0400 |
commit | f0713af4c1a68010e3bd4018212675b53769556a (patch) | |
tree | b7bfbfa62c4ef7cc631311251f1fa09c2426405f /fnlz_mlc.c | |
parent | a6915f17a34a0d636b08050ab1a34957d5c771d2 (diff) | |
download | bdwgc-f0713af4c1a68010e3bd4018212675b53769556a.tar.gz |
Rename (shorten name of) finalized_mlc.c to fnlz_mlc.c file
* finalized_mlc.c: Rename to fnlz_mlc.c file.
* BCC_MAKEFILE (XXXOBJS): Rename "finalized_mlc" to "fnlz_mlc".
* EMX_MAKEFILE (OBJS): Likewise.
* Makefile.am (libgc_la_SOURCES): Likewise.
* Makefile.direct (OBJS, CSRCS): Likewise.
* Makefile.dj (OBJS, CSRCS): Likewise.
* NT_MAKEFILE (OBJS): Likewise.
* NT_STATIC_THREADS_MAKEFILE (OBJS): Likewise.
* NT_X64_STATIC_THREADS_MAKEFILE (OBJS): Likewise.
* NT_X64_THREADS_MAKEFILE (OBJS): Likewise.
* OS2_MAKEFILE (OBJS): Likewise.
* PCR-Makefile (COBJ, CSRC): Likewise.
* SMakefile.amiga (OBJS, finalized_mlc.o): Likewise.
* WCC_MAKEFILE (OBJS): Likewise.
* digimars.mak (OBJS, finalized_mlc.o): Likewise.
* extra/gc.c: Likewise.
* gc.mak: Likewise.
* thread_local_alloc.c: Likewise.
* windows-untested/vc60/gc.dsp (SOURCE): Likewise.
* windows-untested/vc60/libgc.dsp (SOURCE): Likewise.
* windows-untested/vc70/gc.vcproj: Likewise.
* windows-untested/vc70/libgc.vcproj: Likewise.
* windows-untested/vc70/libgcmt.vcproj: Likewise.
* windows-untested/vc71/gc.vcproj: Likewise.
* windows-untested/vc71/libgc.vcproj: Likewise.
* windows-untested/vc71/libgcmt.vcproj: Likewise.
Diffstat (limited to 'fnlz_mlc.c')
-rw-r--r-- | fnlz_mlc.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/fnlz_mlc.c b/fnlz_mlc.c new file mode 100644 index 00000000..6aea12d5 --- /dev/null +++ b/fnlz_mlc.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2011 by Hewlett-Packard Company. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ + +#include "private/gc_priv.h" + +#ifdef ENABLE_DISCLAIM + +#include "gc_disclaim.h" + +#ifdef THREAD_LOCAL_ALLOC +# include "private/thread_local_alloc.h" +#else + STATIC ptr_t * GC_finalized_objfreelist = NULL; +#endif /* !THREAD_LOCAL_ALLOC */ + +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) { + /* [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 */ + /* on such fragments are always even (a link to the next */ + /* fragment, or NULL). If it is desirable to have a finalizer */ + /* 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); + } + return 0; +} + +static GC_bool done_init = FALSE; + +GC_API void GC_CALL GC_init_finalized_malloc(void) +{ + DCL_LOCK_STATE; + + GC_init(); /* In case it's not already done. */ + LOCK(); + if (done_init) { + UNLOCK(); + return; + } + done_init = TRUE; + + GC_finalized_objfreelist = (ptr_t *)GC_new_free_list_inner(); + GC_finalized_kind = GC_new_kind_inner((void **)GC_finalized_objfreelist, + GC_DS_LENGTH, TRUE, TRUE); + GC_register_disclaim_proc(GC_finalized_kind, GC_finalized_disclaim, + NULL, TRUE); + UNLOCK(); +} + +#ifdef THREAD_LOCAL_ALLOC + STATIC void * GC_core_finalized_malloc(size_t lb, + struct GC_finalizer_closure *fclos) +#else + GC_API void * GC_CALL GC_finalized_malloc(size_t lb, + struct GC_finalizer_closure *fclos) +#endif +{ + ptr_t op; + ptr_t *opp; + word lg; + DCL_LOCK_STATE; + + lb += sizeof(void *); + GC_ASSERT(done_init); + if (EXPECT(SMALL_OBJ(lb), 1)) { + lg = GC_size_map[lb]; + opp = &GC_finalized_objfreelist[lg]; + LOCK(); + if (EXPECT((op = *opp) == 0, 0)) { + UNLOCK(); + op = GC_generic_malloc((word)lb, GC_finalized_kind); + } else { + *opp = obj_link(op); + obj_link(op) = 0; + GC_bytes_allocd += GRANULES_TO_BYTES(lg); + UNLOCK(); + } + } else { + op = GC_generic_malloc((word)lb, GC_finalized_kind); + } + *(void **)op = (ptr_t)fclos + 1; /* See [1] */ + return GC_clear_stack(op + sizeof(void *)); +} + +#ifdef THREAD_LOCAL_ALLOC + GC_API void * GC_CALL GC_finalized_malloc(size_t client_lb, + struct GC_finalizer_closure *fclos) + { + size_t lb = client_lb + sizeof(void *); + size_t lg = ROUNDED_UP_GRANULES(lb); + GC_tlfs tsd; + void *result; + void **tiny_fl, **my_fl, *my_entry; + void *next; + + if (GC_EXPECT(lg >= GC_TINY_FREELISTS, 0)) + return GC_core_finalized_malloc(client_lb, fclos); + + tsd = GC_getspecific(GC_thread_key); + tiny_fl = tsd->finalized_freelists; + my_fl = tiny_fl + lg; + my_entry = *my_fl; + while (GC_EXPECT((word)my_entry + <= DIRECT_GRANULES + GC_TINY_FREELISTS + 1, 0)) { + if ((word)my_entry - 1 < DIRECT_GRANULES) { + *my_fl = (ptr_t)my_entry + lg + 1; + return GC_core_finalized_malloc(client_lb, fclos); + } else { + GC_generic_malloc_many(GC_RAW_BYTES_FROM_INDEX(lg), + GC_finalized_kind, my_fl); + my_entry = *my_fl; + if (my_entry == 0) + return GC_oom_fn(lb); + } + } + + next = obj_link(my_entry); + result = (void *)my_entry; + *my_fl = next; + *(void **)result = (ptr_t)fclos + 1; + PREFETCH_FOR_WRITE(next); + return (void **)result + 1; + } +#endif /* THREAD_LOCAL_ALLOC */ + +#endif /* ENABLE_DISCLAIM */ |