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:
parent
4de478a9cc
commit
1cffec34e8
30
moo/lib/gc.c
30
moo/lib/gc.c
@ -579,13 +579,9 @@ int moo_ignite (moo_t* moo, moo_oow_t heapsz)
|
||||
{
|
||||
MOO_ASSERT (moo, moo->_nil == MOO_NULL);
|
||||
|
||||
/*moo->permheap = moo_makeheap (moo, what is the best size???);
|
||||
if (!moo->permheap) goto oops; */
|
||||
if (moo->curheap) moo_killheap (moo, moo->curheap);
|
||||
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;
|
||||
if (moo->heap) moo_killheap (moo, moo->heap);
|
||||
moo->heap = moo_makeheap(moo, heapsz);
|
||||
if (!moo->heap) return -1;
|
||||
|
||||
moo->_nil = moo_allocbytes (moo, MOO_SIZEOF(moo_obj_t));
|
||||
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);
|
||||
|
||||
/* 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
|
||||
* 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)
|
||||
{
|
||||
while (ptr < moo->newheap->ptr)
|
||||
while (ptr < moo->heap->newspace.ptr)
|
||||
{
|
||||
moo_oow_t i;
|
||||
moo_oow_t nbytes_aligned;
|
||||
@ -863,7 +859,7 @@ void moo_gc (moo_t* moo)
|
||||
* finally perform some tricky symbol table clean-up.
|
||||
*/
|
||||
moo_uint8_t* scan_ptr;
|
||||
moo_heap_t* tmp;
|
||||
moo_space_t tmp;
|
||||
moo_oop_t old_nil;
|
||||
moo_oow_t i;
|
||||
moo_evtcb_t* cb;
|
||||
@ -884,9 +880,9 @@ void moo_gc (moo_t* moo)
|
||||
|
||||
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
||||
"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
|
||||
* 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.
|
||||
* reset the upper bound to the base. don't forget to align the heap
|
||||
* 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 */
|
||||
tmp = moo->curheap;
|
||||
moo->curheap = moo->newheap;
|
||||
moo->newheap = tmp;
|
||||
tmp = moo->heap->curspace;
|
||||
moo->heap->curspace = moo->heap->newspace;
|
||||
moo->heap->newspace = tmp;
|
||||
|
||||
/*
|
||||
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 */
|
||||
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
||||
"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)
|
||||
|
@ -29,6 +29,10 @@
|
||||
moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
heap->base = (moo_uint8_t*)(heap + 1);
|
||||
/* adjust the initial allocation pointer to a multiple of the oop size */
|
||||
heap->ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)heap->base), MOO_SIZEOF(moo_oop_t));
|
||||
heap->limit = heap->base + size;
|
||||
heap->size = size;
|
||||
|
||||
MOO_ASSERT (moo, heap->ptr >= heap->base);
|
||||
MOO_ASSERT (moo, heap->limit >= heap->base );
|
||||
MOO_ASSERT (moo, heap->limit - heap->base == size);
|
||||
heap->curspace.base= (moo_uint8_t*)(heap + 1);
|
||||
heap->curspace.ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)heap->curspace.base), MOO_SIZEOF(moo_oop_t));
|
||||
heap->curspace.limit = heap->curspace.ptr + half_size;
|
||||
|
||||
/* if size is too small, heap->ptr may go past heap->limit even at
|
||||
* this moment depending on the alignment of heap->base. subsequent
|
||||
* calls to submoo_allocheapmem() are bound to fail. Make sure to
|
||||
heap->newspace.base = (moo_uint8_t*)(heap + 1) + half_size;
|
||||
heap->newspace.ptr = (moo_uint8_t*)MOO_ALIGN(((moo_uintptr_t)heap->newspace.base), MOO_SIZEOF(moo_oop_t));
|
||||
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 */
|
||||
|
||||
return heap;
|
||||
@ -62,22 +67,22 @@ void moo_killheap (moo_t* moo, moo_heap_t* 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;
|
||||
|
||||
/* check the heap size limit */
|
||||
if (heap->ptr >= heap->limit || heap->limit - heap->ptr < size)
|
||||
/* check the space size limit */
|
||||
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",
|
||||
size, heap->ptr, heap->limit, (moo_oow_t)(heap->limit - heap->base), (moo_oow_t)(heap->limit - heap->ptr));
|
||||
MOO_DEBUG5 (moo, "Cannot allocate %zd bytes from space - ptr %p limit %p size %zd free %zd\n",
|
||||
size, space->ptr, space->limit, (moo_oow_t)(space->limit - space->base), (moo_oow_t)(space->limit - space->ptr));
|
||||
moo_seterrnum (moo, MOO_EOOMEM);
|
||||
return MOO_NULL;
|
||||
}
|
||||
|
||||
/* allocation is as simple as moving the heap pointer */
|
||||
ptr = heap->ptr;
|
||||
heap->ptr += size;
|
||||
/* allocation is as simple as moving the space pointer */
|
||||
ptr = space->ptr;
|
||||
space->ptr += size;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
@ -1073,14 +1073,14 @@ 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.
|
||||
*
|
||||
* \return memory pointer on success and #MOO_NULL on failure.
|
||||
*/
|
||||
void* moo_allocheapmem (
|
||||
void* moo_allocheapspace (
|
||||
moo_t* moo,
|
||||
moo_heap_t* heap,
|
||||
moo_space_t* space,
|
||||
moo_oow_t size
|
||||
);
|
||||
|
||||
|
@ -247,9 +247,7 @@ void moo_fini (moo_t* moo)
|
||||
|
||||
/* if the moo object is closed without moo_ignite(),
|
||||
* the heap may not exist */
|
||||
if (moo->newheap) moo_killheap (moo, moo->newheap);
|
||||
if (moo->curheap) moo_killheap (moo, moo->curheap);
|
||||
if (moo->permheap) moo_killheap (moo, moo->permheap);
|
||||
if (moo->heap) moo_killheap (moo, moo->heap);
|
||||
|
||||
for (i = 0; i < MOO_COUNTOF(moo->sbuf); i++)
|
||||
{
|
||||
|
@ -963,16 +963,28 @@ struct moo_process_scheduler_t
|
||||
#define MOO_BYTESOF(moo,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_heap_t
|
||||
struct moo_space_t
|
||||
{
|
||||
moo_uint8_t* base; /* start of a heap */
|
||||
moo_uint8_t* limit; /* end of a heap */
|
||||
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
|
||||
* ========================================================================= */
|
||||
@ -1428,9 +1440,7 @@ struct moo_t
|
||||
|
||||
/* ========================= */
|
||||
|
||||
moo_heap_t* permheap; /* TODO: put kernel objects to here */
|
||||
moo_heap_t* curheap;
|
||||
moo_heap_t* newheap;
|
||||
moo_heap_t* heap;
|
||||
|
||||
/* =============================================================
|
||||
* nil, true, false
|
||||
|
@ -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);
|
||||
#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))
|
||||
{
|
||||
moo_gc (moo);
|
||||
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
||||
"GC completed - current heap ptr %p limit %p size %zd free %zd\n",
|
||||
moo->curheap->ptr, moo->curheap->limit,
|
||||
(moo_oow_t)(moo->curheap->limit - moo->curheap->base),
|
||||
(moo_oow_t)(moo->curheap->limit - moo->curheap->ptr)
|
||||
moo->heap->curspace.ptr, moo->heap->curspace.limit,
|
||||
(moo_oow_t)(moo->heap->curspace.limit - moo->heap->curspace.base),
|
||||
(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. */
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user