]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve shred
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 11 May 2019 10:40:22 +0000 (12:40 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sat, 11 May 2019 10:40:22 +0000 (12:40 +0200)
include/vm.h
src/lib/instr.c
src/lib/object.c
src/lib/shred.c
src/vm/shreduler.c
src/vm/vm.c
src/vm/vm_shred.c

index 1bc4fd1e8b5f1578610f29f5a1f44254d86937bf..745189c0850a88fb92e7f9549e69081086360d22 100644 (file)
@@ -66,6 +66,7 @@ ANN void shreduler_set_loop(const Shreduler s, const m_bool loop);
 ANN void shreduler_add(const Shreduler s, const VM_Shred shred);
 
 ANEW ANN VM_Shred new_vm_shred(MemPool, const VM_Code code) __attribute__((hot));
+ANEW ANN VM_Shred new_shred_base(const VM_Shred, const VM_Code code) __attribute__((hot));
 __attribute__((hot))
 ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(shred->info->vm->shreduler, shred, 1); }
 void free_vm_shred(const VM_Shred shred)__attribute__((hot, nonnull));
index 8e8d829d485026b01c4c2de6b72cd9140f037cd4..6259e2fda2bcf22b982ee37b1911b6677e22042a 100644 (file)
 INSTR(EOC) {
   vm_shred_exit(shred);
 }
