*/
/*
- * $Header$
- */
-
-/*
* For a review of garbage collection techniques (e.g. generational
* GC) and terminology (e.g. "scavenging") see Paul R. Wilson,
* "Uniprocessor Garbage Collection Techniques". As of 20000618, this
#include "runtime.h"
#include "sbcl.h"
#include "os.h"
+#include "interr.h"
#include "globals.h"
#include "interrupt.h"
#include "validate.h"
#include "lispregs.h"
+#include "arch.h"
#include "gc.h"
#include "gencgc.h"
for (j = 0; j < last_free_page; j++)
if (page_table[j].gen == i) {
+
/* Count the number of boxed pages within the given
- * generation */
- if (page_table[j].allocated == BOXED_PAGE)
+ * generation. */
+ if (page_table[j].allocated == BOXED_PAGE) {
if (page_table[j].large_object)
large_boxed_cnt++;
else
boxed_cnt++;
-
+ }
+
/* Count the number of unboxed pages within the given
- * generation */
- if (page_table[j].allocated == UNBOXED_PAGE)
+ * generation. */
+ if (page_table[j].allocated == UNBOXED_PAGE) {
if (page_table[j].large_object)
large_unboxed_cnt++;
else
unboxed_cnt++;
+ }
}
gc_assert(generations[i].bytes_allocated
#define DIRECT_SCAV 0
+/* FIXME: Most calls end up going to a little trouble to compute an
+ * 'nwords' value. The system might be a little simpler if this
+ * function used an 'end' parameter instead. */
static void
scavenge(lispobj *start, long nwords)
{
static lispobj *
search_static_space(lispobj *pointer)
{
- lispobj* start = (lispobj*)static_space;
+ lispobj* start = (lispobj*)STATIC_SPACE_START;
lispobj* end = (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER);
if ((pointer < start) || (pointer >= end))
return NULL;
case type_FuncallableInstanceHeader:
case type_ByteCodeFunction:
case type_ByteCodeClosure:
- if ((int)pointer != ((int)start_addr+type_FunctionPointer)) {
+ if ((unsigned)pointer !=
+ ((unsigned)start_addr+type_FunctionPointer)) {
if (gencgc_verbose)
FSHOW((stderr,
"/Wf2: %x %x %x\n",
}
break;
case type_ListPointer:
- if ((int)pointer != ((int)start_addr+type_ListPointer)) {
+ if ((unsigned)pointer !=
+ ((unsigned)start_addr+type_ListPointer)) {
if (gencgc_verbose)
FSHOW((stderr,
"/Wl1: %x %x %x\n",
return 0;
}
case type_InstancePointer:
- if ((int)pointer != ((int)start_addr+type_InstancePointer)) {
+ if ((unsigned)pointer !=
+ ((unsigned)start_addr+type_InstancePointer)) {
if (gencgc_verbose)
FSHOW((stderr,
"/Wi1: %x %x %x\n",
}
break;
case type_OtherPointer:
- if ((int)pointer != ((int)start_addr+type_OtherPointer)) {
+ if ((unsigned)pointer !=
+ ((int)start_addr+type_OtherPointer)) {
if (gencgc_verbose)
FSHOW((stderr,
"/Wo1: %x %x %x\n",
region_allocation = page_table[addr_page_index].allocated;
- /* Check the offset within the page */
- if (((int)addr & 0xfff) > page_table[addr_page_index].bytes_used)
+ /* Check the offset within the page.
+ *
+ * FIXME: The mask should have a symbolic name, and ideally should
+ * be derived from page size instead of hardwired to 0xfff.
+ * (Also fix other uses of 0xfff, elsewhere.) */
+ if (((unsigned)addr & 0xfff) > page_table[addr_page_index].bytes_used)
return;
if (enable_pointer_filter && !valid_dynamic_space_pointer(addr))
if ((page_table[addr_page_index].allocated == FREE_PAGE)
|| (page_table[addr_page_index].bytes_used == 0)
/* Check the offset within the page. */
- || (((int)addr & 0xfff)
+ || (((unsigned)addr & 0xfff)
> page_table[addr_page_index].bytes_used)) {
FSHOW((stderr,
"weird? ignore ptr 0x%x to freed area of large object\n",
vector_length));
if (vector_length > 0) {
lispobj *stack_pointer = (lispobj*)stack->data[0];
- if ((stack_pointer < control_stack) ||
- (stack_pointer > control_stack_end))
+ if ((stack_pointer < (lispobj *)CONTROL_STACK_START) ||
+ (stack_pointer > (lispobj *)CONTROL_STACK_END))
lose("invalid stack pointer %x",
(unsigned)stack_pointer);
- if ((stack_pointer > control_stack) &&
- (stack_pointer < control_stack_end)) {
- unsigned int length = ((int)control_stack_end -
- (int)stack_pointer) / 4;
+ if ((stack_pointer > (lispobj *)CONTROL_STACK_START) &&
+ (stack_pointer < (lispobj *)CONTROL_STACK_END)) {
+ /* FIXME: Ick!
+ * (1) hardwired word length = 4; and as usual,
+ * when fixing this, check for other places
+ * with the same problem
+ * (2) calling it 'length' suggests bytes;
+ * perhaps 'size' instead? */
+ unsigned int length = ((unsigned)CONTROL_STACK_END -
+ (unsigned)stack_pointer) / 4;
int j;
if (length >= vector_length) {
lose("invalid stack size %d >= vector length %d",
extern int undefined_tramp;
static void
-verify_space(lispobj*start, size_t words)
+verify_space(lispobj *start, size_t words)
{
- int dynamic_space = (find_page_index((void*)start) != -1);
- int readonly_space =
- (READ_ONLY_SPACE_START <= (int)start &&
- (int)start < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
+ int is_in_dynamic_space = (find_page_index((void*)start) != -1);
+ int is_in_readonly_space =
+ (READ_ONLY_SPACE_START <= (unsigned)start &&
+ (unsigned)start < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
while (words > 0) {
size_t count = 1;
(READ_ONLY_SPACE_START <= thing &&
thing < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
int to_static_space =
- ((int)static_space <= thing &&
+ (STATIC_SPACE_START <= thing &&
thing < SymbolValue(STATIC_SPACE_FREE_POINTER));
/* Does it point to the dynamic space? */
}
/* Check that its not in the RO space as it would then be a
* pointer from the RO to the dynamic space. */
- if (readonly_space) {
+ if (is_in_readonly_space) {
lose("ptr to dynamic space %x from RO space %x",
thing, start);
}
} else {
/* Verify that it points to another valid space. */
if (!to_readonly_space && !to_static_space
- && (thing != (int)&undefined_tramp)) {
+ && (thing != (unsigned)&undefined_tramp)) {
lose("Ptr %x @ %x sees junk.", thing, start);
}
}
/* Check that it's not in the dynamic space.
* FIXME: Isn't is supposed to be OK for code
* objects to be in the dynamic space these days? */
- if (dynamic_space
+ if (is_in_dynamic_space
/* It's ok if it's byte compiled code. The trace
* table offset will be a fixnum if it's x86
* compiled code - check. */
static void
verify_gc(void)
{
+ /* FIXME: It would be nice to make names consistent so that
+ * foo_size meant size *in* *bytes* instead of size in some
+ * arbitrary units. (Yes, this caused a bug, how did you guess?:-)
+ * Some counts of lispobjs are called foo_count; it might be good
+ * to grep for all foo_size and rename the appropriate ones to
+ * foo_count. */
int read_only_space_size =
(lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)
- (lispobj*)READ_ONLY_SPACE_START;
int static_space_size =
(lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER)
- - (lispobj*)static_space;
+ - (lispobj*)STATIC_SPACE_START;
int binding_stack_size =
(lispobj*)SymbolValue(BINDING_STACK_POINTER)
- (lispobj*)BINDING_STACK_START;
verify_space((lispobj*)READ_ONLY_SPACE_START, read_only_space_size);
- verify_space((lispobj*)static_space, static_space_size);
- verify_space((lispobj*)BINDING_STACK_START, binding_stack_size);
+ verify_space((lispobj*)STATIC_SPACE_START , static_space_size);
+ verify_space((lispobj*)BINDING_STACK_START , binding_stack_size);
}
static void
} else {
int free_bytes = 4096 - page_table[page].bytes_used;
if (free_bytes > 0) {
- int *start_addr = (int *)((int)page_address(page)
+ int *start_addr = (int *)((unsigned)page_address(page)
+ page_table[page].bytes_used);
int size = free_bytes / 4;
int i;
/* Scavenge the stack's conservative roots. */
{
lispobj **ptr;
- for (ptr = (lispobj **)CONTROL_STACK_END-1;
- ptr > (lispobj **)&raise; ptr--)
+ for (ptr = (lispobj **)CONTROL_STACK_END - 1;
+ ptr > (lispobj **)&raise;
+ ptr--) {
preserve_pointer(*ptr);
+ }
}
#ifdef CONTROL_STACKS
scavenge_thread_stacks();
}
/* Scavenge the binding stack. */
- scavenge(binding_stack,
- (lispobj *)SymbolValue(BINDING_STACK_POINTER) - binding_stack);
+ scavenge(BINDING_STACK_START,
+ (lispobj *)SymbolValue(BINDING_STACK_POINTER) -
+ (lispobj *)BINDING_STACK_START);
if (SymbolValue(SCAVENGE_READ_ONLY_SPACE) != NIL) {
read_only_space_size =
- (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)
- - read_only_space;
+ (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER) -
+ (lispobj*)READ_ONLY_SPACE_START;
FSHOW((stderr,
"/scavenge read only space: %d bytes\n",
read_only_space_size * sizeof(lispobj)));
- scavenge(read_only_space, read_only_space_size);
+ scavenge(READ_ONLY_SPACE_START, read_only_space_size);
}
- static_space_size = (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER)
- - static_space;
+ static_space_size =
+ (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER) -
+ (lispobj *)STATIC_SPACE_START;
if (gencgc_verbose > 1)
FSHOW((stderr,
"/scavenge static space: %d bytes\n",
static_space_size * sizeof(lispobj)));
- scavenge(static_space, static_space_size);
+ scavenge(STATIC_SPACE_START, static_space_size);
/* All generations but the generation being GCed need to be
* scavenged. The new_space generation needs special handling as
gc_init_tables();
- heap_base = (void*)DYNAMIC_0_SPACE_START;
+ heap_base = (void*)DYNAMIC_SPACE_START;
/* Initialize each page structure. */
for (i = 0; i < NUM_PAGES; i++) {
gencgc_pickup_dynamic(void)
{
int page = 0;
- int addr = DYNAMIC_0_SPACE_START;
+ int addr = DYNAMIC_SPACE_START;
int alloc_ptr = SymbolValue(ALLOCATION_POINTER);
/* Initialize the first region. */
page_table[page].bytes_used = 4096;
page_table[page].large_object = 0;
page_table[page].first_object_offset =
- (void *)DYNAMIC_0_SPACE_START - page_address(page);
+ (void *)DYNAMIC_SPACE_START - page_address(page);
addr += 4096;
page++;
} while (addr < alloc_ptr);