diff --git a/moo/lib/gc.c b/moo/lib/gc.c index a37776d..2d7f1ff 100644 --- a/moo/lib/gc.c +++ b/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) diff --git a/moo/lib/heap.c b/moo/lib/heap.c index 14bd699..1369bc4 100644 --- a/moo/lib/heap.c +++ b/moo/lib/heap.c @@ -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; } diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index e37d1b3..b343089 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -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. * * \return memory pointer on success and #MOO_NULL on failure. */ -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 ); /* ========================================================================= */ diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 8ee7190..fd82c28 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -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++) { diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 317bd6a..48706ac 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -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 diff --git a/moo/lib/obj.c b/moo/lib/obj.c index cd901f6..f7bfe9a 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -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. */ }