From 92e99da2c51e1dcd8523b52da158876e24e56b9c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sun, 19 Sep 2021 16:02:54 +0200 Subject: [PATCH] :art: ReleaseObject by chunks --- include/opcode.h | 7 +++++++ opcode.txt | 1 + src/emit/emit.c | 14 ++++++++++++-- src/lib/engine.c | 8 ++++++++ src/vm/vm.c | 7 ++++++- 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/opcode.h b/include/opcode.h index cd7219d2..deb28418 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -179,6 +179,7 @@ enum { eObjectAssign, eAssign, eObjectRelease, + eObjectRelease2, eGWOP_EXCEPT, eAllocMember4, eDotMember, @@ -397,6 +398,7 @@ enum { #define ObjectAssign (f_instr)eObjectAssign #define Assign (f_instr)eAssign #define ObjectRelease (f_instr)eObjectRelease +#define ObjectRelease2 (f_instr)eObjectRelease2 #define GWOP_EXCEPT (f_instr)eGWOP_EXCEPT #define AllocMember4 (f_instr)eAllocMember4 #define DotMember (f_instr)eDotMember @@ -1254,6 +1256,11 @@ ANN static inline void dump_opcodes(const VM_Code code) { gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); gw_out("\n"); break; + case eObjectRelease2: + gw_out("{Y}┃{0}{-}% 4lu{0}: ObjectRelease2", j); + gw_out(" {-R}%-14p{0}", instr->m_val); + gw_out("\n"); + break; case eGWOP_EXCEPT: gw_out("{Y}┃{0}{-}% 4lu{0}: GWOP_EXCEPT ", j); gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val); diff --git a/opcode.txt b/opcode.txt index 2bd04b75..5117b2d1 100644 --- a/opcode.txt +++ b/opcode.txt @@ -176,6 +176,7 @@ StructRegAddRefAddr~i ObjectAssign Assign ObjectRelease~u +ObjectRelease2~p GWOP_EXCEPT~u AllocMember4~u DotMember~u diff --git a/src/emit/emit.c b/src/emit/emit.c index 79f48b2a..40093328 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -248,9 +248,19 @@ ANN static void free_code(MemPool p, Code *code) { ANN static void emit_pop_scope(const Emitter emit) { m_int offset; - while ((offset = frame_pop(emit)) > -1) { + struct Vector_ v; + vector_init(&v); + while ((offset = frame_pop(emit)) > -1) + vector_add(&v, offset); + if(!vector_size(&v)) + vector_release(&v); + else if(vector_size(&v) == 1) { Instr instr = emit_add_instr(emit, ObjectRelease); - instr->m_val = (m_uint)offset; + instr->m_val = vector_front(&v); + vector_release(&v); + } else { + Instr instr = emit_add_instr(emit, ObjectRelease2); + instr->m_val = (m_uint)v.ptr; } vector_pop(&emit->info->pure); if (emit->info->debug) emit_add_instr(emit, DebugPop); diff --git a/src/lib/engine.c b/src/lib/engine.c index c3e58abd..16054eb5 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -76,6 +76,11 @@ static INSTR(PredicateCheck) { if (!*(m_uint *)REG(-SZ_INT)) handle(shred, "PredicateFail"); } +static FREEARG(freearg_release) { + struct Vector_ v = { .ptr = instr->m_val }; + vector_release(&v); +} + ANN static m_bool import_core_libs(const Gwi gwi) { gwidoc(gwi, "one type to rule them all."); const Type t_class = gwi_mk_type(gwi, "Class", SZ_INT, NULL); @@ -227,6 +232,9 @@ ANN static m_bool import_core_libs(const Gwi gwi) { gwi_enum_ini(gwi, "@hidden_enum"); gwi_enum_add(gwi, "@hidden_enum", 0); gwi_enum_end(gwi); + +gwi_register_freearg(gwi, ObjectRelease2, freearg_release); + return GW_OK; } diff --git a/src/vm/vm.c b/src/vm/vm.c index a416577f..14dcfe95 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -487,7 +487,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] &&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&newobj, &&addref, &&addrefaddr, &&structaddref, &&structaddrefaddr, &&objassign, &&assign, - &&remref, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, + &&remref, &&remref2, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr, &&unioncheck, &&unionint, &&unionfloat, &&unionother, &&unionaddr, &&staticint, &&staticfloat, &&staticother, &&upvalueint, &&upvaluefloat, &&upvalueother, &&upvalueaddr, &&dotfunc, @@ -1102,6 +1102,11 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] remref: release(*(M_Object *)(mem + VAL), shred); DISPATCH() + remref2: + struct Vector_ v = { .ptr = (m_uint*)VAL }; + for(m_uint i = 0; i < vector_size(&v); i++) + release(*(M_Object *)(mem + vector_at(&v, i)), shred); + DISPATCH() except: /* TODO: Refactor except instruction * * so that * -- 2.43.0