-#include "gwion.h"
+
 INSTR(DTOR_EOC) {
-  // TODO: we should be able to use shred->info->mp directly
-  shred->info->mp = (MemPool)instr->m_val;
   const M_Object o = *(M_Object*)MEM(0);
   o->type_ref = o->type_ref->parent;
   __release(o, shred);
index 7c71213c5cc4f8b8f3ae5c418bfbca1afd370c26..f2953142c4fb5666cb16901301abb59acbea04a4 100644 (file)
@@ -46,6 +46,7 @@ M_Object new_string2(MemPool p, const VM_Shred shred, const m_str str) {
 
 ANN static void handle_dtor(const M_Object o, const VM_Shred shred) {
   const VM_Shred sh = new_vm_shred(shred->info->mp, o->type_ref->nspc->dtor);
+  ADD_REF(o->type_ref->nspc->dtor);
   sh->base = shred->base;
   *(M_Object*)sh->mem = o;
   vm_add_shred(shred->info->vm, sh);
index 7ba65ff3ff93480cabc8c3dbc5ee961e5b2400d2..67a6dadf391fe73edf92f82f6cad394adcacf37e 100644 (file)
@@ -21,6 +21,13 @@ static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsi
 #define FORK_RETVAL(o) (o->data + o_fork_retval)
 #define FORK_ORIG(o) (*(VM**)((o)->data + o_fork_orig))
 
+VM_Shred new_shred_base(const VM_Shred shred, const VM_Code code) {
+  const VM_Shred sh = new_vm_shred(shred->info->mp, code);
+  ADD_REF(code)
+  sh->base = shred->base;
+  return sh;
+}
+
 M_Object new_shred(const VM_Shred shred, m_bool is_spork) {
   const M_Object obj = new_object(shred->info->mp, NULL, is_spork ? t_shred : t_fork);
   ME(obj) = shred;
@@ -33,6 +40,7 @@ M_Object new_shred(const VM_Shred shred, m_bool is_spork) {
 
 static MFUN(gw_shred_exit) {
   const VM_Shred s = ME(o);
+  s->mem -= SZ_INT;
   vm_shred_exit(s);
 }
 
@@ -204,7 +212,7 @@ GWION_IMPORT(shred) {
   CHECK_BB(gwi_item_end(gwi, ae_flag_member, NULL))
 
   gwi_item_ini(gwi, "int", "cancel");
-  CHECK_BB((o_shred_cancel = gwi_item_end(gwi, ae_flag_const, NULL)))
+  CHECK_BB((o_shred_cancel = gwi_item_end(gwi, 0, NULL)))
 
   gwi_func_ini(gwi, "void", "exit", gw_shred_exit);
   CHECK_BB(gwi_func_end(gwi, 0))
index c1319b2906d64dc852f5671126fff536648260b3..6aa23902380facda7eb690c00cfb33972b7edec6 100644 (file)
@@ -9,18 +9,18 @@
 #include "instr.h" // unwind
 
 ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) {
-  s->loop = loop < 0 ? 0 : 1;
+  s->loop = loop > 0;
 }
 
 ANN VM_Shred shreduler_get(const Shreduler s) {
-  Driver *bbq = s->bbq;
-  struct ShredTick_ *tk = s->list;
+  Driver *const bbq = s->bbq;
+  struct ShredTick_ *const tk = s->list;
   if(!tk) {
     if(!vector_size(&s->shreds) && !s->loop)
       bbq->is_running = 0;
     return NULL;
   }
-  const m_float time = (m_float)bbq->pos + (m_float).5;
+  const m_float time = (m_float)bbq->pos + (m_float)GWION_EPSILON;
   if(tk->wake_time <= time) {
     if((s->list = tk->next))
       s->list->prev = NULL;
@@ -44,15 +44,9 @@ ANN static void unwind(const VM_Shred shred) {
   while(code) {
     const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
     if(exec == eFuncReturn) {
-      if(GET_FLAG(code, op))
-        code = *(VM_Code*)(shred->mem - SZ_INT);
-      else {
-        if(GET_FLAG(code, ctor))
-          code = *(VM_Code*)(shred->mem - SZ_INT*2);
-        else
-          code = *(VM_Code*)(shred->mem - SZ_INT*3);
+      code = *(VM_Code*)(shred->mem - SZ_INT*3);
+      if(!GET_FLAG(code, op))
         REM_REF(code, shred->info->vm->gwion)
-      }
       shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4) + SZ_INT*4;
       if(shred->mem <= (((m_bit*)(shred) + sizeof(struct VM_Shred_) + SIZEOF_REG)))break;
     } else break;
@@ -123,7 +117,8 @@ ANN void shredule(const Shreduler s, const VM_Shred shred, const m_float wake_ti
 }
 
 ANN void shreduler_add(const Shreduler s, const VM_Shred shred) {
-// create shred->tick here ?
+  shred->tick = mp_alloc(shred->info->mp, ShredTick);
+  shred->tick->self = shred;
   shred->tick->shreduler = s;
   shred->tick->xid = ++s->shred_ids;
   vector_add(&s->shreds, (vtype)shred);
index 58c9309567eed2b2d2140e6e07b1c4175272323f..32305df98455ff2695bea87c27cb3d2bb3ea6f4b 100644 (file)
@@ -119,23 +119,17 @@ ANN static inline m_bool overflow_(const m_bit* mem, const VM_Shred c) {
 }
 
 ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const Instr instr) {
-  const VM_Code code = (VM_Code)instr->m_val;
-  const VM_Shred sh = new_vm_shred(shred->info->mp, code);
-  ADD_REF(code)
+  const VM_Shred sh = new_shred_base(shred, (VM_Code)instr->m_val);
+  vm_add_shred(shred->info->vm, sh);
   sh->tick->parent = shred->tick;
   if(!shred->tick->child.ptr)
     vector_init(&shred->tick->child);
   vector_add(&shred->tick->child, (vtype)sh);
-  sh->base = shred->base;
-  vm_add_shred(shred->info->vm, sh);
   return sh;
 }
 
 ANN static inline VM_Shred init_fork_shred(const VM_Shred shred, const Instr instr) {
-  const VM_Code code = (VM_Code)instr->m_val;
-  const VM_Shred sh = new_vm_shred(shred->info->mp, code);
-  ADD_REF(code)
-  sh->base = shred->base;
+  const VM_Shred sh = new_shred_base(shred, (VM_Code)instr->m_val);
   vm_fork(shred->info->vm, sh);
   return sh;
 }
@@ -597,8 +591,10 @@ regtomem:
   *(m_uint*)(mem+instr->m_val) = *(m_uint*)(reg+instr->m_val2);
   DISPATCH()
 overflow:
-  if(overflow_(mem, shred))
+  if(overflow_((shred->mem = mem), shred)) {
+shred->code = a.code;
     Except(shred, "StackOverflow");
+  }
 next:
 PRAGMA_PUSH()
   goto *dispatch[next];
@@ -683,6 +679,8 @@ arrayaccess:
     _release(array_base, shred);
     gw_err("\t... at index [%" INT_F "]\n", idx);
     gw_err("\t... at dimension [%" INT_F "]\n", instr->m_val);
+    shred->code = code;
+    shred->mem = mem;
     exception(shred, "ArrayOutofBounds");
     continue;
   }
@@ -724,6 +722,8 @@ exceptbase:
 except:
   if(!(a.obj  = *(M_Object*)(reg-SZ_INT))) {
     if(array_base) _release(array_base, shred);
+    shred->code = code;
+    shred->mem = mem;
     exception(shred, "NullPtrException");
     continue;
   }
index 4afcb0536fa31925101583ebf551f9682443a1c7..a67ec2b7de8b228e8076cbf720267761a3614311 100644 (file)
@@ -38,8 +38,6 @@ VM_Shred new_vm_shred(MemPool p, VM_Code c) {
   shred->code          = c;
   shred->reg           = (m_bit*)shred + sizeof(struct VM_Shred_);
   shred->base = shred->mem = shred->reg + SIZEOF_REG;
-  shred->tick = mp_alloc(p, ShredTick);
-  shred->tick->self = shred;
   shred->info = new_shredinfo(p, c->name);
   vector_init(&shred->gc);
   return shred;