added many lines of code for initial loading
This commit is contained in:
126
stix/lib/gc.c
126
stix/lib/gc.c
@ -28,63 +28,73 @@
|
||||
|
||||
static void cleanup_symbols_for_gc (stix_t* stix, stix_oop_t _nil)
|
||||
{
|
||||
#if 0
|
||||
stix_oop_oop_t buc;
|
||||
stix_oop_char_t sym;
|
||||
stix_oop_char_t symbol;
|
||||
stix_oow_t tally, index, i, x, y, z;
|
||||
stix_oow_t bucket_size;
|
||||
|
||||
tally = STIX_OOP_TO_SMINT (stix->symtab->slot[STIX_SYMTAB_TALLY]);
|
||||
#if defined(STIX_SUPPORT_GC_DURING_IGNITION)
|
||||
if (!stix->symtab) return; /* symbol table has not been created */
|
||||
#endif
|
||||
|
||||
bucket_size = STIX_OBJ_GET_SIZE(stix->symtab->bucket);
|
||||
|
||||
tally = STIX_OOP_TO_SMINT(stix->symtab->tally);
|
||||
if (tally <= 0) return;
|
||||
|
||||
buc = (stix_oop_oop_t) stix->symtab->slot[STIX_SYMTAB_BUCKET];
|
||||
for (index = 0; index < buc->size; )
|
||||
for (index = 0; index < bucket_size; )
|
||||
{
|
||||
if (buc->slot[index]->flags & STIX_OBJ_FLAG_MOVED)
|
||||
if (STIX_OBJ_GET_FLAGS_MOVED(stix->symtab->bucket->slot[index]))
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
STIX_ASSERT (buc->slot[index] != _nil);
|
||||
STIX_ASSERT (stix->symtab->bucket->slot[index] != _nil);
|
||||
|
||||
/*
|
||||
{
|
||||
sym = (stix_oop_char_t)buc->slot[index];
|
||||
wprintf (L">> DISPOSING %d [%S] from the symbol table\n", (int)index, sym->slot);
|
||||
}
|
||||
for (i = 0, x = index, y = index; i < buc->size; i++)
|
||||
*/
|
||||
|
||||
for (i = 0, x = index, y = index; i < bucket_size; i++)
|
||||
{
|
||||
y = (y + 1) % buc->size;
|
||||
y = (y + 1) % bucket_size;
|
||||
|
||||
/* done if the slot at the current hash index is _nil */
|
||||
if (buc->slot[y] == _nil) break;
|
||||
if (stix->symtab->bucket->slot[y] == _nil) break;
|
||||
|
||||
/* get the natural hash index for the data in the slot
|
||||
* at the current hash index */
|
||||
sym = (stix_oop_char_t)buc->slot[y];
|
||||
symbol = (stix_oop_char_t)stix->symtab->bucket->slot[y];
|
||||
|
||||
STIX_ASSERT (STIX_CLASSOF(stix,sym) == (stix_oop_t)stix->cc.symbol);
|
||||
STIX_ASSERT (STIX_CLASSOF(stix,symbol) == stix->_symbol);
|
||||
|
||||
z = hash_chars (sym->slot, sym->size) % buc->size;
|
||||
z = stix_hashchars(symbol->slot, STIX_OBJ_GET_SIZE(symbol)) % bucket_size;
|
||||
|
||||
/* move an element if necessary */
|
||||
if ((y > x && (z <= x || z > y)) ||
|
||||
(y < x && (z <= x && z > y)))
|
||||
{
|
||||
buc->slot[x] = buc->slot[y];
|
||||
stix->symtab->bucket->slot[x] = stix->symtab->bucket->slot[y];
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
|
||||
buc->slot[x] = _nil;
|
||||
stix->symtab->bucket->slot[x] = _nil;
|
||||
tally--;
|
||||
}
|
||||
|
||||
stix->symtab->slot[STIX_SYMTAB_TALLY] = STIX_OOP_FROM_SMINT(tally);
|
||||
#endif
|
||||
stix->symtab->tally = STIX_OOP_FROM_SMINT(tally);
|
||||
}
|
||||
|
||||
static stix_oop_t move_one (stix_t* stix, stix_oop_t oop)
|
||||
{
|
||||
#if defined(STIX_SUPPORT_GC_DURING_IGNITION)
|
||||
if (!oop) return oop;
|
||||
#endif
|
||||
|
||||
STIX_ASSERT (STIX_OOP_IS_POINTER(oop));
|
||||
|
||||
if (STIX_OBJ_GET_FLAGS_MOVED(oop))
|
||||
@ -93,7 +103,7 @@ static stix_oop_t move_one (stix_t* stix, stix_oop_t oop)
|
||||
* the class field has been updated to the new object
|
||||
* in the 'else' block below. i can simply return it
|
||||
* without further migration. */
|
||||
return oop->_class;
|
||||
return STIX_OBJ_GET_CLASS(oop);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -125,8 +135,8 @@ static stix_oop_t move_one (stix_t* stix, stix_oop_t oop)
|
||||
/* let the class field of the old object point to the new
|
||||
* object allocated in the new heap. it is returned in
|
||||
* the 'if' block at the top of this function. */
|
||||
oop->_class = tmp;
|
||||
|
||||
STIX_OBJ_SET_CLASS (oop, tmp);
|
||||
|
||||
/* return the new object */
|
||||
return tmp;
|
||||
}
|
||||
@ -141,11 +151,10 @@ static stix_uint8_t* scan_new_heap (stix_t* stix, stix_uint8_t* ptr)
|
||||
stix_oop_t oop;
|
||||
|
||||
oop = (stix_oop_t)ptr;
|
||||
nbytes = (oop->_size + STIX_OBJ_GET_FLAGS_EXTRA(oop)) * STIX_OBJ_GET_FLAGS_UNIT(oop);
|
||||
nbytes = (STIX_OBJ_GET_SIZE(oop) + STIX_OBJ_GET_FLAGS_EXTRA(oop)) * STIX_OBJ_GET_FLAGS_UNIT(oop);
|
||||
nbytes_aligned = STIX_ALIGN (nbytes, STIX_SIZEOF(stix_oop_t));
|
||||
|
||||
oop->_class = move_one (stix, oop->_class);
|
||||
|
||||
STIX_OBJ_SET_CLASS (oop, move_one(stix, STIX_OBJ_GET_CLASS(oop)));
|
||||
if (STIX_OBJ_GET_FLAGS_TYPE(oop) == STIX_OBJ_TYPE_OOP)
|
||||
{
|
||||
stix_obj_oop_t* xtmp;
|
||||
@ -157,7 +166,7 @@ static stix_uint8_t* scan_new_heap (stix_t* stix, stix_uint8_t* ptr)
|
||||
xtmp->slot[i] = move_one (stix, xtmp->slot[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*wprintf (L"ptr in gc => %p size => %d, aligned size => %d\n", ptr, (int)nbytes, (int)nbytes_aligned);*/
|
||||
ptr = ptr + STIX_SIZEOF(stix_obj_t) + nbytes_aligned;
|
||||
}
|
||||
@ -174,30 +183,40 @@ void stix_gc (stix_t* stix)
|
||||
* move objects pointed to by the fields to the new heap.
|
||||
* finally perform some tricky symbol table clean-up.
|
||||
*/
|
||||
|
||||
stix_uint8_t* ptr;
|
||||
stix_heap_t* tmp;
|
||||
stix_oop_t old__nil;
|
||||
stix_oop_t old_nil;
|
||||
stix_oow_t i;
|
||||
|
||||
/* TODO: allocate common objects like _nil and the root dictionary
|
||||
* in the permanant heap. minimize moving around */
|
||||
|
||||
old__nil = stix->_nil;
|
||||
old_nil = stix->_nil;
|
||||
|
||||
/* move _nil and the root object table */
|
||||
stix->_nil = move_one (stix, stix->_nil);
|
||||
stix->root = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->root);
|
||||
stix->_true = move_one (stix, stix->_true);
|
||||
stix->_false = move_one (stix, stix->_false);
|
||||
stix->_nil = move_one (stix, stix->_nil);
|
||||
stix->_true = move_one (stix, stix->_true);
|
||||
stix->_false = move_one (stix, stix->_false);
|
||||
|
||||
stix->cc.array = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.array);
|
||||
stix->cc.association = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.association);
|
||||
/*stix->cc.metaclass = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.metaclass);*/
|
||||
stix->cc.string = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.string);
|
||||
stix->cc.symbol = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.symbol);
|
||||
stix->cc.sysdic = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.sysdic);
|
||||
stix->cc.numeric[0] = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.numeric[0]);
|
||||
stix->cc.numeric[1] = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.numeric[1]);
|
||||
/*printf ("BEFORE GC = %p %p %p %p %p %p %p %p %p %p\n", stix->_array, stix->_class, stix->_nil_object, stix->_object, stix->_symbol, stix->_symbol_set, stix->_system_dictionary, stix->_association, stix->_character, stix->_small_integer);*/
|
||||
stix->_stix = move_one (stix, stix->_stix);
|
||||
stix->_class = move_one (stix, stix->_class);
|
||||
stix->_nil_object = move_one (stix, stix->_nil_object);
|
||||
stix->_object = move_one (stix, stix->_object);
|
||||
stix->_array = move_one (stix, stix->_array);
|
||||
stix->_symbol = move_one (stix, stix->_symbol);
|
||||
stix->_symbol_set = move_one (stix, stix->_symbol_set);
|
||||
stix->_system_dictionary = move_one (stix, stix->_system_dictionary);
|
||||
stix->_association = move_one (stix, stix->_association);
|
||||
stix->_character = move_one (stix, stix->_character);
|
||||
stix->_small_integer = move_one (stix, stix->_small_integer);
|
||||
|
||||
/*printf ("AFTER GC = %p %p %p %p %p %p %p %p %p %p\n", stix->_array, stix->_class, stix->_nil_object, stix->_object, stix->_symbol, stix->_symbol_set, stix->_system_dictionary, stix->_association, stix->_character, stix->_small_integer);*/
|
||||
stix->sysdic = (stix_oop_set_t) move_one (stix, (stix_oop_t)stix->sysdic);
|
||||
|
||||
for (i = 0; i < stix->tmp_count; i++)
|
||||
{
|
||||
*stix->tmp_stack[i] = move_one (stix, *stix->tmp_stack[i]);
|
||||
}
|
||||
|
||||
/* scan the new heap to move referenced objects */
|
||||
ptr = (stix_uint8_t*) STIX_ALIGN ((stix_uintptr_t)stix->newheap->base, STIX_SIZEOF(stix_oop_t));
|
||||
@ -207,10 +226,10 @@ void stix_gc (stix_t* stix)
|
||||
* if the symbol has not moved to the new heap, the symbol
|
||||
* is not referenced by any other objects than the symbol
|
||||
* table itself */
|
||||
cleanup_symbols_for_gc (stix, old__nil);
|
||||
cleanup_symbols_for_gc (stix, old_nil);
|
||||
|
||||
/* move the symbol table itself */
|
||||
stix->symtab = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->symtab);
|
||||
stix->symtab = (stix_oop_set_t)move_one (stix, (stix_oop_t)stix->symtab);
|
||||
|
||||
/* scan the new heap again from the end position of
|
||||
* the previous scan to move referenced objects by
|
||||
@ -242,3 +261,24 @@ printf ("===========================\n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void stix_pushtmp (stix_t* stix, stix_oop_t* oop_ptr)
|
||||
{
|
||||
/* if you have too many temporaries pushed, something must be wrong.
|
||||
* change your code not to exceede the stack limit */
|
||||
STIX_ASSERT (stix->tmp_count < STIX_COUNTOF(stix->tmp_stack));
|
||||
stix->tmp_stack[stix->tmp_count++] = oop_ptr;
|
||||
}
|
||||
|
||||
void stix_poptmp (stix_t* stix)
|
||||
{
|
||||
STIX_ASSERT (stix->tmp_count > 0);
|
||||
stix->tmp_count--;
|
||||
}
|
||||
|
||||
void stix_poptmps (stix_t* stix, stix_oow_t count)
|
||||
{
|
||||
STIX_ASSERT (stix->tmp_count >= count);
|
||||
stix->tmp_count -= count;
|
||||
}
|
||||
|
Reference in New Issue
Block a user