diff --git a/source/m3.h b/source/m3.h index a6f3393..4a249f4 100644 --- a/source/m3.h +++ b/source/m3.h @@ -244,10 +244,13 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref); // LoadModule transfers ownership of a module to the runtime. Do not free modules once successfully imported into the runtime. + typedef const void * (* M3RawCall) (IM3Runtime runtime, uint64_t * _sp, void * _mem); + + M3Result m3_LinkRawFunction (IM3Module io_module, const char * const i_moduleName, const char * const i_functionName, - const void * const i_function); // void (u64 * _sp, u8 * _mem) + M3RawCall i_function); // void (u64 * _sp, u8 * _mem) diff --git a/source/m3_bind.c b/source/m3_bind.c index 50e81f7..09ceb15 100644 --- a/source/m3_bind.c +++ b/source/m3_bind.c @@ -30,8 +30,6 @@ M3State; typedef m3ret_t (* M3ArgPusher) (d_m3BindingArgList, M3State * i_state); typedef f64 (* M3ArgPusherFpReturn) (d_m3BindingArgList, M3State * i_state); -typedef m3ret_t (* M3RawCall) (IM3Runtime runtime, u64 * _sp, void * _mem); - m3ret_t PushArg_runtime (d_m3BindingArgList, M3State * _state) { @@ -259,9 +257,11 @@ M3Result m3_RegisterFunction (IM3Runtime io_runtime, const char * const i_fun } +typedef M3Result (* M3Linker) (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function); + -M3Result LinkFunction (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function) +M3Result LinkCFunction (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function) { M3Result result = c_m3Err_none; @@ -359,11 +359,12 @@ M3Result LinkFunction (IM3Module io_module, IM3Function io_function, const c } -M3Result m3_LinkCFunction (IM3Module io_module, - const char * const i_moduleName, - const char * const i_functionName, - const char * const i_signature, - const void * i_function) +M3Result FindAndLinkFunction (IM3Module io_module, + ccstr_t i_moduleName, + ccstr_t i_functionName, + ccstr_t i_signature, + voidptr_t i_function, + const M3Linker i_linker) { M3Result result = c_m3Err_functionLookupFailed; @@ -376,40 +377,42 @@ M3Result m3_LinkCFunction (IM3Module io_module, if (strcmp (f->import.fieldUtf8, i_functionName) == 0 and strcmp (f->import.moduleUtf8, i_moduleName) == 0) { - result = LinkFunction (io_module, f, i_signature, i_function); + result = i_linker (io_module, f, i_signature, i_function); } } } - + return result; } -// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -d_m3RetSig CallRawFunction (d_m3OpSig) +M3Result m3_LinkCFunction (IM3Module io_module, + const char * const i_moduleName, + const char * const i_functionName, + const char * const i_signature, + const void * i_function) { - M3RawCall call = (M3RawCall) (* _pc++); - IM3Runtime runtime = (IM3Runtime) (* _pc++); - m3ret_t possible_trap = call (runtime, _sp, _mem); - return possible_trap; + return FindAndLinkFunction (io_module, i_moduleName, i_functionName, i_signature, i_function, LinkCFunction); } -M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, const void * i_function) +// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + +M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, ccstr_t i_signature, const void * i_function) { M3Result result = c_m3Err_none; d_m3Assert (io_module->runtime); - IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, 3); + IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, 2); if (page) { io_function->compiled = GetPagePC (page); io_function->module = io_module; - EmitWord (page, CallRawFunction); + EmitWord (page, op_CallRawFunction); EmitWord (page, i_function); - EmitWord (page, io_module->runtime); ReleaseCodePage (io_module->runtime, page); } @@ -419,30 +422,13 @@ M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, cons } -M3Result m3_LinkRawFunction (IM3Module io_module, - const char * const i_moduleName, - const char * const i_functionName, - const void * i_function) +M3Result m3_LinkRawFunction (IM3Module io_module, + const char * const i_moduleName, + const char * const i_functionName, + M3RawCall i_function) { - M3Result result = c_m3Err_functionLookupFailed; - - for (u32 i = 0; i < io_module->numFunctions; ++i) - { - IM3Function f = & io_module->functions [i]; - - if (f->import.moduleUtf8 and f->import.fieldUtf8) - { - if (strcmp (f->import.fieldUtf8, i_functionName) == 0 and - strcmp (f->import.moduleUtf8, i_moduleName) == 0) - { - result = LinkRawFunction (io_module, f, i_function); - } - } - } - - return result; + return FindAndLinkFunction (io_module, i_moduleName, i_functionName, NULL, i_function, LinkRawFunction); } - diff --git a/source/m3_core.h b/source/m3_core.h index 05d9ca9..35d099f 100644 --- a/source/m3_core.h +++ b/source/m3_core.h @@ -28,6 +28,7 @@ typedef int8_t i8; typedef const void * m3ret_t; +typedef const void * voidptr_t; typedef const char * cstr_t; typedef const char * const ccstr_t; typedef const u8 * bytes_t; @@ -140,7 +141,7 @@ typedef struct M3CodePageHeader M3CodePageHeader; -#define c_m3CodePageFreeLinesThreshold 10 +#define c_m3CodePageFreeLinesThreshold 4 // max is probably: select _sss #define c_m3MemPageSize 65536 #define c_m3MaxFunctionStackHeight d_m3MaxFunctionStackHeight @@ -152,7 +153,6 @@ M3CodePageHeader; #define c_m3AlignWasmMemoryToPages d_m3AlignWasmMemoryToPages -//#define c_m3MaxSaneWasmSize 1000000000 #define c_m3MaxSaneUtf8Length 2000 #define c_m3MaxNumFunctionArgs d_m3MaxNumFunctionArgs diff --git a/source/m3_emit.c b/source/m3_emit.c index db4f54e..8a0aea9 100644 --- a/source/m3_emit.c +++ b/source/m3_emit.c @@ -21,9 +21,10 @@ M3Result EnsureCodePageNumLines (IM3Compilation o, u32 i_numLines) if (page) { + d_m3Assert (NumFreeLines (o->page) >= 2); m3log (emit, "bridging new code page from: %d %p (free slots: %d) to: %d", o->page->info.sequence, GetPC (o), NumFreeLines (o->page), page->info.sequence); - - EmitWord (o->page, op_Bridge); d_m3Assert (NumFreeLines (o->page) >= 2); + + EmitWord (o->page, op_Bridge); EmitWord (o->page, GetPagePC (page)); ReleaseCodePage (o->runtime, o->page); @@ -40,21 +41,7 @@ M3Result EnsureCodePageNumLines (IM3Compilation o, u32 i_numLines) // have execution jump to a new page if slots are critically low M3Result BridgeToNewPageIfNecessary (IM3Compilation o) { - return EnsureCodePageNumLines (o, c_m3CodePageFreeLinesThreshold - 2); -} - - -void log_emit (IM3Compilation o, IM3Operation i_operation) -{ -# if DEBUG - OpInfo i = find_operation_info (i_operation); - - if (i.info) - { - printf ("%p: %s", GetPC (o), i.info->name); - } - else printf ("not found: %p", i_operation); -# endif + return EnsureCodePageNumLines (o, c_m3CodePageFreeLinesThreshold); } diff --git a/source/m3_env.h b/source/m3_env.h index 41c6720..c3e96bc 100644 --- a/source/m3_env.h +++ b/source/m3_env.h @@ -219,8 +219,6 @@ typedef struct M3Runtime M3Memory memory; M3ErrorInfo error; - - } M3Runtime; diff --git a/source/m3_exec.c b/source/m3_exec.c index 5b31444..894576d 100644 --- a/source/m3_exec.c +++ b/source/m3_exec.c @@ -54,9 +54,6 @@ void ReportError2 (IM3Function i_function, m3ret_t i_result) } - - - d_m3OpDef (Call) { pc_t callPC = immediate (pc_t); @@ -138,6 +135,16 @@ d_m3OpDef (CallIndirect) } +d_m3OpDef (CallRawFunction) +{ + M3RawCall call = (M3RawCall) (* _pc++); + IM3Runtime runtime = GetRuntime (_mem); + + m3ret_t possible_trap = call (runtime, _sp, _mem); + return possible_trap; +} + + d_m3OpDef (MemCurrent) { // TODO: get memory from _mem, so that compiled code isn't tied to a specific runtime @@ -205,7 +212,7 @@ d_m3OpDef (Compile) d_m3OpDef (Entry) { - M3MemoryHeader * header = (M3MemoryHeader *) _mem - 1; + M3MemoryHeader * header = GetMemoryHeader (_mem); if ((void *) _sp <= header->maxStack) { @@ -242,78 +249,6 @@ d_m3OpDef (Entry) } -#if d_m3RuntimeStackDumps -d_m3OpDef (DumpStack) -{ - u32 opcodeIndex = immediate (u32); - u64 stackHeight = immediate (u64); - IM3Function function = immediate (IM3Function); - - cstr_t funcName = (function) ? function->name : ""; - - printf (" %4d ", opcodeIndex); - printf (" %-25s r0: 0x%016" PRIx64 " i:%" PRIi64 " u:%" PRIu64 "\n", funcName, _r0, _r0, _r0); - printf (" fp0: %lf \n", _fp0); - - u64 * sp = _sp; - - for (u32 i = 0; i < stackHeight; ++i) - { - printf ("%016llx ", (u64) sp); - - cstr_t kind = ""; - - printf ("%5s %2d: 0x%" PRIx64 " %" PRIi64 "\n", kind, i, (u64) *(sp), (i64) *sp); - - ++sp; - } - printf ("---------------------------------------------------------------------------------------------------------\n"); - - return nextOpDirect(); -} -#endif - - - -# if d_m3EnableOpProfiling -M3ProfilerSlot s_opProfilerCounts [c_m3ProfilerSlotMask] = {}; - - -void ProfileHit (cstr_t i_operationName) -{ - u64 ptr = (u64) i_operationName; - - M3ProfilerSlot * slot = & s_opProfilerCounts [ptr & c_m3ProfilerSlotMask]; - - if (slot->opName) - { - if (slot->opName != i_operationName) - { - printf ("**** profiler slot collision; increase mask width\n"); - m3NotImplemented (); - } - } - - slot->opName = i_operationName; - slot->hitCount++; -} -# endif - - -void m3_PrintProfilerInfo () -{ - # if d_m3EnableOpProfiling - for (u32 i = 0; i <= c_m3ProfilerSlotMask; ++i) - { - M3ProfilerSlot * slot = & s_opProfilerCounts [i]; - - if (slot->opName) - printf ("%13llu %s\n", slot->hitCount, slot->opName); - } - # endif -} - - d_m3OpDef (GetGlobal) { i64 * global = immediate (i64 *); @@ -412,3 +347,89 @@ d_m3OpDef (BranchTable) return jumpOp (branches [branchIndex]); } + + +d_m3OpDef (CopySlot_64) +{ + u64 * dst = slot_ptr (u64); + u64 * src = slot_ptr (u64); + + * dst = * src; // printf ("copy: %p <- %" PRIi64 " <- %p\n", dst, * dst, src); + + return nextOp (); +} + + + +#if d_m3RuntimeStackDumps +//-------------------------------------------------------------------------------------------------------- +d_m3OpDef (DumpStack) +{ + u32 opcodeIndex = immediate (u32); + u64 stackHeight = immediate (u64); + IM3Function function = immediate (IM3Function); + + cstr_t funcName = (function) ? function->name : ""; + + printf (" %4d ", opcodeIndex); + printf (" %-25s r0: 0x%016" PRIx64 " i:%" PRIi64 " u:%" PRIu64 "\n", funcName, _r0, _r0, _r0); + printf (" fp0: %lf \n", _fp0); + + u64 * sp = _sp; + + for (u32 i = 0; i < stackHeight; ++i) + { + printf ("%016llx ", (u64) sp); + + cstr_t kind = ""; + + printf ("%5s %2d: 0x%" PRIx64 " %" PRIi64 "\n", kind, i, (u64) *(sp), (i64) *sp); + + ++sp; + } + printf ("---------------------------------------------------------------------------------------------------------\n"); + + return nextOpDirect(); +} +#endif + + +# if d_m3EnableOpProfiling +//-------------------------------------------------------------------------------------------------------- +M3ProfilerSlot s_opProfilerCounts [c_m3ProfilerSlotMask] = {}; + +void ProfileHit (cstr_t i_operationName) +{ + u64 ptr = (u64) i_operationName; + + M3ProfilerSlot * slot = & s_opProfilerCounts [ptr & c_m3ProfilerSlotMask]; + + if (slot->opName) + { + if (slot->opName != i_operationName) + { + printf ("**** profiler slot collision; increase mask width\n"); + m3NotImplemented (); + } + } + + slot->opName = i_operationName; + slot->hitCount++; +} + +void m3_PrintProfilerInfo () +{ + for (u32 i = 0; i <= c_m3ProfilerSlotMask; ++i) + { + M3ProfilerSlot * slot = & s_opProfilerCounts [i]; + + if (slot->opName) + printf ("%13llu %s\n", slot->hitCount, slot->opName); + } +} + +# else + +void m3_PrintProfilerInfo () {} + +# endif diff --git a/source/m3_exec.h b/source/m3_exec.h index baab358..ea91912 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -39,14 +39,16 @@ # define constant64(TYPE) * ((TYPE *) _pc++) #endif - #define nextOpDirect() ((IM3Operation)(* _pc))(_pc + 1, d_m3OpArgs) #define jumpOpDirect(PC) ((IM3Operation)(* PC))( PC + 1, d_m3OpArgs) # if d_m3EnableOpProfiling -# define nextOp() profileOp (d_m3OpAllArgs, __PRETTY_FUNCTION__) + +d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName); + +# define nextOp() profileOp (d_m3OpAllArgs, __FUNCTION__) # elif d_m3TraceExec -# define nextOp() debugOp (d_m3OpAllArgs, __PRETTY_FUNCTION__) +# define nextOp() debugOp (d_m3OpAllArgs, __FUNCTION__) # else # define nextOp() nextOpDirect() # endif @@ -59,44 +61,6 @@ d_m3RetSig Call (d_m3OpSig) return nextOpDirect(); } - -d_m3RetSig debugOp (d_m3OpSig, cstr_t i_opcode) -{ - char name [100]; - strcpy (name, strstr (i_opcode, "op_") + 3); - char * bracket = strstr (name, "("); - if (bracket) { - *bracket = 0; - } - - puts (name); - return nextOpDirect(); -} - -static const u32 c_m3ProfilerSlotMask = 0xFFFF; - -typedef struct M3ProfilerSlot -{ - cstr_t opName; - u64 hitCount; -} -M3ProfilerSlot; - -void ProfileHit (cstr_t i_operationName); - -d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName) -{ - ProfileHit (i_operationName); - - return nextOpDirect(); -} - -#if d_m3RuntimeStackDumps -d_m3OpDecl (DumpStack) -#endif - - - // TODO: OK, this needs some explanation here ;0 #define d_m3CommutativeOpMacro(RES, REG, TYPE, NAME, OP, ...) \ @@ -615,6 +579,7 @@ d_m3Op (ContinueLoopIf) d_m3OpDecl (Compile) d_m3OpDecl (Call) d_m3OpDecl (CallIndirect) +d_m3OpDecl (CallRawFunction) d_m3OpDecl (Entry) d_m3OpDecl (MemCurrent) @@ -676,15 +641,8 @@ d_m3Op (SetGlobal_f64) } -d_m3Op (CopySlot_64) -{ - u64 * dst = slot_ptr (u64); - u64 * src = slot_ptr (u64); - - * dst = * src; // printf ("copy: %p <- %" PRIi64 " <- %p\n", dst, * dst, src); - return nextOp (); -} +d_m3OpDecl (CopySlot_64) d_m3Op (PreserveCopySlot_64) @@ -900,4 +858,48 @@ d_m3Store_i (i64, i64) # endif +//--------------------------------------------------------------------------------------------------------------------- +// debug/profiling +//--------------------------------------------------------------------------------------------------------------------- +#if d_m3TraceExec +d_m3RetSig debugOp (d_m3OpSig, cstr_t i_opcode) +{ + char name [100]; + strcpy (name, strstr (i_opcode, "op_") + 3); + char * bracket = strstr (name, "("); + if (bracket) { + *bracket = 0; + } + + puts (name); + return nextOpDirect(); +} +# endif + +# if d_m3RuntimeStackDumps +d_m3OpDecl (DumpStack) +# endif + +# if d_m3EnableOpProfiling +static const u32 c_m3ProfilerSlotMask = 0xFFFF; + +typedef struct M3ProfilerSlot +{ + cstr_t opName; + u64 hitCount; +} +M3ProfilerSlot; + +void ProfileHit (cstr_t i_operationName); + +d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName) +{ + ProfileHit (i_operationName); + + return nextOpDirect(); +} +# endif + + + #endif /* m3_exec_h */ diff --git a/source/m3_info.c b/source/m3_info.c index 22042fa..2e509cc 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -403,6 +403,7 @@ void log_opcode (IM3Compilation o, u8 i_opcode) u16 GetMaxExecSlot (IM3Compilation o); + void emit_stack_dump (IM3Compilation o) { # if d_m3RuntimeStackDumps @@ -418,3 +419,17 @@ void emit_stack_dump (IM3Compilation o) # endif } + +void log_emit (IM3Compilation o, IM3Operation i_operation) +{ +# if DEBUG + OpInfo i = find_operation_info (i_operation); + + if (i.info) + { + printf ("%p: %s", GetPC (o), i.info->name); + } + else printf ("not found: %p", i_operation); +# endif +} + diff --git a/source/m3_info.h b/source/m3_info.h index a91d2f6..e508aaa 100644 --- a/source/m3_info.h +++ b/source/m3_info.h @@ -26,6 +26,7 @@ void dump_type_stack (IM3Compilation o); void log_opcode (IM3Compilation o, u8 i_opcode); const char * get_indention_string (IM3Compilation o); void emit_stack_dump (IM3Compilation o); +void log_emit (IM3Compilation o, IM3Operation i_operation); #endif /* m3_info_h */