# include <stdio.h>
# include "private/gc_priv.h"
#ifndef SMALL_CONFIG
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));
}
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);
p[0] = (word)ofl;
p[1] = 0;
p[2] = (word)p;
p[3] = 0;
p += 4;
for (; p < lim; p += 4) {
p[0] = (word)(p-2);
p[1] = 0;
p[2] = (word)p;
p[3] = 0;
};
return((ptr_t)(p-2));
}
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));
}
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));
p[0] = (word)(p-4);
p[1] = 0;
CLEAR_DOUBLE(p+2);
};
return((ptr_t)(p-4));
}
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) {
p[0] = (word)(p-2);
p[2] = (word)p;
};
return((ptr_t)(p-2));
}
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));
p[0] = (word)(p-4);
p[4] = (word)p;
};
return((ptr_t)(p-4));
}
#endif
ptr_t GC_build_fl(h, sz, clear, list)
struct hblk *h;
word sz;
GC_bool clear;
ptr_t list;
{
word *p, *prev;
word *last_object;
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);
# ifndef SMALL_CONFIG
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 {
break;
}
case 4: if (clear) {
return GC_build_fl_clear4(h, list);
} else {
return GC_build_fl4(h, list);
}
default:
break;
}
# endif
if (clear) BZERO(h, HBLKSIZE);
p = &(h -> hb_body[sz]);
prev = &(h -> hb_body[0]);
last_object = (word *)((char *)h + HBLKSIZE);
last_object -= sz;
while (p <= last_object) {
obj_link(p) = (ptr_t)prev;
prev = p;
p += sz;
}
p -= sz;
obj_link(h -> hb_body) = list;
return ((ptr_t)p);
}
void GC_new_hblk(sz, kind)
register word sz;
int kind;
{
register struct hblk *h;
register GC_bool clear = GC_obj_kinds[kind].ok_init;
# ifdef PRINTSTATS
if ((sizeof (struct hblk)) > HBLKSIZE) {
ABORT("HBLK SZ inconsistency");
}
# endif
if (GC_debugging_started) clear = TRUE;
h = GC_allochblk(sz, kind, 0);
if (h == 0) return;
if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
GC_obj_kinds[kind].ok_freelist[sz] =
GC_build_fl(h, sz, clear, GC_obj_kinds[kind].ok_freelist[sz]);
}