renamed moo_allocheapmem() to moo_allocheapspace() and changed its second parameter from moo_heap_t* to moo_space_t*

added moo_space_t
changed moo_makeheap() to create a single heap and split it to multiple spaces
This commit is contained in:
hyunghwan.chung 2018-11-30 13:37:15 +00:00
parent 4de478a9cc
commit 1cffec34e8
6 changed files with 63 additions and 54 deletions

View File

@ -579,13 +579,9 @@ int moo_ignite (moo_t* moo, moo_oow_t heapsz)
{ {
MOO_ASSERT (moo, moo->_nil == MOO_NULL); MOO_ASSERT (moo, moo->_nil == MOO_NULL);
/*moo->permheap = moo_makeheap (moo, what is the best size???); if (moo->heap) moo_killheap (moo, moo->heap);
if (!moo->permheap) goto oops; */ moo->heap = moo_makeheap(moo, heapsz);
if (moo->curheap) moo_killheap (moo, moo->curheap); if (!moo->heap) return -1;
if (moo->newheap) moo_killheap (moo, moo->newheap);
moo->curheap = moo_makeheap(moo, heapsz);
moo->newheap = moo_makeheap(moo, heapsz);
if (!moo->curheap || !moo->newheap) return -1;
moo->_nil = moo_allocbytes (moo, MOO_SIZEOF(moo_obj_t)); moo->_nil = moo_allocbytes (moo, MOO_SIZEOF(moo_obj_t));
if (!moo->_nil) return -1; if (!moo->_nil) return -1;
@ -730,7 +726,7 @@ moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop)
nbytes_aligned = get_payload_bytes (moo, oop); nbytes_aligned = get_payload_bytes (moo, oop);
/* allocate space in the new heap */ /* allocate space in the new heap */
tmp = moo_allocheapmem (moo, moo->newheap, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); tmp = moo_allocheapspace(moo, &moo->heap->newspace, MOO_SIZEOF(moo_obj_t) + nbytes_aligned);
/* allocation here must not fail because /* allocation here must not fail because
* i'm allocating the new space in a new heap for * i'm allocating the new space in a new heap for
@ -759,7 +755,7 @@ moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop)
static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr) static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr)
{ {
while (ptr < moo->newheap->ptr) while (ptr < moo->heap->newspace.ptr)
{ {
moo_oow_t i; moo_oow_t i;
moo_oow_t nbytes_aligned; moo_oow_t nbytes_aligned;
@ -863,7 +859,7 @@ void moo_gc (moo_t* moo)
* finally perform some tricky symbol table clean-up. * finally perform some tricky symbol table clean-up.
*/ */
moo_uint8_t* scan_ptr; moo_uint8_t* scan_ptr;
moo_heap_t* tmp; moo_space_t tmp;
moo_oop_t old_nil; moo_oop_t old_nil;
moo_oow_t i; moo_oow_t i;
moo_evtcb_t* cb; moo_evtcb_t* cb;
@ -884,9 +880,9 @@ void moo_gc (moo_t* moo)
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
"Starting GC curheap base %p ptr %p newheap base %p ptr %p\n", "Starting GC curheap base %p ptr %p newheap base %p ptr %p\n",
moo->curheap->base, moo->curheap->ptr, moo->newheap->base, moo->newheap->ptr); moo->heap->curspace.base, moo->heap->curspace.ptr, moo->heap->newspace.base, moo->heap->newspace.ptr);
scan_ptr = (moo_uint8_t*) MOO_ALIGN ((moo_uintptr_t)moo->newheap->base, MOO_SIZEOF(moo_oop_t)); scan_ptr = (moo_uint8_t*) MOO_ALIGN ((moo_uintptr_t)moo->heap->newspace.base, MOO_SIZEOF(moo_oop_t));
/* TODO: allocate common objects like _nil and the root dictionary /* TODO: allocate common objects like _nil and the root dictionary
* in the permanant heap. minimize moving around */ * in the permanant heap. minimize moving around */
@ -981,12 +977,12 @@ void moo_gc (moo_t* moo)
/* the contents of the current heap is not needed any more. /* the contents of the current heap is not needed any more.
* reset the upper bound to the base. don't forget to align the heap * reset the upper bound to the base. don't forget to align the heap
* pointer to the OOP size. See moo_makeheap() also */ * pointer to the OOP size. See moo_makeheap() also */
moo->curheap->ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)moo->curheap->base), MOO_SIZEOF(moo_oop_t)); moo->heap->curspace.ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)moo->heap->curspace.base), MOO_SIZEOF(moo_oop_t));
/* swap the current heap and old heap */ /* swap the current heap and old heap */
tmp = moo->curheap; tmp = moo->heap->curspace;
moo->curheap = moo->newheap; moo->heap->curspace = moo->heap->newspace;
moo->newheap = tmp; moo->heap->newspace = tmp;
/* /*
if (moo->symtab && MOO_LOG_ENABLED(moo, MOO_LOG_GC | MOO_LOG_DEBUG)) if (moo->symtab && MOO_LOG_ENABLED(moo, MOO_LOG_GC | MOO_LOG_DEBUG))
@ -1012,7 +1008,7 @@ void moo_gc (moo_t* moo)
/* TODO: include some gc statstics like number of live objects, gc performance, etc */ /* TODO: include some gc statstics like number of live objects, gc performance, etc */
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
"Finished GC curheap base %p ptr %p newheap base %p ptr %p\n", "Finished GC curheap base %p ptr %p newheap base %p ptr %p\n",
moo->curheap->base, moo->curheap->ptr, moo->newheap->base, moo->newheap->ptr); moo->heap->curspace.base, moo->heap->curspace.ptr, moo->heap->newspace.base, moo->heap->newspace.ptr);
} }
void moo_pushtmp (moo_t* moo, moo_oop_t* oop_ptr) void moo_pushtmp (moo_t* moo, moo_oop_t* oop_ptr)

