summaryrefslogtreecommitdiff
path: root/fnlz_mlc.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2011-11-11 17:55:13 +0400
committerIvan Maidanski <ivmai@mail.ru>2011-11-11 17:55:13 +0400
commitf0713af4c1a68010e3bd4018212675b53769556a (patch)
treeb7bfbfa62c4ef7cc631311251f1fa09c2426405f /fnlz_mlc.c
parenta6915f17a34a0d636b08050ab1a34957d5c771d2 (diff)
downloadbdwgc-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.c146
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 */