diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 910f903..0e00a3a 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1629,7 +1629,7 @@ static moo_oop_process_t start_initial_process (moo_t* moo, moo_oop_context_t c) MOO_ASSERT (moo, moo->processor->active == moo->nil_process); proc = make_process(moo, c, MOO_OBJ_FLAGS_PROC_INNATE); - if (!proc) return MOO_NULL; + if (MOO_UNLIKELY(!proc)) return MOO_NULL; chain_into_processor (moo, proc, PROC_STATE_RUNNING); moo->processor->active = proc; @@ -1666,7 +1666,7 @@ static MOO_INLINE int activate_new_method (moo_t* moo, moo_oop_method_t mth, moo moo_pushvolat (moo, (moo_oop_t*)&mth); ctx = (moo_oop_context_t)moo_instantiate(moo, moo->_method_context, MOO_NULL, actual_ntmprs); moo_popvolat (moo); - if (!ctx) return -1; + if (MOO_UNLIKELY(!ctx)) return -1; MOO_STORE_OOP (moo, (moo_oop_t*)&ctx->sender, (moo_oop_t)moo->active_context); ctx->ip = MOO_SMOOI_TO_OOP(0); @@ -1968,7 +1968,7 @@ static int start_initial_process_and_context (moo_t* moo, const moo_oocs_t* objn moo_oop_process_t proc; moo_oow_t tmp_count = 0; moo_oop_t sym_startup; - + #if defined(INVOKE_DIRECTLY) moo_oop_association_t ass; #else @@ -1984,7 +1984,7 @@ static int start_initial_process_and_context (moo_t* moo, const moo_oocs_t* objn MOO_LOG2 (moo, MOO_LOG_DEBUG, "Cannot find a class '%.*js'", objname->len, objname->ptr); return -1; } - + sym_statup = moo_findsymbol(moo, mthname->ptr, mthname->len; if (!sym_startup) { @@ -2476,7 +2476,7 @@ static moo_pfrc_t pf_method_get_ip_source_line (moo_t* moo, moo_mod_t* mod, moo_ if (ipv < di->code_loc_len && code_loc_ptr[ipv] <= MOO_SMOOI_MAX) { retv = moo_oowtoint(moo, code_loc_ptr[ipv]); - if (!retv) return MOO_PF_FAILURE; + if (MOO_UNLIKELY(!retv)) return MOO_PF_FAILURE; } } @@ -5258,16 +5258,17 @@ static MOO_INLINE int do_return (moo_t* moo, moo_oob_t bcode, moo_oop_t return_v { unwind_protect = 0; - /* set the instruction pointer to an invalid value. - * this is stored into the current method context - * before context switching and marks a dead context */ + if (moo->active_context->origin == moo->active_context) { /* returning from a method */ MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->active_context) == moo->_method_context); - /* mark that the context is dead. it will be - * save to the context object by SWITCH_ACTIVE_CONTEXT() */ + + /* set the instruction pointer to an invalid value. + * this is stored into the current method context + * before context switching by SWITCH_ACTIVE_CONTEXT() + * and marks the context dead */ moo->ip = -1; } else diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 6f051c3..525f741 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -514,7 +514,7 @@ static int ignite_2 (moo_t* moo) /* Create 'true' and 'false objects */ moo->_true = moo_instantiate(moo, moo->_true_class, MOO_NULL, 0); moo->_false = moo_instantiate(moo, moo->_false_class, MOO_NULL, 0); - if (!moo->_true || !moo->_false) return -1; + if (MOO_UNLIKELY(!moo->_true) || MOO_UNLIKELY(!moo->_false)) return -1; /* Prevent the object instations in the permspace. * @@ -537,7 +537,7 @@ static int ignite_2 (moo_t* moo) /* Create the symbol table */ tmp = moo_instantiate(moo, moo->_symbol_table, MOO_NULL, 0); - if (!tmp) return -1; + if (MOO_UNLIKELY(!tmp)) return -1; moo->symtab = (moo_oop_dic_t)tmp; moo->symtab->tally = MOO_SMOOI_TO_OOP(0); @@ -937,6 +937,11 @@ static moo_rbt_walk_t call_module_gc (moo_rbt_t* rbt, moo_rbt_pair_t* pair, void void moo_gc (moo_t* moo) { +#if defined(MOO_ENABLE_GC_MARK_SWEEP) + /* TODO: */ + + +#else /* * move a referenced object to the new heap. * inspect the fields of the moved object in the new heap. @@ -1103,6 +1108,7 @@ void moo_gc (moo_t* moo) MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, "Finished GC curheap base %p ptr %p newheap base %p ptr %p\n", moo->heap->curspace.base, moo->heap->curspace.ptr, moo->heap->newspace.base, moo->heap->newspace.ptr); +#endif } void moo_pushvolat (moo_t* moo, moo_oop_t* oop_ptr) diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 4ed34c3..afb263e 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -720,7 +720,6 @@ struct moo_compiler_t # error Unsupported MOO_BCODE_LONG_PARAM_SIZE #endif - /* ---------------------------------------------------------------------------------------------------------------- SHORT INSTRUCTION CODE LONG INSTRUCTION CODE diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 5779ec0..8bbe6b0 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -34,6 +34,9 @@ /* TODO: move this macro out to the build files.... */ #define MOO_INCLUDE_COMPILER +/*#define MOO_ENABLE_GC_MARK_SWEEP*/ + + typedef struct moo_mod_t moo_mod_t; /* ========================================================================== */ @@ -198,6 +201,19 @@ enum moo_method_type_t }; typedef enum moo_method_type_t moo_method_type_t; + +/* ========================================================================= + * HEADER FOR SOME GC IMPLEMENTATIONS + * ========================================================================= */ +#if defined(MOO_ENABLE_GC_MARK_SWEEP) +typedef struct moo_gchdr_t moo_gchdr_t; +struct moo_gchdr_t +{ + moo_gchdr_t* next; +}; +/* The size of moo_gchdr_t must be aligned to MOO_SIZEOF_OOP_T */ +#endif + /* ========================================================================= * OBJECT STRUCTURE * ========================================================================= */ @@ -1780,6 +1796,10 @@ struct moo_t moo_uintmax_t inst_counter; } stat; +#if defined(MOO_ENABLE_GC_MARK_SWEEP) + moo_gchdr_t* gch; +#endif + #if defined(MOO_INCLUDE_COMPILER) moo_compiler_t* c; #endif diff --git a/moo/lib/obj.c b/moo/lib/obj.c index 500ddde..693773b 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -29,11 +29,38 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size) { moo_uint8_t* ptr; +#if defined(MOO_ENABLE_GC_MARK_SWEEP) + moo_gchdr_t* gch; +#endif #if defined(MOO_BUILD_DEBUG) if ((moo->option.trait & MOO_TRAIT_DEBUG_GC) && !(moo->option.trait & MOO_TRAIT_NOGC)) moo_gc (moo); #endif +#if defined(MOO_ENABLE_GC_MARK_SWEEP) + if (MOO_UNLIKELY(moo->igniting)) + { + gch = (moo_gchdr_t*)moo_allocmem(moo, MOO_SIZEOF(*gch) + size); + if (MOO_UNLIKELY(!gch)) return MOO_NULL; + } + else + { +// TODO: perform GC if allocation got above threshold... + gch = (moo_gchdr_t*)moo_allocmem(moo, MOO_SIZEOF(*gch) + size); + if (!gch && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC)) + { + moo_gc (moo); + MOO_LOG0 (moo, MOO_LOG_GC | MOO_LOG_INFO, "GC completed\n"); /* TODO: add more inforamtion */ + gch = (moo_gchdr_t*)moo_allocmem(moo, MOO_SIZEOF(*gch) + size); + if (MOO_UNLIKELY(!gch)) return MOO_NULL; + } + } + + gch->next = moo->gch; + moo->gch = gch; + + ptr = (moo_uint8_t*)(gch + 1); +#else if (MOO_UNLIKELY(moo->igniting)) { /* you must increase the size of the permspace if this allocation fails */ @@ -55,6 +82,8 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size) /* TODO: grow heap if ptr is still null. */ } } +#endif + return ptr; } @@ -74,7 +103,7 @@ moo_oop_t moo_allocoopobj (moo_t* moo, moo_oow_t size) * of the allocated space to be an even number. * see MOO_OOP_IS_NUMERIC() and MOO_OOP_IS_POINTER() */ hdr = (moo_oop_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); - if (!hdr) return MOO_NULL; + if (MOO_UNLIKELY(!hdr)) return MOO_NULL; hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 0, 0, 0); MOO_OBJ_SET_SIZE (hdr, size);