aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc/new_hblk.c
diff options
context:
space:
mode:
Diffstat (limited to 'boehm-gc/new_hblk.c')
-rw-r--r--boehm-gc/new_hblk.c253
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]);
}
-