diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 7d1ce4f..32320d9 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -228,30 +228,27 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit ## create an internal semaphore for timeout notification. s := Semaphore new. - - ## grant the partial membership to the internal semaphore. - ## it's partial because it's not added to self.semarr. - ##s _group: self. self addSemaphore: s. - ## arrange the processor to notify upon timeout. - System signal: s after: seconds. - [ + ## arrange the processor to notify upon timeout. + System signal: s afterSecs: seconds. + ## wait on the semaphore group. r := self wait. ## if the internal semaphore has been signaled, ## arrange to return nil to indicate timeout. - if (r == s) { r := nil } - elsif (r signalAction notNil) { r signalAction value: r }. + if (r == s) { r := nil } ## timed out + elsif (r signalAction notNil) { r signalAction value: r }. ## run the signal action block ] ensure: [ + ## System< X << (MOO_LIW_BITS * n * 2) * -------------------------------------------------------------------- */ -#define CANNOT_KARATSUBA(xs, ys) \ + +#if !defined(NDEBUG) +#define CANNOT_KARATSUBA(moo,xs,ys) \ + ((xs) < (moo)->option.karatsuba_cutoff || (ys) < (moo)->option.karatsuba_cutoff || \ + ((xs) > (ys) && (ys) <= (((xs) + 1) / 2)) || \ + ((xs) < (ys) && (xs) <= (((ys) + 1) / 2))) +#else +#define CANNOT_KARATSUBA(moo,xs,ys) \ ((xs) < KARATSUBA_CUTOFF || (ys) < KARATSUBA_CUTOFF || \ ((xs) > (ys) && (ys) <= (((xs) + 1) / 2)) || \ ((xs) < (ys) && (xs) <= (((ys) + 1) / 2))) +#endif static MOO_INLINE moo_oow_t multiply_unsigned_array_karatsuba (moo_t* moo, const moo_liw_t* x, moo_oow_t xs, const moo_liw_t* y, moo_oow_t ys, moo_liw_t* z) { @@ -1185,7 +1185,7 @@ static MOO_INLINE moo_oow_t multiply_unsigned_array_karatsuba (moo_t* moo, const /* place (a0 + a1) * (b0 + b1) at the shifted position */ zsp = z + nshifts; - if (CANNOT_KARATSUBA(tmplen[0], tmplen[1])) + if (CANNOT_KARATSUBA(moo, tmplen[0], tmplen[1])) { multiply_unsigned_array (tmp[0], tmplen[0], tmp[1], tmplen[1], zsp); xlen = count_effective (zsp, tmplen[0] + tmplen[1]); @@ -1199,7 +1199,7 @@ static MOO_INLINE moo_oow_t multiply_unsigned_array_karatsuba (moo_t* moo, const /* tmp[0] = a0 * b0 */ tmplen[0] = ndigits_xl + ndigits_yl; MOO_MEMSET (tmp[0], 0, sizeof(moo_liw_t) * tmplen[0]); - if (CANNOT_KARATSUBA(ndigits_xl, ndigits_yl)) + if (CANNOT_KARATSUBA(moo, ndigits_xl, ndigits_yl)) { multiply_unsigned_array (x, ndigits_xl, y, ndigits_yl, tmp[0]); tmplen[0] = count_effective(tmp[0], tmplen[0]); @@ -1213,7 +1213,7 @@ static MOO_INLINE moo_oow_t multiply_unsigned_array_karatsuba (moo_t* moo, const /* tmp[1] = a1 * b1 */ tmplen[1] = ndigits_xh + ndigits_yh; MOO_MEMSET (tmp[1], 0, sizeof(moo_liw_t) * tmplen[1]); - if (CANNOT_KARATSUBA(ndigits_xh, ndigits_yh)) + if (CANNOT_KARATSUBA(moo, ndigits_xh, ndigits_yh)) { multiply_unsigned_array (x + nshifts, ndigits_xh, y + nshifts, ndigits_yh, tmp[1]); tmplen[1] = count_effective (tmp[1], tmplen[1]); @@ -1304,7 +1304,7 @@ oops: tmplen[2] = tmplen[0] + tmplen[1]; tmp[2] = moo_callocmem (moo, MOO_SIZEOF(moo_liw_t) * tmplen[2]); if (!tmp[2]) goto oops; - if (CANNOT_KARATSUBA(tmplen[0], tmplen[1])) + if (CANNOT_KARATSUBA(moo, tmplen[0], tmplen[1])) { multiply_unsigned_array (tmp[0], tmplen[0], tmp[1], tmplen[1], tmp[2]); xlen = count_effective (tmp[2], tmplen[2]); @@ -1318,7 +1318,7 @@ oops: /* tmp[0] = a0 * b0 */ tmplen[0] = ndigits_xl + ndigits_yl; MOO_MEMSET (tmp[0], 0, sizeof(moo_liw_t) * tmplen[0]); - if (CANNOT_KARATSUBA(ndigits_xl, ndigits_yl)) + if (CANNOT_KARATSUBA(moo, ndigits_xl, ndigits_yl)) { multiply_unsigned_array (x, ndigits_xl, y, ndigits_yl, tmp[0]); tmplen[0] = count_effective(tmp[0], tmplen[0]); @@ -1332,7 +1332,7 @@ oops: /* tmp[1] = a1 * b1 */ tmplen[1] = ndigits_xh + ndigits_yh; MOO_MEMSET (tmp[1], 0, sizeof(moo_liw_t) * tmplen[1]); - if (CANNOT_KARATSUBA(ndigits_xh, ndigits_yh)) + if (CANNOT_KARATSUBA(moo, ndigits_xh, ndigits_yh)) { multiply_unsigned_array (x + nshifts, ndigits_xh, y + nshifts, ndigits_yh, tmp[1]); tmplen[1] = count_effective (tmp[1], tmplen[1]); @@ -1561,7 +1561,7 @@ static moo_oop_t multiply_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t if (!z) return MOO_NULL; #if defined(ENABLE_KARATSUBA) - if (CANNOT_KARATSUBA (xs, ys)) + if (CANNOT_KARATSUBA(moo,xs, ys)) { #endif multiply_unsigned_array ( diff --git a/moo/lib/exec.c b/moo/lib/exec.c index a423763..5e4ede5 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2492,16 +2492,14 @@ static moo_pfrc_t pf_system_remove_semaphore (moo_t* moo, moo_ooi_t nargs) moo->sem_gcfin = (moo_oop_semaphore_t)moo->_nil; } - if (MOO_OOP_IS_SMOOI(sem->heap_index) && - sem->heap_index != MOO_SMOOI_TO_OOP(-1)) + if (MOO_OOP_IS_SMOOI(sem->heap_index) && sem->heap_index != MOO_SMOOI_TO_OOP(-1)) { /* the semaphore is in the timed semaphore heap */ delete_from_sem_heap (moo, MOO_OOP_TO_SMOOI(sem->heap_index)); MOO_ASSERT (moo, sem->heap_index == MOO_SMOOI_TO_OOP(-1)); } - if (MOO_OOP_IS_SMOOI(sem->io_index) && - sem->io_index != MOO_SMOOI_TO_OOP(-1)) + if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1)) { /* the semaphore is associated with IO */ if (delete_from_sem_io (moo, MOO_OOP_TO_SMOOI(sem->io_index)) <= -1) diff --git a/moo/lib/main.c b/moo/lib/main.c index ad59777..fea10f3 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -2117,6 +2117,37 @@ static int handle_logopt (moo_t* moo, const moo_bch_t* str) return 0; } +#if !defined(NDEBUG) +static int handle_dbgopt (moo_t* moo, const moo_bch_t* str) +{ + xtn_t* xtn = moo_getxtn (moo); + const moo_bch_t* cm, * flt; + moo_oow_t len; + unsigned int trait, dbgopt = 0; + + cm = str - 1; + do + { + flt = cm + 1; + + cm = moo_findbcharinbcstr(flt, ','); + len = cm? (cm - flt): moo_countbcstr(flt); + if (moo_compbcharsbcstr (flt, len, "gc") == 0) dbgopt |= MOO_DEBUG_GC; + else if (moo_compbcharsbcstr (flt, len, "bigint") == 0) dbgopt |= MOO_DEBUG_BIGINT; + /* TODO: error handling for unknown options */ + } + while (cm); + + moo_getoption (moo, MOO_TRAIT, &trait); + trait |= dbgopt; + moo_setoption (moo, MOO_TRAIT, &trait); + return 0; +} +#endif + + +#define MIN_MEMSIZE 2048000ul + int main (int argc, char* argv[]) { static moo_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' }; /*TODO: make this an argument */ @@ -2132,16 +2163,25 @@ int main (int argc, char* argv[]) moo_bci_t c; static moo_bopt_lng_t lopt[] = { - { ":log", 'l' }, - { MOO_NULL, '\0' } + { ":log", 'l' }, + { ":memsize", 'm' }, +#if !defined(NDEBUG) + { ":debug", '\0' }, /* NOTE: there is no short option for --debug */ +#endif + { MOO_NULL, '\0' } }; static moo_bopt_t opt = { - "l:", + "l:m:", lopt }; const char* logopt = MOO_NULL; + moo_oow_t memsize = MIN_MEMSIZE; + +#if !defined(NDEBUG) + const char* dbgopt = MOO_NULL; +#endif setlocale (LC_ALL, ""); @@ -2161,6 +2201,19 @@ int main (int argc, char* argv[]) logopt = opt.arg; break; + case 'm': + memsize = strtoul(opt.arg, MOO_NULL, 0); + if (memsize <= MIN_MEMSIZE) memsize = MIN_MEMSIZE; + break; + + case '\0': + if (moo_compbcstr(opt.lngopt, "debug") == 0) + { + dbgopt = opt.arg; + break; + } + goto print_usage; + case ':': if (opt.lngopt) fprintf (stderr, "bad argument for '%s'\n", opt.lngopt); @@ -2195,7 +2248,7 @@ int main (int argc, char* argv[]) lt_dlinit (); #endif - moo = moo_open (&sys_mmgr, MOO_SIZEOF(xtn_t), 2048000lu, &vmprim, MOO_NULL); + moo = moo_open (&sys_mmgr, MOO_SIZEOF(xtn_t), memsize, &vmprim, MOO_NULL); if (!moo) { fprintf (stderr, "ERROR: cannot open moo\n"); @@ -2242,6 +2295,17 @@ int main (int argc, char* argv[]) xtn->logmask = MOO_LOG_ALL_TYPES | MOO_LOG_ERROR | MOO_LOG_FATAL; } +#if !defined(NDEBUG) + if (dbgopt) + { + if (handle_dbgopt (moo, dbgopt) <= -1) + { + close_moo (moo); + return -1; + } + } +#endif + if (moo_ignite(moo) <= -1) { moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "ERROR: cannot ignite moo - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo)); diff --git a/moo/lib/moo-opt.h b/moo/lib/moo-opt.h index 490e46d..478c7a3 100644 --- a/moo/lib/moo-opt.h +++ b/moo/lib/moo-opt.h @@ -47,7 +47,7 @@ struct moo_uopt_t { /* input */ const moo_uch_t* str; /* option string */ - moo_uopt_lng_t* lng; /* long options */ + moo_uopt_lng_t* lng; /* long options */ /* output */ moo_uci_t opt; /* character checked for validity */ @@ -57,10 +57,10 @@ struct moo_uopt_t const moo_uch_t* lngopt; /* input + output */ - int ind; /* index into parent argv vector */ + int ind; /* index into parent argv vector */ /* input + output - internal*/ - moo_uch_t* cur; + moo_uch_t* cur; }; @@ -78,7 +78,7 @@ struct moo_bopt_t { /* input */ const moo_bch_t* str; /* option string */ - moo_bopt_lng_t* lng; /* long options */ + moo_bopt_lng_t* lng; /* long options */ /* output */ moo_bci_t opt; /* character checked for validity */ @@ -88,10 +88,10 @@ struct moo_bopt_t const moo_bch_t* lngopt; /* input + output */ - int ind; /* index into parent argv vector */ + int ind; /* index into parent argv vector */ /* input + output - internal*/ - moo_bch_t* cur; + moo_bch_t* cur; }; #if defined(__cplusplus) diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 96585db..04d63ce 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -44,9 +44,12 @@ * PUSH_CONTEXT, PUSH_INTLIT, PUSH_INTLIT, SEND_BLOCK_COPY */ #define MOO_USE_MAKE_BLOCK +/* define this to enable karatsuba multiplication in bigint */ +#define MOO_ENABLE_KARATSUBA +#define MOO_KARATSUBA_CUTOFF 32 +#define MOO_KARATSUBA_CUTOFF_DEBUG 3 + #if !defined(NDEBUG) -/* this is for gc debugging */ -#define MOO_DEBUG_GC 1 /*#define MOO_DEBUG_LEXER 1*/ #define MOO_DEBUG_COMPILER 1 #define MOO_DEBUG_VM_PROCESSOR 1 @@ -55,6 +58,9 @@ #define MOO_PROFILE_VM 1 #endif + + + /* allow the caller to drive process switching by calling * moo_switchprocess(). */ #define MOO_EXTERNAL_PROCESS_SWITCH diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 5485855..1689ebd 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -96,6 +96,9 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t moo->option.dfl_symtab_size = MOO_DFL_SYMTAB_SIZE; moo->option.dfl_sysdic_size = MOO_DFL_SYSDIC_SIZE; moo->option.dfl_procstk_size = MOO_DFL_PROCSTK_SIZE; +#if !defined(NDEBUG) + moo->option.karatsuba_cutoff = MOO_KARATSUBA_CUTOFF; +#endif moo->log.capa = MOO_ALIGN_POW2(1, MOO_LOG_CAPA_ALIGN); /* TODO: is this a good initial size? */ /* alloate the log buffer in advance though it may get reallocated @@ -244,6 +247,9 @@ int moo_setoption (moo_t* moo, moo_option_t id, const void* value) { case MOO_TRAIT: moo->option.trait = *(const unsigned int*)value; + #if !defined(NDEBUG) + moo->option.karatsuba_cutoff = ((moo->option.trait & MOO_DEBUG_BIGINT)? MOO_KARATSUBA_CUTOFF_DEBUG: MOO_KARATSUBA_CUTOFF); + #endif return 0; case MOO_LOG_MASK: diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 878bab0..313f161 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -113,12 +113,17 @@ typedef enum moo_option_dflval_t moo_option_dflval_t; enum moo_trait_t { +#if !defined(NDEBUG) + MOO_DEBUG_GC = (1 << 0), + MOO_DEBUG_BIGINT = (1 << 1), +#endif + /* perform no garbage collection when the heap is full. * you still can use moo_gc() explicitly. */ - MOO_NOGC = (1 << 0), + MOO_NOGC = (1 << 8), /* wait for running process when exiting from the main method */ - MOO_AWAIT_PROCS = (1 << 1) + MOO_AWAIT_PROCS = (1 << 9) }; typedef enum moo_trait_t moo_trait_t; @@ -1130,6 +1135,11 @@ struct moo_t moo_oow_t dfl_symtab_size; moo_oow_t dfl_sysdic_size; moo_oow_t dfl_procstk_size; + +#if !defined(NDEBUG) + /* set automatically when trait is set */ + int karatsuba_cutoff; +#endif } option; moo_vmprim_t vmprim; diff --git a/moo/lib/obj.c b/moo/lib/obj.c index 3b5f13f..e8e59fe 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -30,8 +30,8 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size) { moo_uint8_t* ptr; -#if defined(MOO_DEBUG_GC) - if (!(moo->option.trait & MOO_NOGC)) moo_gc (moo); +#if !defined(NDEBUG) + if ((moo->option.trait &MOO_DEBUG_GC) && !(moo->option.trait & MOO_NOGC)) moo_gc (moo); #endif ptr = moo_allocheapmem (moo, moo->curheap, size); diff --git a/moo/lib/opt-impl.h b/moo/lib/opt-impl.h index a2d050c..19e2d1b 100644 --- a/moo/lib/opt-impl.h +++ b/moo/lib/opt-impl.h @@ -1,9 +1,3 @@ - -/* this file is supposed to be included by opt.c multiple times */ - - - - /* * $Id$ * @@ -30,6 +24,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +/* this file is supposed to be included by opt.c multiple times */ + + #include "moo-opt.h" #include "moo-utl.h"