View File

@ -29,6 +29,10 @@
moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size) moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size)
{ {
moo_heap_t* heap; moo_heap_t* heap;
moo_oow_t half_size;
if (size < 65536) size = 65536; /* not really useful check as 65536 is too small */
half_size = size / 2;
heap = (moo_heap_t*)moo->vmprim.alloc_heap(moo, MOO_SIZEOF(*heap) + size); heap = (moo_heap_t*)moo->vmprim.alloc_heap(moo, MOO_SIZEOF(*heap) + size);
if (!heap) if (!heap)
@ -39,19 +43,20 @@ moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size)
} }
MOO_MEMSET (heap, 0, MOO_SIZEOF(*heap) + size); MOO_MEMSET (heap, 0, MOO_SIZEOF(*heap) + size);
heap->base = (moo_uint8_t*)(heap + 1); heap->base = (moo_uint8_t*)(heap + 1);
/* adjust the initial allocation pointer to a multiple of the oop size */ heap->size = size;
heap->ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)heap->base), MOO_SIZEOF(moo_oop_t));
heap->limit = heap->base + size;
MOO_ASSERT (moo, heap->ptr >= heap->base); heap->curspace.base= (moo_uint8_t*)(heap + 1);
MOO_ASSERT (moo, heap->limit >= heap->base ); heap->curspace.ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)heap->curspace.base), MOO_SIZEOF(moo_oop_t));
MOO_ASSERT (moo, heap->limit - heap->base == size); heap->curspace.limit = heap->curspace.ptr + half_size;
/* if size is too small, heap->ptr may go past heap->limit even at heap->newspace.base = (moo_uint8_t*)(heap + 1) + half_size;
* this moment depending on the alignment of heap->base. subsequent heap->newspace.ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)heap->newspace.base), MOO_SIZEOF(moo_oop_t));
* calls to submoo_allocheapmem() are bound to fail. Make sure to heap->newspace.limit = heap->newspace.ptr + half_size;
/* if size is too small, space->ptr may go past space->limit even at
* this moment depending on the alignment of space->base. subsequent
* calls to moo_allocheapspace() are bound to fail. Make sure to
* pass a heap size large enough */ * pass a heap size large enough */
return heap; return heap;
@ -62,22 +67,22 @@ void moo_killheap (moo_t* moo, moo_heap_t* heap)
moo->vmprim.free_heap (moo, heap); moo->vmprim.free_heap (moo, heap);
} }
void* moo_allocheapmem (moo_t* moo, moo_heap_t* heap, moo_oow_t size) void* moo_allocheapspace (moo_t* moo, moo_space_t* space, moo_oow_t size)
{ {
moo_uint8_t* ptr; moo_uint8_t* ptr;
/* check the heap size limit */ /* check the space size limit */
if (heap->ptr >= heap->limit || heap->limit - heap->ptr < size) if (space->ptr >= space->limit || space->limit - space->ptr < size)
{ {
MOO_DEBUG5 (moo, "Cannot allocate %zd bytes from heap - ptr %p limit %p size %zd free %zd\n", MOO_DEBUG5 (moo, "Cannot allocate %zd bytes from space - ptr %p limit %p size %zd free %zd\n",
size, heap->ptr, heap->limit, (moo_oow_t)(heap->limit - heap->base), (moo_oow_t)(heap->limit - heap->ptr)); size, space->ptr, space->limit, (moo_oow_t)(space->limit - space->base), (moo_oow_t)(space->limit - space->ptr));
moo_seterrnum (moo, MOO_EOOMEM); moo_seterrnum (moo, MOO_EOOMEM);
return MOO_NULL; return MOO_NULL;
} }
/* allocation is as simple as moving the heap pointer */ /* allocation is as simple as moving the space pointer */
ptr = heap->ptr; ptr = space->ptr;
heap->ptr += size; space->ptr += size;
return ptr; return ptr;
} }

