some largely unsuccessful attempts at making GC faster

cvs
Slava Pestov 2004-12-11 18:26:36 +00:00
parent 805653deb8
commit 7d75929d0a
3 changed files with 72 additions and 66 deletions

View File

@ -10,56 +10,58 @@ INLINE void gc_debug(char* msg, CELL x) {
#endif #endif
} }
void collect_roots(void)
{
int i;
CELL ptr;
/*T must be the first in the heap */
copy_object(&T);
/* the bignum 0 1 -1 constants must be the next three */
copy_bignum_constants();
copy_object(&callframe);
for(ptr = ds_bot; ptr <= ds; ptr += CELLS)
copy_object((void*)ptr);
for(ptr = cs_bot; ptr <= cs; ptr += CELLS)
copy_object((void*)ptr);
for(i = 0; i < USER_ENV; i++)
copy_object(&userenv[i]);
}
/* /*
Given a pointer to a tagged pointer to oldspace, copy it to newspace. Given a pointer to a tagged pointer to oldspace, copy it to newspace.
If the object has already been copied, return the forwarding If the object has already been copied, return the forwarding
pointer address without copying anything; otherwise, install pointer address without copying anything; otherwise, install
a new forwarding pointer. a new forwarding pointer.
*/ */
void copy_object(CELL* handle) CELL copy_object_impl(CELL pointer)
{ {
CELL pointer = *handle; CELL newpointer;
CELL tag = TAG(pointer);
CELL header, newpointer;
if(tag == FIXNUM_TYPE || pointer == F)
return;
#ifdef GC_DEBUG
if(in_zone(&active,pointer)) if(in_zone(&active,pointer))
critical_error("copy_object given newspace ptr",pointer); critical_error("copy_object given newspace ptr",pointer);
#endif
header = get(UNTAG(pointer));
if(TAG(header) == GC_COLLECTED)
{
newpointer = UNTAG(header);
gc_debug("FORWARDING",newpointer);
}
else if(TAG(pointer) == GC_COLLECTED)
{
critical_error("asked to copy forwarding pointer",pointer);
newpointer = 0; /* to shut up gcc */
}
else
{
gc_debug("copy_object",pointer); gc_debug("copy_object",pointer);
newpointer = (CELL)copy_untagged_object((void*)UNTAG(pointer), newpointer = (CELL)copy_untagged_object((void*)UNTAG(pointer),
object_size(pointer)); object_size(pointer));
put(UNTAG(pointer),RETAG(newpointer,GC_COLLECTED)); put(UNTAG(pointer),RETAG(newpointer,GC_COLLECTED));
}
#ifdef GC_DEBUG
if(tag == GC_COLLECTED) if(tag == GC_COLLECTED)
critical_error("installing forwarding pointer in newspace",newpointer); critical_error("installing forwarding pointer in newspace",newpointer);
#endif
*handle = RETAG(newpointer,tag); return newpointer;
} }
void collect_object(void) INLINE void collect_object(CELL scan)
{ {
CELL size = untagged_object_size(scan);
gc_debug("collect_object",scan);
gc_debug("collect_object size=",size);
switch(untag_header(get(scan))) switch(untag_header(get(scan)))
{ {
case WORD_TYPE: case WORD_TYPE:
@ -78,52 +80,32 @@ void collect_object(void)
collect_port((F_PORT*)scan); collect_port((F_PORT*)scan);
break; break;
} }
scan += size;
} }
void collect_next(void) INLINE CELL collect_next(CELL scan)
{ {
CELL size;
gc_debug("collect_next",scan); gc_debug("collect_next",scan);
gc_debug("collect_next header",get(scan)); gc_debug("collect_next header",get(scan));
switch(TAG(get(scan))) switch(TAG(get(scan)))
{ {
case HEADER_TYPE: case HEADER_TYPE:
collect_object(); size = untagged_object_size(scan);
collect_object(scan);
break; break;
default: default:
size = CELLS;
copy_object((CELL*)scan); copy_object((CELL*)scan);
scan += CELLS;
break; break;
} }
}
void collect_roots(void) return scan + size;
{
int i;
CELL ptr;
gc_debug("collect_roots",scan);
/*T must be the first in the heap */
copy_object(&T);
/* the bignum 0 1 -1 constants must be the next three */
copy_bignum_constants();
copy_object(&callframe);
for(ptr = ds_bot; ptr <= ds; ptr += CELLS)
copy_object((void*)ptr);
for(ptr = cs_bot; ptr <= cs; ptr += CELLS)
copy_object((void*)ptr);
for(i = 0; i < USER_ENV; i++)
copy_object(&userenv[i]);
} }
void primitive_gc(void) void primitive_gc(void)
{ {
int64_t start = current_millis(); int64_t start = current_millis();
CELL scan;
gc_in_progress = true; gc_in_progress = true;
@ -133,10 +115,11 @@ void primitive_gc(void)
collect_io_tasks(); collect_io_tasks();
/* collect literal objects referenced from compiled code */ /* collect literal objects referenced from compiled code */
collect_literals(); collect_literals();
while(scan < active.here) while(scan < active.here)
{ {
gc_debug("scan loop",scan); gc_debug("scan loop",scan);
collect_next(); scan = collect_next(scan);
} }
gc_debug("gc done",0); gc_debug("gc done",0);

View File

@ -1,4 +1,3 @@
CELL scan;
bool gc_in_progress; bool gc_in_progress;
int64_t gc_time; int64_t gc_time;
@ -11,9 +10,31 @@ INLINE void* copy_untagged_object(void* pointer, CELL size)
return newpointer; return newpointer;
} }
void copy_object(CELL* handle); CELL copy_object_impl(CELL pointer);
void collect_object(void);
void collect_next(void); INLINE void copy_object(CELL* handle)
{
CELL pointer = *handle;
CELL tag;
CELL header;
CELL newpointer;
if(pointer == F)
return;
tag = TAG(pointer);
if(tag == FIXNUM_TYPE)
return;
header = get(UNTAG(pointer));
if(TAG(header) == GC_COLLECTED)
newpointer = UNTAG(header);
else
newpointer = copy_object_impl(pointer);
*handle = RETAG(newpointer,tag);
}
void collect_roots(void); void collect_roots(void);
void primitive_gc(void); void primitive_gc(void);
void maybe_garbage_collection(void); void maybe_garbage_collection(void);

View File

@ -54,10 +54,12 @@ INLINE CELL tag_header(CELL cell)
INLINE CELL untag_header(CELL cell) INLINE CELL untag_header(CELL cell)
{ {
CELL type = cell >> TAG_BITS; CELL type = cell >> TAG_BITS;
#ifdef HEADER_DEBUG
if(TAG(cell) != HEADER_TYPE) if(TAG(cell) != HEADER_TYPE)
critical_error("header type check",cell); critical_error("header type check",cell);
if(type <= HEADER_TYPE && type != WORD_TYPE) if(type <= HEADER_TYPE && type != WORD_TYPE)
critical_error("header invariant check",cell); critical_error("header invariant check",cell);
#endif
return type; return type;
} }