diff options
Diffstat (limited to 'boehm-gc/new_hblk.c')
-rw-r--r-- | boehm-gc/new_hblk.c | 253 |
1 files changed, 92 insertions, 161 deletions
diff --git a/boehm-gc/new_hblk.c b/boehm-gc/new_hblk.c index e5580e4ca21..e2992d445cd 100644 --- a/boehm-gc/new_hblk.c +++ b/boehm-gc/new_hblk.c @@ -11,253 +11,184 @@ * 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. - * - * This file contains the functions: - * ptr_t GC_build_flXXX(h, old_fl) - * void GC_new_hblk(n) */ -/* Boehm, May 19, 1994 2:09 pm PDT */ - -# include <stdio.h> -# include "private/gc_priv.h" +#include "private/gc_priv.h" -#ifndef SMALL_CONFIG /* - * Build a free list for size 1 objects inside hblk h. Set the last link to - * be ofl. Return a pointer tpo the first free list entry. + * This file contains the functions: + * ptr_t GC_build_flXXX(h, old_fl) + * void GC_new_hblk(size) */ -ptr_t GC_build_fl1(h, ofl) -struct hblk *h; -ptr_t ofl; -{ - register word * p = h -> hb_body; - register word * lim = (word *)(h + 1); - - p[0] = (word)ofl; - p[1] = (word)(p); - p[2] = (word)(p+1); - p[3] = (word)(p+2); - p += 4; - for (; p < lim; p += 4) { - p[0] = (word)(p-1); - p[1] = (word)(p); - p[2] = (word)(p+1); - p[3] = (word)(p+2); - }; - return((ptr_t)(p-1)); -} -/* The same for size 2 cleared objects */ -ptr_t GC_build_fl_clear2(h, ofl) -struct hblk *h; -ptr_t ofl; -{ - register word * p = h -> hb_body; - register word * lim = (word *)(h + 1); - +#include <stdio.h> + +#ifndef SMALL_CONFIG + /* Build a free list for size 2 (words) cleared objects inside */ + /* hblk h. Set the last link to be ofl. Return a pointer tpo the */ + /* first free list entry. */ + STATIC ptr_t GC_build_fl_clear2(struct hblk *h, ptr_t ofl) + { + word * p = (word *)(h -> hb_body); + word * lim = (word *)(h + 1); + p[0] = (word)ofl; p[1] = 0; p[2] = (word)p; p[3] = 0; p += 4; - for (; p < lim; p += 4) { + for (; (word)p < (word)lim; p += 4) { p[0] = (word)(p-2); p[1] = 0; p[2] = (word)p; p[3] = 0; }; return((ptr_t)(p-2)); -} + } -/* The same for size 3 cleared objects */ -ptr_t GC_build_fl_clear3(h, ofl) -struct hblk *h; -ptr_t ofl; -{ - register word * p = h -> hb_body; - register word * lim = (word *)(h + 1) - 2; - - p[0] = (word)ofl; - p[1] = 0; - p[2] = 0; - p += 3; - for (; p < lim; p += 3) { - p[0] = (word)(p-3); - p[1] = 0; - p[2] = 0; - }; - return((ptr_t)(p-3)); -} + /* The same for size 4 cleared objects. */ + STATIC ptr_t GC_build_fl_clear4(struct hblk *h, ptr_t ofl) + { + word * p = (word *)(h -> hb_body); + word * lim = (word *)(h + 1); -/* The same for size 4 cleared objects */ -ptr_t GC_build_fl_clear4(h, ofl) -struct hblk *h; -ptr_t ofl; -{ - register word * p = h -> hb_body; - register word * lim = (word *)(h + 1); - p[0] = (word)ofl; p[1] = 0; p[2] = 0; p[3] = 0; p += 4; - for (; p < lim; p += 4) { - PREFETCH_FOR_WRITE((ptr_t)(p+64)); + for (; (word)p < (word)lim; p += 4) { + PREFETCH_FOR_WRITE((ptr_t)(p+64)); p[0] = (word)(p-4); p[1] = 0; - CLEAR_DOUBLE(p+2); + CLEAR_DOUBLE(p+2); }; return((ptr_t)(p-4)); -} + } + + /* The same for size 2 uncleared objects. */ + STATIC ptr_t GC_build_fl2(struct hblk *h, ptr_t ofl) + { + word * p = (word *)(h -> hb_body); + word * lim = (word *)(h + 1); -/* The same for size 2 uncleared objects */ -ptr_t GC_build_fl2(h, ofl) -struct hblk *h; -ptr_t ofl; -{ - register word * p = h -> hb_body; - register word * lim = (word *)(h + 1); - p[0] = (word)ofl; p[2] = (word)p; p += 4; - for (; p < lim; p += 4) { + for (; (word)p < (word)lim; p += 4) { p[0] = (word)(p-2); p[2] = (word)p; }; return((ptr_t)(p-2)); -} + } + + /* The same for size 4 uncleared objects. */ + STATIC ptr_t GC_build_fl4(struct hblk *h, ptr_t ofl) + { + word * p = (word *)(h -> hb_body); + word * lim = (word *)(h + 1); -/* The same for size 4 uncleared objects */ -ptr_t GC_build_fl4(h, ofl) -struct hblk *h; -ptr_t ofl; -{ - register word * p = h -> hb_body; - register word * lim = (word *)(h + 1); - p[0] = (word)ofl; p[4] = (word)p; p += 8; - for (; p < lim; p += 8) { - PREFETCH_FOR_WRITE((ptr_t)(p+64)); + for (; (word)p < (word)lim; p += 8) { + PREFETCH_FOR_WRITE((ptr_t)(p+64)); p[0] = (word)(p-4); p[4] = (word)p; }; return((ptr_t)(p-4)); -} - + } #endif /* !SMALL_CONFIG */ - -/* Build a free list for objects of size sz inside heap block h. */ -/* Clear objects inside h if clear is set. Add list to the end of */ -/* the free list we build. Return the new free list. */ -/* This could be called without the main GC lock, if we ensure that */ -/* there is no concurrent collection which might reclaim objects that */ -/* we have not yet allocated. */ -ptr_t GC_build_fl(h, sz, clear, list) -struct hblk *h; -word sz; -GC_bool clear; -ptr_t list; +/* Build a free list for objects of size sz inside heap block h. */ +/* Clear objects inside h if clear is set. Add list to the end of */ +/* the free list we build. Return the new free list. */ +/* This could be called without the main GC lock, if we ensure that */ +/* there is no concurrent collection which might reclaim objects that */ +/* we have not yet allocated. */ +GC_INNER ptr_t GC_build_fl(struct hblk *h, size_t sz, GC_bool clear, + ptr_t list) { word *p, *prev; - word *last_object; /* points to last object in new hblk */ + word *last_object; /* points to last object in new hblk */ - /* Do a few prefetches here, just because its cheap. */ - /* If we were more serious about it, these should go inside */ - /* the loops. But write prefetches usually don't seem to */ - /* matter much. */ + /* Do a few prefetches here, just because its cheap. */ + /* If we were more serious about it, these should go inside */ + /* the loops. But write prefetches usually don't seem to */ + /* matter much. */ PREFETCH_FOR_WRITE((ptr_t)h); PREFETCH_FOR_WRITE((ptr_t)h + 128); PREFETCH_FOR_WRITE((ptr_t)h + 256); PREFETCH_FOR_WRITE((ptr_t)h + 378); - /* Handle small objects sizes more efficiently. For larger objects */ - /* the difference is less significant. */ -# ifndef SMALL_CONFIG +# ifndef SMALL_CONFIG + /* Handle small objects sizes more efficiently. For larger objects */ + /* the difference is less significant. */ switch (sz) { - case 1: return GC_build_fl1(h, list); case 2: if (clear) { - return GC_build_fl_clear2(h, list); - } else { - return GC_build_fl2(h, list); - } - case 3: if (clear) { - return GC_build_fl_clear3(h, list); - } else { - /* It's messy to do better than the default here. */ - break; - } + return GC_build_fl_clear2(h, list); + } else { + return GC_build_fl2(h, list); + } case 4: if (clear) { - return GC_build_fl_clear4(h, list); - } else { - return GC_build_fl4(h, list); - } + return GC_build_fl_clear4(h, list); + } else { + return GC_build_fl4(h, list); + } default: - break; + break; } -# endif /* !SMALL_CONFIG */ - +# endif /* !SMALL_CONFIG */ + /* Clear the page if necessary. */ if (clear) BZERO(h, HBLKSIZE); - + /* Add objects to free list */ - p = &(h -> hb_body[sz]); /* second object in *h */ - prev = &(h -> hb_body[0]); /* One object behind p */ + p = (word *)(h -> hb_body) + sz; /* second object in *h */ + prev = (word *)(h -> hb_body); /* One object behind p */ last_object = (word *)((char *)h + HBLKSIZE); last_object -= sz; - /* Last place for last object to start */ + /* Last place for last object to start */ /* make a list of all objects in *h with head as last object */ - while (p <= last_object) { + while ((word)p <= (word)last_object) { /* current object's link points to last object */ obj_link(p) = (ptr_t)prev; - prev = p; - p += sz; + prev = p; + p += sz; } - p -= sz; /* p now points to last object */ + p -= sz; /* p now points to last object */ - /* - * put p (which is now head of list of objects in *h) as first - * pointer in the appropriate free list for this size. - */ - obj_link(h -> hb_body) = list; - return ((ptr_t)p); + /* Put p (which is now head of list of objects in *h) as first */ + /* pointer in the appropriate free list for this size. */ + *(ptr_t *)h = list; + return ((ptr_t)p); } /* - * Allocate a new heapblock for small objects of size n. + * Allocate a new heapblock for small objects of size gran granules. * Add all of the heapblock's objects to the free list for objects * of that size. * Set all mark bits if objects are uncollectable. * Will fail to do anything if we are out of memory. */ -void GC_new_hblk(sz, kind) -register word sz; -int kind; +GC_INNER void GC_new_hblk(size_t gran, int kind) { - register struct hblk *h; /* the new heap block */ - register GC_bool clear = GC_obj_kinds[kind].ok_init; + struct hblk *h; /* the new heap block */ + GC_bool clear = GC_obj_kinds[kind].ok_init; + + GC_STATIC_ASSERT((sizeof (struct hblk)) == HBLKSIZE); -# ifdef PRINTSTATS - if ((sizeof (struct hblk)) > HBLKSIZE) { - ABORT("HBLK SZ inconsistency"); - } -# endif if (GC_debugging_started) clear = TRUE; /* Allocate a new heap block */ - h = GC_allochblk(sz, kind, 0); + h = GC_allochblk(GRANULES_TO_BYTES(gran), kind, 0); if (h == 0) return; /* Mark all objects if appropriate. */ if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h)); /* Build the free list */ - GC_obj_kinds[kind].ok_freelist[sz] = - GC_build_fl(h, sz, clear, GC_obj_kinds[kind].ok_freelist[sz]); + GC_obj_kinds[kind].ok_freelist[gran] = + GC_build_fl(h, GRANULES_TO_WORDS(gran), clear, + GC_obj_kinds[kind].ok_freelist[gran]); } - |