diff --git a/ase/stx/memory.c b/ase/stx/memory.c new file mode 100644 index 00000000..1dc54168 --- /dev/null +++ b/ase/stx/memory.c @@ -0,0 +1,101 @@ +/* + * $Id: memory.c,v 1.1 2005-05-06 15:54:47 bacon Exp $ + */ + +#include +#include + +xp_stx_memory_t* xp_stx_memory_open ( + xp_stx_memory_t* mem, xp_stx_word_t capacity) +{ + xp_assert (capacity > 0); + xp_stx_object_t** slots; + + if (mem == XP_NULL) { + mem = (xp_stx_memory_t*)xp_malloc(xp_sizeof(xp_stx_memory_t)); + if (mem == XP_NULL) return XP_NULL; + mem->__malloced = xp_true; + } + else mem->__malloced = xp_false; + + slots = (xp_stx_object_t**)xp_malloc ( + capacity * xp_sizeof(xp_stx_object_t*)); + if (slots == XP_NULL) { + if (mem->__malloced) xp_free (mem); + mem = XP_NULL; + } + + mem->capacity = capacity; + mem->slots = slots; + + /* weave the free slot list */ + mem->free = &slots[capacity - 1]; + while (capacity > 1) { + capacity--; + mem->slots[capacity] = (xp_stx_object_t*)&mem->slots[capacity - 1]; + } + mem->slots[--capacity] = XP_NULL; + + return mem; +} + +void xp_stx_memory_free (xp_stx_memory_t* mem) +{ + /* TODO: free all linked objects... */ + + xp_free (mem->slots); + mem->capacity = 0; + mem->slots = XP_NULL; + mem->free = XP_NULL; + if (mem->__malloced) xp_free (mem); +} + +/* +// resize the object table - mem +xp_stx_memory_t* xp_stx_memory_resize (xp_stx_memory_t* mem, xp_stx_word_t capacity) +{ +} +*/ + +void xp_stx_garbage_collect (xp_stx_memory_t* mem) +{ + /* TODO: implement this function */ +} + +xp_stx_word_t xp_stx_alloc_object (xp_stx_memory_t* mem, xp_stx_word_t nbytes) +{ + xp_stx_object_t** slot; + xp_stx_object_t* object; + + /* find the free object slot */ + if (mem->free == XP_NULL) { + xp_stx_garbage_collect (mem); + if (mem->free == XP_NULL) return mem->capacity; + } + + object = (xp_stx_object_t*)xp_malloc (nbytes); + if (object == XP_NULL) { + xp_stx_garbage_collect (mem); + object = (xp_stx_object_t*)xp_malloc (nbytes); + if (object == XP_NULL) return mem->capacity; + } + + slot = mem->free; + mem->free = (xp_stx_object_t**)*slot; + *slot = object; + + return (xp_stx_word_t)(slot - mem->slots); +} + +void xp_stx_dealloc_object (xp_stx_memory_t* mem, xp_stx_word_t object_index) +{ + /* + * THIS IS PRIMITIVE LOW-LEVEL DEALLOC. THIS WILL NOT + * DEALLOCATE MEMORY ALLOCATED FOR ITS INSTANCE VARIABLES. + */ + + xp_free (mem->slots[object_index]); + mem->slots[object_index] = (xp_stx_object_t*)mem->free; + mem->free = &mem->slots[object_index]; +} + diff --git a/ase/stx/memory.h b/ase/stx/memory.h new file mode 100644 index 00000000..9988decd --- /dev/null +++ b/ase/stx/memory.h @@ -0,0 +1,61 @@ +/* + * $Id: memory.h,v 1.1 2005-05-06 15:54:47 bacon Exp $ + */ + +#ifndef _XP_STX_MEMORY_H_ +#define _XP_STX_MEMORY_H_ + +#include +#include + +typedef struct xp_stx_memory_t xp_stx_memory_t; +typedef struct xp_stx_object_t xp_stx_object_t; + +typedef xp_byte xp_stx_byte_t; +typedef xp_size_t xp_stx_word_t; +typedef xp_size_t xp_stx_size_t; +typedef xp_size_t xp_stx_index_t; +typedef xp_stx_object_t* xp_stx_pointer_t; + +#define XP_STX_OBJECT(mem,index) (mem->slots[index>>1]) + +/* access - is_byte_indexed: 1; size: rest */ +#define XP_STX_OBJECT_HEADER \ + xp_stx_word_t access; \ + xp_stx_word_t class + +/* common object header structure */ +struct xp_stx_object_t +{ + XP_STX_OBJECT_HEADER; +}; + +struct xp_stx_memory_t +{ + xp_stx_word_t capacity; + xp_stx_object_t** slots; + xp_stx_object_t** free; + + xp_stx_word_t nil; + //xp_stx_word_t smalltalk; + //xp_stx_word_t classes[]; + xp_stx_word_t symbol_table; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +xp_stx_memory_t* xp_stx_memory_open ( + xp_stx_memory_t* mem, xp_stx_word_t capacity); +void xp_stx_memory_close (xp_stx_memory_t* mem); + +void xp_stx_gaxpage_collect (xp_stx_memory_t* mem); +xp_stx_word_t xp_stx_alloc_object (xp_stx_memory_t* mem, xp_stx_word_t size); +void xp_stx_dealloc_object (xp_stx_memory_t* mem, xp_stx_word_t object_index); + +#ifdef __cplusplus +} +#endif + +#endif