Commit 7f90e896 authored by Laszlo Domoszlai's avatar Laszlo Domoszlai
Browse files

add B stack (need testing)

parent 98384066
...@@ -30,11 +30,13 @@ ...@@ -30,11 +30,13 @@
} \ } \
argmask <<= 1; argmask <<= 1;
#define arg_from_code(desc, arg) \ #define arg_from_code(descarg, arg) \
if(((FunEntry*) (desc))->strictness & argmask) \ if(((FunEntry*) (descarg))->strictness & argmask) \
{ \ { \
push_a(NULL); \ Thunk* phl = alloc_b(); \
exec(arg, frame_ptr, stack_top_a); \ phl->desc = (Desc*) __STACK_PLACEHOLDER__; \
push_a(phl); \
exec(arg, frame_ptr, stack_top_a, stack_top_b); \
} \ } \
else \ else \
{ \ { \
...@@ -88,8 +90,20 @@ struct Thunk* create_thunk(Code* expr, int frame_ptr) ...@@ -88,8 +90,20 @@ struct Thunk* create_thunk(Code* expr, int frame_ptr)
return thunk; return thunk;
} }
case CT_VAR: case CT_VAR:
case CT_VAR_STRICT:
return local(frame_ptr, ((VarEntry*) expr)->index); return local(frame_ptr, ((VarEntry*) expr)->index);
case CT_VAR_STRICT:
{
Thunk* arg = local(frame_ptr, ((VarEntry*) expr)->index);
if(arg->desc->unboxable)
{
return createT(arg);
}
else
{
return arg;
}
}
case CT_THUNK: case CT_THUNK:
return &((ThunkEntry*) expr)->thunk; return &((ThunkEntry*) expr)->thunk;
case CT_SELECT: case CT_SELECT:
...@@ -99,7 +113,7 @@ struct Thunk* create_thunk(Code* expr, int frame_ptr) ...@@ -99,7 +113,7 @@ struct Thunk* create_thunk(Code* expr, int frame_ptr)
} }
} }
void exec(Code* expr, int frame_ptr, int root_frame_ptr) void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
{ {
while(1) while(1)
{ {
...@@ -117,15 +131,14 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -117,15 +131,14 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
switch (slice->type) { switch (slice->type) {
case FT_PRIM: case FT_PRIM:
{ {
Thunk args[expr->nr_args];
for (int i = 0; i < expr->nr_args; i++) { for (int i = 0; i < expr->nr_args; i++) {
push_a(&args[i]); push_a(alloc_b());
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a); exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, stack_top_b);
} }
((PrimEntry*) slice)->exec(root_frame_ptr); ((PrimEntry*) slice)->exec(root_frame_ptr);
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
case FT_FUN: case FT_FUN:
...@@ -156,6 +169,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -156,6 +169,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
set_return(root_frame_ptr, thunk); set_return(root_frame_ptr, thunk);
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
case FT_BOXED_LIT: case FT_BOXED_LIT:
...@@ -182,12 +196,13 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -182,12 +196,13 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
} }
for (int i = 0; i < expr->nr_args; i++) { for (int i = 0; i < expr->nr_args; i++) {
push_a(NULL); push_a(alloc_b());
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a); exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, stack_top_b);
} }
((PrimEntry*) slice)->exec(root_frame_ptr); ((PrimEntry*) slice)->exec(root_frame_ptr);
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
case FT_FUN: case FT_FUN:
...@@ -226,6 +241,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -226,6 +241,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
set_return(root_frame_ptr, thunk); set_return(root_frame_ptr, thunk);
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
case FT_BOXED_LIT: case FT_BOXED_LIT:
...@@ -237,13 +253,22 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -237,13 +253,22 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
} }
case CT_VAR_STRICT: case CT_VAR_STRICT:
{ {
Thunk* thunk = local(frame_ptr, ((VarEntry*) expr)->index); Thunk* arg = local(frame_ptr, ((VarEntry*) expr)->index);
assert(is_hnf(thunk)); assert(is_hnf(arg));
forward_thunk(thunk, root_frame_ptr); if(arg->desc->unboxable)
set_return(root_frame_ptr, thunk); {
arg = updateT(get_dst(root_frame_ptr), arg);
}
else
{
forward_thunk(arg, root_frame_ptr);
}
set_return(root_frame_ptr, arg);
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
case CT_VAR: case CT_VAR:
...@@ -260,6 +285,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -260,6 +285,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
// Destroy stack frame before eval, it is not needed any more // Destroy stack frame before eval, it is not needed any more
// Greatly reduces stack usage // Greatly reduces stack usage
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
frame_ptr = stack_top_a; frame_ptr = stack_top_a;
// Here frame_ptr == root_frame_ptr // Here frame_ptr == root_frame_ptr
...@@ -282,6 +308,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -282,6 +308,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
((PrimEntry*) thunk->desc)->exec(root_frame_ptr); ((PrimEntry*) thunk->desc)->exec(root_frame_ptr);
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
case FT_CAF: case FT_CAF:
...@@ -292,6 +319,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -292,6 +319,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
case FT_RECORD: case FT_RECORD:
case FT_BOXED_LIT: case FT_BOXED_LIT:
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
} }
...@@ -301,12 +329,13 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -301,12 +329,13 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
forward_thunk(thunk, root_frame_ptr); forward_thunk(thunk, root_frame_ptr);
set_return(root_frame_ptr, thunk); set_return(root_frame_ptr, thunk);
destroy_stack_frame(root_frame_ptr); destroy_stack_frame(root_frame_ptr);
destroy_stack_frame_b(root_frame_ptr_b);
return; return;
} }
case CT_SELECT: case CT_SELECT:
{ {
push_a(NULL); push_a(NULL);
exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a); exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a, stack_top_b);
Thunk* pattern = pop_a(); Thunk* pattern = pop_a();
assert(is_hnf(pattern)); assert(is_hnf(pattern));
...@@ -345,11 +374,8 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr) ...@@ -345,11 +374,8 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
} }
case CT_IF: case CT_IF:
{ {
Thunk tmp; push_a(alloc_b());
tmp.desc = (Desc*) __BOOL__; exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a, stack_top_b);
push_a(&tmp);
exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a);
Thunk* cond = pop_a(); Thunk* cond = pop_a();
if (readB(cond)) { if (readB(cond)) {
...@@ -381,7 +407,7 @@ struct Thunk* eval(Thunk* thunk) { ...@@ -381,7 +407,7 @@ struct Thunk* eval(Thunk* thunk) {
arg_from_thunk(thunk->desc, thunk->_args[i]); arg_from_thunk(thunk->desc, thunk->_args[i]);
} }
exec(((FunEntry*) thunk->desc)->body, frame_ptr, frame_ptr); exec(((FunEntry*) thunk->desc)->body, frame_ptr, frame_ptr, stack_top_b);
thunk = pop_a(); thunk = pop_a();
return thunk; return thunk;
} }
......
...@@ -60,7 +60,7 @@ struct IfEntry { ...@@ -60,7 +60,7 @@ struct IfEntry {
struct Code* fexpr; struct Code* fexpr;
}; };
void exec(Code* expr, int frame_ptr, int root_frame_ptr); void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b);
struct Thunk* eval(Thunk* thunk); struct Thunk* eval(Thunk* thunk);
#endif // __CODE_H #endif // __CODE_H
\ No newline at end of file
...@@ -39,12 +39,13 @@ Desc* get_slice(Desc* f, int nrargs) { ...@@ -39,12 +39,13 @@ Desc* get_slice(Desc* f, int nrargs) {
return &(((SliceEntry*) f)[-(f->arity - nrargs)].base); return &(((SliceEntry*) f)[-(f->arity - nrargs)].base);
} }
FunEntry* alloc_prim(char* name) { FunEntry* alloc_prim(char* name, int unboxable) {
int len = strlen(name); int len = strlen(name);
FunEntry* entry = (FunEntry*) alloc_desc(sizeof (FunEntry) + len + 1); FunEntry* entry = (FunEntry*) alloc_desc(sizeof (FunEntry) + len + 1);
entry->base.type = FT_BOXED_LIT; entry->base.type = FT_BOXED_LIT;
entry->base.arity = 0; entry->base.arity = 0;
entry->base.thunk_size = sizeof(Thunk); entry->base.thunk_size = sizeof(Thunk);
entry->base.unboxable = unboxable;
memcpy(entry->name, name, len + 1); memcpy(entry->name, name, len + 1);
return entry; return entry;
} }
...@@ -84,19 +85,28 @@ int printDesc(Desc* f) { ...@@ -84,19 +85,28 @@ int printDesc(Desc* f) {
} }
void init_desc() { void init_desc() {
__INT__ = alloc_prim("INT"); __INT__ = alloc_prim("INT", 1);
__BOOL__ = alloc_prim("BOOL"); __BOOL__ = alloc_prim("BOOL", 1);
__CHAR__ = alloc_prim("CHAR"); __CHAR__ = alloc_prim("CHAR", 1);
__REAL__ = alloc_prim("REAL"); __REAL__ = alloc_prim("REAL", 1);
__STRING__ = alloc_prim("STRING");
__ARRAY__ = alloc_prim("ARRAY"); __STRING__ = alloc_prim("STRING", 0);
__FORWARD_PTR__ = alloc_prim("FWD"); __ARRAY__ = alloc_prim("ARRAY", 0);
__FORWARD_PTR__ = alloc_prim("FWD", 0);
// Avoid to be overwritten by updateF
__STACK_PLACEHOLDER__ = alloc_prim("PLACEHOLDER", 0);
__STACK_PLACEHOLDER__->base.thunk_size = 0;
} }
struct FunEntry* __FORWARD_PTR__;
struct FunEntry* __INT__; struct FunEntry* __INT__;
struct FunEntry* __BOOL__; struct FunEntry* __BOOL__;
struct FunEntry* __CHAR__; struct FunEntry* __CHAR__;
struct FunEntry* __REAL__; struct FunEntry* __REAL__;
struct FunEntry* __STRING__; struct FunEntry* __STRING__;
struct FunEntry* __ARRAY__; struct FunEntry* __ARRAY__;
struct FunEntry* __FORWARD_PTR__;
struct FunEntry* __STACK_PLACEHOLDER__;
...@@ -65,12 +65,15 @@ Desc* get_slice(Desc* f, int nrargs); ...@@ -65,12 +65,15 @@ Desc* get_slice(Desc* f, int nrargs);
int printDesc(Desc* f); int printDesc(Desc* f);
extern struct FunEntry* __FORWARD_PTR__;
extern struct FunEntry* __INT__; extern struct FunEntry* __INT__;
extern struct FunEntry* __BOOL__; extern struct FunEntry* __BOOL__;
extern struct FunEntry* __CHAR__; extern struct FunEntry* __CHAR__;
extern struct FunEntry* __REAL__; extern struct FunEntry* __REAL__;
extern struct FunEntry* __STRING__; extern struct FunEntry* __STRING__;
extern struct FunEntry* __ARRAY__; extern struct FunEntry* __ARRAY__;
extern struct FunEntry* __FORWARD_PTR__;
extern struct FunEntry* __STACK_PLACEHOLDER__;
#endif // __DESC_H #endif // __DESC_H
\ No newline at end of file
...@@ -9,6 +9,7 @@ struct Desc { ...@@ -9,6 +9,7 @@ struct Desc {
FunType type : 3; FunType type : 3;
unsigned int arity : 8; // LIMITATION: maximum 32 arguments unsigned int arity : 8; // LIMITATION: maximum 32 arguments
unsigned int thunk_size : 10; // It gives false result for strings and arrays unsigned int thunk_size : 10; // It gives false result for strings and arrays
unsigned int unboxable : 1;
}; };
#endif // __DESC_H #endif // __DESC_H
\ No newline at end of file
...@@ -85,7 +85,7 @@ int main ( int argc, char *argv[] ) ...@@ -85,7 +85,7 @@ int main ( int argc, char *argv[] )
#endif #endif
push_a(NULL); push_a(NULL);
exec(expr, stack_top_a, stack_top_a); exec(expr, stack_top_a, stack_top_a, stack_top_b);
Thunk* res = pop_a(); Thunk* res = pop_a();
#ifdef BENCHMARK #ifdef BENCHMARK
......
Markdown is supported
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