From c412ac4289c1c5960d46f2b2af9f26e6295c86a8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 10 Sep 2020 18:24:06 +0200 Subject: [PATCH] :art: VM improvments --- include/emit.h | 3 ++- include/opcode.h | 2 -- opcode.txt | 1 - src/emit/emit.c | 15 ++++++++--- src/lib/array.c | 9 ++++--- src/vm/vm.c | 69 ++++++++++++++++++++++++++---------------------- 6 files changed, 57 insertions(+), 42 deletions(-) diff --git a/include/emit.h b/include/emit.h index df560225..d7c2fc7d 100644 --- a/include/emit.h +++ b/include/emit.h @@ -47,6 +47,7 @@ ANN m_uint emit_local(const Emitter emit, const Type t); ANN Instr emit_exp_spork(const Emitter, const Exp_Unary*); ANN m_bool emit_exp(const Emitter, const Exp); ANN static inline void emit_except(const Emitter emit, const Type t) { - emit_add_instr(emit, !GET_FLAG(t, nonnull) ? GWOP_EXCEPT : SetObj); + if(!GET_FLAG(t, nonnull)) + emit_add_instr(emit, GWOP_EXCEPT); } #endif diff --git a/include/opcode.h b/include/opcode.h index 8a9327fc..a7ed4a74 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -156,7 +156,6 @@ enum { eObjectAssign, eAssign, eObjectRelease, - eSetObj, eGWOP_EXCEPT, eAllocMember4, eDotMember, @@ -335,7 +334,6 @@ enum { #define ObjectAssign (f_instr)eObjectAssign #define Assign (f_instr)eAssign #define ObjectRelease (f_instr)eObjectRelease -#define SetObj (f_instr)eSetObj #define GWOP_EXCEPT (f_instr)eGWOP_EXCEPT #define AllocMember4 (f_instr)eAllocMember4 #define DotMember (f_instr)eDotMember diff --git a/opcode.txt b/opcode.txt index ff33a876..2ae78cc8 100644 --- a/opcode.txt +++ b/opcode.txt @@ -153,7 +153,6 @@ RegAddRefAddr ObjectAssign Assign ObjectRelease -SetObj GWOP_EXCEPT AllocMember4 DotMember diff --git a/src/emit/emit.c b/src/emit/emit.c index 1169192a..67614f56 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1097,8 +1097,9 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) { m_bit exec = back->opcode; m_uint val = back->m_val; m_uint val2 = back->m_val2; - back->opcode = eRegPushMem; - back->m_val = back->m_val2 = 0; + back->opcode = eReg2Reg; + back->m_val2 = -SZ_INT; + regpush(emit, SZ_INT); const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec); instr->m_val = val; instr->m_val2 = val2; @@ -1214,6 +1215,15 @@ ANN void spork_code(const Emitter emit, const struct Sporker *sp) { ANN void spork_func(const Emitter emit, const struct Sporker *sp) { const Func f = sp->exp->d.exp_call.m_func; if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) { + regpush(emit, SZ_INT*2); + // (re-)emit owner + if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot) + emit_exp(emit, sp->exp->d.exp_call.func->d.exp_dot.base); + else { + assert(sp->exp->d.exp_call.func->exp_type == ae_exp_primary); + emit_add_instr(emit, RegPushMem); + } + regpop(emit, SZ_INT*3); const m_uint depth = f->def->stack_depth; regpop(emit, depth -SZ_INT); const Instr spork = emit_add_instr(emit, SporkMemberFptr); @@ -1470,7 +1480,6 @@ ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) { ANN static m_bool variadic_state(const Emitter emit, const Stmt_VarLoop stmt, const m_uint status) { regpushi(emit, status); CHECK_BB(emit_exp(emit, stmt->exp)) - emit_add_instr(emit, SetObj); const Instr member = emit_add_instr(emit, DotMember4); member->m_val = SZ_INT; emit_add_instr(emit, int_r_assign); diff --git a/src/lib/array.c b/src/lib/array.c index 34046336..b61fb477 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -272,22 +272,23 @@ ANN static void array_loop(const Emitter emit, const m_uint depth) { emit_add_instr(emit, GWOP_EXCEPT); for(m_uint i = 0; i < depth - 1; ++i) { const Instr access = emit_add_instr(emit, ArrayAccess); - access->m_val = i; + access->m_val = i * SZ_INT; + access->m_val2 = !i ? SZ_INT : 0; const Instr get = emit_add_instr(emit, ArrayGet); - get->m_val = i; + get->m_val = i * SZ_INT; get->m_val2 = -SZ_INT; emit_add_instr(emit, GWOP_EXCEPT); } const Instr post_pop = emit_add_instr(emit, RegPop); post_pop->m_val = SZ_INT; const Instr access = emit_add_instr(emit, ArrayAccess); - access->m_val = depth; + access->m_val = depth * SZ_INT; } ANN static void array_finish(const Emitter emit, const m_uint depth, const m_uint size, const m_bool is_var) { const Instr get = emit_add_instr(emit, is_var ? ArrayAddr : ArrayGet); - get->m_val = depth; + get->m_val = depth * SZ_INT; const Instr push = emit_add_instr(emit, ArrayValid); push->m_val = is_var ? SZ_INT : size; } diff --git a/src/vm/vm.c b/src/vm/vm.c index aab88f5a..3e4d3490 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -325,7 +325,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat, &&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid, &&newobj, &&addref, &&addrefaddr, &&objassign, &&assign, &&remref, - &&setobj, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, + &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, &&staticint, &&staticfloat, &&staticother, &&dotfunc, &&dotstaticfunc, &&gcini, &&gcadd, &&gcend, @@ -680,9 +680,9 @@ PRAGMA_PUSH() DISPATCH() PRAGMA_POP() sporkmemberfptr: - for(m_uint i = 0; i < VAL; i+= SZ_INT) + for(m_uint i = SZ_INT; i < VAL; i+= SZ_INT) *(m_uint*)(child->reg + i) = *(m_uint*)(reg - VAL + i); - *(M_Object*)(child->reg + VAL) = a.obj; + *(M_Object*)(child->reg + VAL) = *(M_Object*)(reg + VAL + SZ_INT); *(m_uint*)(child->reg + VAL + SZ_INT) = *(m_uint*)(reg + VAL - SZ_INT*2); child->reg += VAL + SZ_INT*2; DISPATCH() @@ -727,7 +727,8 @@ arraytop: goto _goto; arrayaccess: { - register const m_int idx = *(m_int*)(reg + SZ_INT * VAL); + register const m_int idx = *(m_int*)(reg + VAL); + a.obj = *(M_Object*)(reg-VAL2); if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) { gw_err(_(" ... at index [%" INT_F "]\n"), idx); gw_err(_(" ... at dimension [%" INT_F "]\n"), VAL); @@ -738,10 +739,10 @@ arrayaccess: DISPATCH() } arrayget: - m_vector_get(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * VAL), (reg + (m_int)VAL2)); + m_vector_get(ARRAY(a.obj), *(m_int*)(reg + VAL), (reg + (m_int)VAL2)); DISPATCH() arrayaddr: - *(m_bit**)(reg + (m_int)VAL2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * VAL)); + *(m_bit**)(reg + (m_int)VAL2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + VAL)); DISPATCH() arrayvalid: // are we sure it is the array ? @@ -753,20 +754,27 @@ newobj: reg += SZ_INT; DISPATCH() addref: - a.obj = *((M_Object*)(reg+(m_int)VAL) + (m_int)VAL2); - goto addrefcommon; + { + const M_Object o = *((M_Object*)(reg+(m_int)VAL) + (m_int)VAL2); + if(o) + ++o->ref; + } + DISPATCH() addrefaddr: - a.obj = *(*(M_Object**)(reg+(m_int)VAL) + (m_int)VAL2); -addrefcommon: - if(a.obj) - ++a.obj->ref; + { + const M_Object o = *(*(M_Object**)(reg+(m_int)VAL) + (m_int)VAL2); + if(o) + ++o->ref; + } DISPATCH() objassign: - a.obj = **(M_Object**)(reg -SZ_INT); - if(a.obj) { - --a.obj->ref; - _release(a.obj, shred); +{ + const M_Object o = **(M_Object**)(reg -SZ_INT); + if(o) { + --o->ref; + _release(o, shred); } +} assign: reg -= SZ_INT; **(M_Object**)reg = *(M_Object*)(reg-SZ_INT); @@ -774,43 +782,39 @@ assign: remref: release(*(M_Object*)(mem + VAL), shred); DISPATCH() -setobj: - a.obj = *(M_Object*)(reg-SZ_INT-(m_int)VAL); - DISPATCH(); except: /* TODO: Refactor except instruction * * so that * * VAL = offset (no default SZ_INT) * * VAL2 = error message * * grep for GWOP_EXCEPT and Except, exception... */ - if(!(a.obj = *(M_Object*)(reg-SZ_INT-VAL))) { + if(!*(M_Object*)(reg-SZ_INT-VAL)) { shred->pc = PC; exception(shred, "NullPtrException"); continue; } DISPATCH(); allocmemberaddr: - a.obj = *(M_Object*)mem; - *(m_bit**)reg = a.obj->data + VAL; + *(m_bit**)reg = (*(M_Object*)mem)->data + VAL; reg += SZ_INT; DISPATCH() dotmember: - *(m_uint*)(reg-SZ_INT) = *(m_uint*)(a.obj->data + VAL); + *(m_uint*)(reg-SZ_INT) = *(m_uint*)((*(M_Object*)(reg-SZ_INT))->data + VAL); DISPATCH() dotfloat: - *(m_float*)(reg-SZ_INT) = *(m_float*)(a.obj->data + VAL); + *(m_float*)(reg-SZ_INT) = *(m_float*)((*(M_Object*)(reg-SZ_INT))->data + VAL); reg += SZ_FLOAT - SZ_INT; DISPATCH() dotother: // LOOP_OPTIM PRAGMA_PUSH() for(m_uint i = 0; i <= VAL2; i += SZ_INT) - *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)((a.obj->data + VAL) + i); + *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)(((*(M_Object*)(reg-SZ_INT))->data + VAL) + i); PRAGMA_POP() reg += VAL2 - SZ_INT; DISPATCH() dotaddr: - *(m_bit**)(reg-SZ_INT) = (a.obj->data + VAL); + *(m_bit**)(reg-SZ_INT) = ((*(M_Object*)(reg-SZ_INT))->data + VAL); DISPATCH() staticint: *(m_uint*)reg = *(m_uint*)VAL; @@ -828,11 +832,11 @@ staticother: reg += VAL2; DISPATCH() dotfunc: - assert(a.obj); reg += SZ_INT; + VAL2 = SZ_INT; dotstaticfunc: PRAGMA_PUSH() - *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, VAL))->code; + *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at((*(M_Object*)(reg-SZ_INT-VAL2))->vtable, VAL))->code; PRAGMA_POP() DISPATCH() gcini: @@ -842,16 +846,19 @@ gcadd: vector_add(&shred->gc, *(vtype*)(reg-SZ_INT)); DISPATCH(); gcend: - while((a.obj = (M_Object)vector_pop(&shred->gc))) - _release(a.obj, shred); +{ + M_Object o; + while((o = (M_Object)vector_pop(&shred->gc))) + _release(o, shred); +} DISPATCH() gacktype: { const M_Object o = *(M_Object*)(reg - SZ_INT); if(o) *(Type*)reg = o->type_ref; - DISPATCH() } + DISPATCH() gackend: { m_str str = *(m_str*)(reg - SZ_INT); -- 2.43.0