Commit 936d585f authored by Laszlo Domoszlai's avatar Laszlo Domoszlai
Browse files

introduce forward pointers in thunks

overwrite a thunk if the result fits or put a forward pointer there
parent 68bb16b1
......@@ -14,15 +14,7 @@ struct Thunk* exec(Code* expr, int frame_ptr, Thunk* target)
switch(expr->local_type)
{
case LIT_INT:
if(target == NULL)
{
return createI(((LitEntry*) expr)->_int);
}
else
{
updateI(target, ((LitEntry*) expr)->_int);
return target;
}
return updateI(target, ((LitEntry*) expr)->_int);
default:
printf("Exec: Unhandled LIT type");
exit(-1);
......@@ -31,8 +23,8 @@ struct Thunk* exec(Code* expr, int frame_ptr, Thunk* target)
case CT_VAR:
switch(expr->local_type)
{
case VAR_FN:
return createF(((VarEntry*) expr)->f, 0);
case VAR_FN:
return updateF(target, ((VarEntry*) expr)->f, 0);
case VAR_ARG:
return stack[frame_ptr - ((VarEntry*) expr)->index];
default:
......@@ -51,7 +43,7 @@ struct Thunk* exec(Code* expr, int frame_ptr, Thunk* target)
switch(var->base.local_type)
{
case VAR_FN:
thunk = createF(var->f, expr->nr_args);
thunk = updateF(target, var->f, expr->nr_args);
for(int i=0; i<thunk->desc->arity; i++)
{
thunk->_args[i] = exec(((AppEntry*)expr)->args[i], frame_ptr, NULL);
......@@ -61,7 +53,7 @@ struct Thunk* exec(Code* expr, int frame_ptr, Thunk* target)
Thunk* basethunk;
basethunk = eval(stack[frame_ptr - var->index]);
thunk = createF(basethunk->desc->type == FT_SLICE ?
thunk = updateF(target, basethunk->desc->type == FT_SLICE ?
((SliceEntry*) basethunk->desc)->forward_ptr : basethunk->desc, basethunk->desc->arity + expr->nr_args);
for(int i=0; i<basethunk->desc->arity; i++)
......
No preview for this file type
......@@ -8,7 +8,7 @@
void __add(Thunk* target)
{
return updateI(target, readI(eval(stack[stack_top - 2])) + readI(eval(stack[stack_top - 1])));
updateI(target, readI(eval(stack[stack_top - 2])) + readI(eval(stack[stack_top - 1])));
}
PrimEntry* add_prim(int arity, int strictness, char* name, void (*exec)(Thunk*))
......
......@@ -6,19 +6,37 @@
#include "code.h"
#include "mem.h"
struct Thunk* createI(int i)
#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
int thunk_size(Thunk* thunk)
{
Thunk* thunk = (Thunk*) alloc_heap(sizeof(Thunk));
thunk->desc = (Desc*) __INT__;
thunk->_int = i;
return thunk;
if(thunk->desc == NULL || thunk->desc->type == FT_BOXED_LIT)
{
if(thunk->desc == (Desc*) __STRING__ || thunk->desc == (Desc*) __ARRAY__)
{
printf("tunk_size: unhandled literal type\n");
exit(-1);
}
return sizeof(Thunk);
}
else
{
return max(sizeof(Thunk), sizeof(Desc*) + sizeof(Thunk*) * thunk->desc->arity);
}
}
void updateI(Thunk* target, int i)
struct Thunk* updateI(Thunk* target, int i)
{
if(target == NULL) target = (Thunk*) alloc_heap(sizeof(Thunk));
// always can be overwritten with boxed integer
target->desc = (Desc*) __INT__;
target->_int = i;
return target;
}
int readI(Thunk* thunk)
......@@ -32,10 +50,25 @@ int readI(Thunk* thunk)
return thunk->_int;
}
struct Thunk* createF(Desc* f, int nrargs)
struct Thunk* updateF(Thunk* target, Desc* f, int nrargs)
{
// Even if no arguments, still allocate enough space for a forward pointer
Thunk* thunk = (Thunk*) alloc_heap(sizeof(Thunk) + sizeof(Thunk*) * (nrargs > 0 ? nrargs - 1 : 0));
Thunk* thunk = target;
int newsize = max(sizeof(Thunk), sizeof(Desc*) + sizeof(Thunk*) * nrargs);
if(thunk == NULL)
{
thunk = (Thunk*) alloc_heap(newsize);
}
else
{
if(thunk_size(target) < newsize)
{
thunk = (Thunk*) alloc_heap(newsize);
target->desc = NULL;
target->_forward_ptr = thunk;
}
}
thunk->desc = &(((SliceEntry*) f)[-(f->arity - nrargs)].base);
return thunk;
}
......@@ -43,6 +76,12 @@ struct Thunk* createF(Desc* f, int nrargs)
Thunk* eval(Thunk* thunk)
{
while(true){
while(thunk->desc == NULL)
{
thunk = thunk->_forward_ptr;
}
switch(thunk->desc->type)
{
case FT_BOXED_LIT:
......@@ -56,6 +95,7 @@ Thunk* eval(Thunk* thunk)
for(int i=0; i<thunk->desc->arity; i++)
{
// TODO: handle strictness
pushs(thunk->_args[i]);
}
thunk = exec(((FunEntry*) thunk->desc)->body, stack_top - 1, thunk);
......@@ -105,6 +145,11 @@ int printDesc(Desc* f)
void print(Thunk* thunk)
{
while(thunk->desc == NULL)
{
thunk = thunk->_forward_ptr;
}
if(thunk->desc->type == FT_BOXED_LIT)
{
if((FunEntry*) thunk->desc == __INT__)
......
......@@ -6,11 +6,12 @@
typedef struct Thunk
{
struct Desc* desc;
struct Desc* desc; // NULL, if it is a forward pointer
union
{
Thunk* _forward_ptr;
int _int;
double _real; // TODO: move "real" out of here, too long
double _real; // TODO: move "real" out of here, too long (at least on 32 bits)
char _char;
int _bool;
struct CleanString* _string_ptr;
......@@ -19,11 +20,10 @@ typedef struct Thunk
};
} Thunk;
struct Thunk* createI(int i);
void updateI(Thunk* target, int i);
struct Thunk* updateI(Thunk* target, int i);
int readI(Thunk* thunk);
struct Thunk* createF(Desc* f, int nrargs);
struct Thunk* updateF(Thunk* target, Desc* f, int nrargs);
Thunk* eval(Thunk* thunk);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment