From 1551bf6b48b0de1d2f544cbba1c60d09274a0f9e Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Tue, 13 Feb 2018 16:14:55 -0500 Subject: [PATCH] Use flatter representation for function and environments. --- src/core/bytecode.c | 4 ++-- src/core/fiber.c | 1 + src/core/gc.c | 11 ++++------ src/core/vm.c | 44 ++++++++++++++++---------------------- src/include/dst/dsttypes.h | 3 +-- 5 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/core/bytecode.c b/src/core/bytecode.c index f16ceeee..b199ce15 100644 --- a/src/core/bytecode.c +++ b/src/core/bytecode.c @@ -217,7 +217,7 @@ DstFuncDef *dst_funcdef_alloc() { def->defs_length = 0; def->constants_length = 0; def->bytecode_length = 0; - def->environments_length = 1; + def->environments_length = 0; return def; } @@ -225,7 +225,7 @@ DstFuncDef *dst_funcdef_alloc() { DstFunction *dst_thunk(DstFuncDef *def) { DstFunction *func = dst_gcalloc(DST_MEMORY_FUNCTION, sizeof(DstFunction)); func->def = def; - func->envs = NULL; + dst_assert(def->environments_length == 0, "tried to create thunk that needs upvalues"); return func; } diff --git a/src/core/fiber.c b/src/core/fiber.c index 096fbe6f..f6971a5f 100644 --- a/src/core/fiber.c +++ b/src/core/fiber.c @@ -230,6 +230,7 @@ void dst_fiber_cframe(DstFiber *fiber) { newframe->prevframe = oldframe; newframe->pc = NULL; newframe->func = NULL; + newframe->env = NULL; } /* Pop a stack frame from the fiber. Returns the new stack frame, or diff --git a/src/core/gc.c b/src/core/gc.c index 5a06e623..f0fc2b55 100644 --- a/src/core/gc.c +++ b/src/core/gc.c @@ -166,10 +166,9 @@ static void dst_mark_function(DstFunction *func) { return; dst_gc_mark(func); numenvs = func->def->environments_length; - if (NULL != func->envs) - for (i = 0; i < numenvs; ++i) - if (NULL != func->envs[i]) - dst_mark_funcenv(func->envs[i]); + for (i = 0; i < numenvs; ++i) { + dst_mark_funcenv(func->envs[i]); + } dst_mark_funcdef(func->def); } @@ -204,6 +203,7 @@ static void dst_deinit_block(DstGCMemoryHeader *block) { DstAbstractHeader *h = (DstAbstractHeader *)mem; switch (block->flags & DST_MEM_TYPEBITS) { default: + case DST_MEMORY_FUNCTION: break; /* Do nothing for non gc types */ case DST_MEMORY_SYMBOL: dst_symbol_deinit((const uint8_t *)mem + 2 * sizeof(int32_t)); @@ -220,9 +220,6 @@ static void dst_deinit_block(DstGCMemoryHeader *block) { case DST_MEMORY_BUFFER: dst_buffer_deinit((DstBuffer *) mem); break; - case DST_MEMORY_FUNCTION: - free(((DstFunction *)mem)->envs); - break; case DST_MEMORY_ABSTRACT: if (h->type->gc) { if (h->type->gc((void *)(h + 1), h->size)) { diff --git a/src/core/vm.c b/src/core/vm.c index 9e182125..eac74571 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -495,36 +495,30 @@ static void *op_lookup[255] = { { DstFuncDef *fd; DstFunction *fn; + int32_t elen; vm_assert((int32_t)oparg(2, 0xFFFF) < func->def->defs_length, "invalid funcdef"); fd = func->def->defs[(int32_t)oparg(2, 0xFFFF)]; - fn = dst_thunk(fd); + elen = fd->environments_length; + fn = dst_gcalloc(DST_MEMORY_FUNCTION, sizeof(DstFunction) + (elen * sizeof(DstFuncEnv *))); + fn->def = fd; { - int32_t elen = fd->environments_length; - if (elen) { - int32_t i; - fn->envs = malloc(sizeof(DstFuncEnv *) * elen); - if (NULL == fn->envs) { - DST_OUT_OF_MEMORY; - } - for (i = 0; i < elen; ++i) { - int32_t inherit = fd->environments[i]; - if (inherit == -1) { - DstStackFrame *frame = (DstStackFrame *)stack - 1; - if (!frame->env) { - /* Lazy capture of current stack frame */ - DstFuncEnv *env = dst_gcalloc(DST_MEMORY_FUNCENV, sizeof(DstFuncEnv)); - env->offset = dst_vm_fiber->frame; - env->as.fiber = dst_vm_fiber; - env->length = func->def->slotcount; - frame->env = env; - } - fn->envs[i] = frame->env; - } else { - fn->envs[i] = func->envs[inherit]; + int32_t i; + for (i = 0; i < elen; ++i) { + int32_t inherit = fd->environments[i]; + if (inherit == -1) { + DstStackFrame *frame = (DstStackFrame *)stack - 1; + if (!frame->env) { + /* Lazy capture of current stack frame */ + DstFuncEnv *env = dst_gcalloc(DST_MEMORY_FUNCENV, sizeof(DstFuncEnv)); + env->offset = dst_vm_fiber->frame; + env->as.fiber = dst_vm_fiber; + env->length = func->def->slotcount; + frame->env = env; } + fn->envs[i] = frame->env; + } else { + fn->envs[i] = func->envs[inherit]; } - } else { - fn->envs = NULL; } } stack[oparg(1, 0xFF)] = dst_wrap_function(fn); diff --git a/src/include/dst/dsttypes.h b/src/include/dst/dsttypes.h index 2b668039..ba610524 100644 --- a/src/include/dst/dsttypes.h +++ b/src/include/dst/dsttypes.h @@ -402,8 +402,7 @@ struct DstFuncEnv { /* A function */ struct DstFunction { DstFuncDef *def; - /* Consider allocating envs with entire function struct */ - DstFuncEnv **envs; + DstFuncEnv *envs[]; }; /* Defines an abstract type */