version 1.1.1.1, 1999/12/03 07:39:10 |
version 1.5, 2002/07/24 08:00:11 |
|
|
/* |
/* |
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. |
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. |
|
* Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. |
* |
* |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
|
|
|
|
|
|
# include <stdio.h> |
# include <stdio.h> |
# include "gc_priv.h" |
# include "private/gc_priv.h" |
|
|
#ifndef SMALL_CONFIG |
#ifndef SMALL_CONFIG |
/* |
/* |
Line 30 ptr_t GC_build_fl1(h, ofl) |
|
Line 31 ptr_t GC_build_fl1(h, ofl) |
|
struct hblk *h; |
struct hblk *h; |
ptr_t ofl; |
ptr_t ofl; |
{ |
{ |
register word * p = (word *)h; |
register word * p = h -> hb_body; |
register word * lim = (word *)(h + 1); |
register word * lim = (word *)(h + 1); |
|
|
p[0] = (word)ofl; |
p[0] = (word)ofl; |
Line 52 ptr_t GC_build_fl_clear2(h, ofl) |
|
Line 53 ptr_t GC_build_fl_clear2(h, ofl) |
|
struct hblk *h; |
struct hblk *h; |
ptr_t ofl; |
ptr_t ofl; |
{ |
{ |
register word * p = (word *)h; |
register word * p = h -> hb_body; |
register word * lim = (word *)(h + 1); |
register word * lim = (word *)(h + 1); |
|
|
p[0] = (word)ofl; |
p[0] = (word)ofl; |
Line 74 ptr_t GC_build_fl_clear3(h, ofl) |
|
Line 75 ptr_t GC_build_fl_clear3(h, ofl) |
|
struct hblk *h; |
struct hblk *h; |
ptr_t ofl; |
ptr_t ofl; |
{ |
{ |
register word * p = (word *)h; |
register word * p = h -> hb_body; |
register word * lim = (word *)(h + 1) - 2; |
register word * lim = (word *)(h + 1) - 2; |
|
|
p[0] = (word)ofl; |
p[0] = (word)ofl; |
Line 94 ptr_t GC_build_fl_clear4(h, ofl) |
|
Line 95 ptr_t GC_build_fl_clear4(h, ofl) |
|
struct hblk *h; |
struct hblk *h; |
ptr_t ofl; |
ptr_t ofl; |
{ |
{ |
register word * p = (word *)h; |
register word * p = h -> hb_body; |
register word * lim = (word *)(h + 1); |
register word * lim = (word *)(h + 1); |
|
|
p[0] = (word)ofl; |
p[0] = (word)ofl; |
|
|
p[3] = 0; |
p[3] = 0; |
p += 4; |
p += 4; |
for (; p < lim; p += 4) { |
for (; p < lim; p += 4) { |
|
PREFETCH_FOR_WRITE(p+64); |
p[0] = (word)(p-4); |
p[0] = (word)(p-4); |
p[1] = 0; |
p[1] = 0; |
p[2] = 0; |
CLEAR_DOUBLE(p+2); |
p[3] = 0; |
|
}; |
}; |
return((ptr_t)(p-4)); |
return((ptr_t)(p-4)); |
} |
} |
Line 116 ptr_t GC_build_fl2(h, ofl) |
|
Line 117 ptr_t GC_build_fl2(h, ofl) |
|
struct hblk *h; |
struct hblk *h; |
ptr_t ofl; |
ptr_t ofl; |
{ |
{ |
register word * p = (word *)h; |
register word * p = h -> hb_body; |
register word * lim = (word *)(h + 1); |
register word * lim = (word *)(h + 1); |
|
|
p[0] = (word)ofl; |
p[0] = (word)ofl; |
Line 134 ptr_t GC_build_fl4(h, ofl) |
|
Line 135 ptr_t GC_build_fl4(h, ofl) |
|
struct hblk *h; |
struct hblk *h; |
ptr_t ofl; |
ptr_t ofl; |
{ |
{ |
register word * p = (word *)h; |
register word * p = h -> hb_body; |
register word * lim = (word *)(h + 1); |
register word * lim = (word *)(h + 1); |
|
|
p[0] = (word)ofl; |
p[0] = (word)ofl; |
p[4] = (word)p; |
p[4] = (word)p; |
p += 8; |
p += 8; |
for (; p < lim; p += 8) { |
for (; p < lim; p += 8) { |
|
PREFETCH_FOR_WRITE(p+64); |
p[0] = (word)(p-4); |
p[0] = (word)(p-4); |
p[4] = (word)p; |
p[4] = (word)p; |
}; |
}; |
|
|
|
|
#endif /* !SMALL_CONFIG */ |
#endif /* !SMALL_CONFIG */ |
|
|
/* |
|
* Allocate a new heapblock for small objects of size n. |
/* Build a free list for objects of size sz inside heap block h. */ |
* Add all of the heapblock's objects to the free list for objects |
/* Clear objects inside h if clear is set. Add list to the end of */ |
* of that size. |
/* the free list we build. Return the new free list. */ |
* Set all mark bits if objects are uncollectable. |
/* This could be called without the main GC lock, if we ensure that */ |
* Will fail to do anything if we are out of memory. |
/* there is no concurrent collection which might reclaim objects that */ |
*/ |
/* we have not yet allocated. */ |
void GC_new_hblk(sz, kind) |
ptr_t GC_build_fl(h, sz, clear, list) |
register word sz; |
struct hblk *h; |
int kind; |
word sz; |
|
GC_bool clear; |
|
ptr_t list; |
{ |
{ |
register word *p, |
word *p, *prev; |
*prev; |
word *last_object; /* points to last object in new hblk */ |
word *last_object; /* points to last object in new hblk */ |
|
register struct hblk *h; /* the new heap block */ |
|
register GC_bool clear = GC_obj_kinds[kind].ok_init; |
|
|
|
# ifdef PRINTSTATS |
/* Do a few prefetches here, just because its cheap. */ |
if ((sizeof (struct hblk)) > HBLKSIZE) { |
/* If we were more serious about it, these should go inside */ |
ABORT("HBLK SZ inconsistency"); |
/* the loops. But write prefetches usually don't seem to */ |
} |
/* matter much. */ |
# endif |
PREFETCH_FOR_WRITE((char *)h); |
|
PREFETCH_FOR_WRITE((char *)h + 128); |
/* Allocate a new heap block */ |
PREFETCH_FOR_WRITE((char *)h + 256); |
h = GC_allochblk(sz, kind, 0); |
PREFETCH_FOR_WRITE((char *)h + 378); |
if (h == 0) return; |
|
|
|
/* Mark all objects if appropriate. */ |
|
if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h)); |
|
|
|
/* Handle small objects sizes more efficiently. For larger objects */ |
/* Handle small objects sizes more efficiently. For larger objects */ |
/* the difference is less significant. */ |
/* the difference is less significant. */ |
# ifndef SMALL_CONFIG |
# ifndef SMALL_CONFIG |
switch (sz) { |
switch (sz) { |
case 1: GC_obj_kinds[kind].ok_freelist[1] = |
case 1: return GC_build_fl1(h, list); |
GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]); |
|
return; |
|
case 2: if (clear) { |
case 2: if (clear) { |
GC_obj_kinds[kind].ok_freelist[2] = |
return GC_build_fl_clear2(h, list); |
GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]); |
|
} else { |
} else { |
GC_obj_kinds[kind].ok_freelist[2] = |
return GC_build_fl2(h, list); |
GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]); |
|
} |
} |
return; |
|
case 3: if (clear) { |
case 3: if (clear) { |
GC_obj_kinds[kind].ok_freelist[3] = |
return GC_build_fl_clear3(h, list); |
GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]); |
|
return; |
|
} else { |
} else { |
/* It's messy to do better than the default here. */ |
/* It's messy to do better than the default here. */ |
break; |
break; |
} |
} |
case 4: if (clear) { |
case 4: if (clear) { |
GC_obj_kinds[kind].ok_freelist[4] = |
return GC_build_fl_clear4(h, list); |
GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]); |
|
} else { |
} else { |
GC_obj_kinds[kind].ok_freelist[4] = |
return GC_build_fl4(h, list); |
GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]); |
|
} |
} |
return; |
|
default: |
default: |
break; |
break; |
} |
} |
|
|
* put p (which is now head of list of objects in *h) as first |
* put p (which is now head of list of objects in *h) as first |
* pointer in the appropriate free list for this size. |
* pointer in the appropriate free list for this size. |
*/ |
*/ |
obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz]; |
obj_link(h -> hb_body) = list; |
GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p); |
return ((ptr_t)p); |
|
} |
|
|
|
/* |
|
* Allocate a new heapblock for small objects of size n. |
|
* 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; |
|
{ |
|
register struct hblk *h; /* the new heap block */ |
|
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; |
|
|
|
/* Allocate a new heap block */ |
|
h = GC_allochblk(sz, 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]); |
} |
} |
|
|