View File

@ -1073,15 +1073,15 @@ void moo_killheap (
); );
/** /**
* The moo_allocheapmem() function allocates \a size bytes in the heap pointed * The moo_allocheapspace() function allocates \a size bytes in the heap pointed
* to by \a heap. * to by \a heap.
* *
* \return memory pointer on success and #MOO_NULL on failure. * \return memory pointer on success and #MOO_NULL on failure.
*/ */
void* moo_allocheapmem ( void* moo_allocheapspace (
moo_t* moo, moo_t* moo,
moo_heap_t* heap, moo_space_t* space,
moo_oow_t size moo_oow_t size
); );
/* ========================================================================= */ /* ========================================================================= */

View File

@ -247,9 +247,7 @@ void moo_fini (moo_t* moo)
/* if the moo object is closed without moo_ignite(), /* if the moo object is closed without moo_ignite(),
* the heap may not exist */ * the heap may not exist */
if (moo->newheap) moo_killheap (moo, moo->newheap); if (moo->heap) moo_killheap (moo, moo->heap);
if (moo->curheap) moo_killheap (moo, moo->curheap);
if (moo->permheap) moo_killheap (moo, moo->permheap);
for (i = 0; i < MOO_COUNTOF(moo->sbuf); i++) for (i = 0; i < MOO_COUNTOF(moo->sbuf); i++)
{ {

View File

@ -963,16 +963,28 @@ struct moo_process_scheduler_t
#define MOO_BYTESOF(moo,oop) \ #define MOO_BYTESOF(moo,oop) \
(MOO_OOP_IS_NUMERIC(oop)? MOO_SIZEOF(moo_oow_t): MOO_OBJ_BYTESOF(oop)) (MOO_OOP_IS_NUMERIC(oop)? MOO_SIZEOF(moo_oow_t): MOO_OBJ_BYTESOF(oop))
typedef struct moo_space_t moo_space_t;
typedef struct moo_heap_t moo_heap_t; struct moo_space_t
struct moo_heap_t
{ {
moo_uint8_t* base; /* start of a heap */ moo_uint8_t* base; /* start of a heap */
moo_uint8_t* limit; /* end of a heap */ moo_uint8_t* limit; /* end of a heap */
moo_uint8_t* ptr; /* next allocation pointer */ moo_uint8_t* ptr; /* next allocation pointer */
}; };
typedef struct moo_heap_t moo_heap_t;
struct moo_heap_t
{
moo_uint8_t* base;
moo_oow_t size;
moo_space_t permspace;
moo_space_t curspace;
moo_space_t newspace;
};
/* ========================================================================= /* =========================================================================
* MOO VM LOGGING * MOO VM LOGGING
* ========================================================================= */ * ========================================================================= */
@ -1428,9 +1440,7 @@ struct moo_t
/* ========================= */ /* ========================= */
moo_heap_t* permheap; /* TODO: put kernel objects to here */ moo_heap_t* heap;
moo_heap_t* curheap;
moo_heap_t* newheap;
/* ============================================================= /* =============================================================
* nil, true, false * nil, true, false

View File

@ -34,17 +34,17 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size)
if ((moo->option.trait & MOO_DEBUG_GC) && !(moo->option.trait & MOO_NOGC)) moo_gc (moo); if ((moo->option.trait & MOO_DEBUG_GC) && !(moo->option.trait & MOO_NOGC)) moo_gc (moo);
#endif #endif
ptr = (moo_uint8_t*)moo_allocheapmem(moo, moo->curheap, size); ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size);
if (!ptr && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_NOGC)) if (!ptr && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_NOGC))
{ {
moo_gc (moo); moo_gc (moo);
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
"GC completed - current heap ptr %p limit %p size %zd free %zd\n", "GC completed - current heap ptr %p limit %p size %zd free %zd\n",
moo->curheap->ptr, moo->curheap->limit, moo->heap->curspace.ptr, moo->heap->curspace.limit,
(moo_oow_t)(moo->curheap->limit - moo->curheap->base), (moo_oow_t)(moo->heap->curspace.limit - moo->heap->curspace.base),
(moo_oow_t)(moo->curheap->limit - moo->curheap->ptr) (moo_oow_t)(moo->heap->curspace.limit - moo->heap->curspace.ptr)
); );
ptr = (moo_uint8_t*)moo_allocheapmem(moo, moo->curheap, size); ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size);
/* TODO: grow heap if ptr is still null. */ /* TODO: grow heap if ptr is still null. */
} }