From aff9957c569341e7a1c167b6a36f7f27a82bd8b4 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Tue, 18 Aug 2009 12:05:23 -0500 Subject: [PATCH] clib: move REG to the stack frames It means that functions have different frame sizes. To achieve this, each function frame ('me') is stored in a big_frame ('fra') that contains enough space to store all the REGs. Signed-off-by: Jean Privat --- clib/gc.c | 8 +++----- clib/nit_common.h | 5 +++-- src/compiling/compiling_icode.nit | 33 +++++++++++++++++---------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/clib/gc.c b/clib/gc.c index 25629d0..227b83b 100644 --- a/clib/gc.c +++ b/clib/gc.c @@ -109,7 +109,6 @@ void GC_scavenging(void) { } void GC_collect(void) { - val_t **pointers; val_t *pointer; int i; int j; @@ -123,16 +122,15 @@ void GC_collect(void) { for (i = 0; i < staticObjects.size; i++) { object = *(val_t*)(staticObject->pointer); if (!ISNULL(object) && ISOBJ(object)) { - *(staticObject->pointer) = (val_t)GC_evacuation((obj_t)object); + *(staticObject->pointer) = GC_evacuation((obj_t)object); } staticObject = staticObject->next; } while (frame != NULL) { - pointers = frame->REG_pointer; for (j = 0; j < frame->REG_size; j++) { - object = (val_t)(pointers[j]); + object = frame->REG[j]; if (!ISNULL(object) && ISOBJ(object)) { - pointers[j] = (val_t*)GC_evacuation((obj_t)object); + frame->REG[j] = GC_evacuation((obj_t)object); } } if (frame == frame->prev) break; diff --git a/clib/nit_common.h b/clib/nit_common.h index e267682..93a42c3 100644 --- a/clib/nit_common.h +++ b/clib/nit_common.h @@ -122,14 +122,15 @@ extern val_t G_sys; extern int glob_argc; extern char ** glob_argv; -/* Stack frames */ +/* Stack frames. + * Are used to store local variables (REGS) of function and provide information for stack dump */ struct stack_frame_t { struct stack_frame_t *prev; /* previous stack frame */ const char *file; /* source filename (.nit) */ int line; /* line number (in the source) */ const char *meth; /* human function name (usually the method name) */ int REG_size; /* number of local variables */ - val_t **REG_pointer; /* array of local variables */ + val_t REG[1]; /* local variables (flexible array) */ }; extern struct stack_frame_t *stack_frame_head; diff --git a/src/compiling/compiling_icode.nit b/src/compiling/compiling_icode.nit index e0a987b..75ceb7c 100644 --- a/src/compiling/compiling_icode.nit +++ b/src/compiling/compiling_icode.nit @@ -54,7 +54,7 @@ class I2CCompilerVisitor if not strs.has_key(i) then strs[i] = "closctx->variable[{i}]" else strs = once new HashMap[Int, String] - if not strs.has_key(i) then strs[i] = "REG[{i}]" + if not strs.has_key(i) then strs[i] = "fra.me.REG[{i}]" end s = strs[i] ids[e] = s @@ -264,20 +264,21 @@ redef class IRoutine if location != null then ll = location.line_start end - v.add_decl("struct stack_frame_t frame = \{NULL, NULL, {ll}, LOCATE_{v.basecname}, {std_slots_nb}\};") - v.add_instr("frame.prev = stack_frame_head; stack_frame_head = &frame;") - v.add_instr("frame.file = LOCATE_{v.visitor.module.name};") - v.add_instr("frame.REG_pointer = (val_t **)®") - - # Add local variables - if std_slots_nb == 0 then - v.add_decl("val_t *REG = NULL;") + # Encapsulate the frame ('me') in a larger structure ('fra') that has enough space to store the local variables (REG) + if std_slots_nb > 1 then + v.add_decl("struct \{struct stack_frame_t me; val_t MORE_REG[{std_slots_nb-1}];\} fra;") else - var init_vals = new Buffer - init_vals.append "val_t REG[{std_slots_nb}] = \{ NIT_NULL" - for i in [1..std_slots_nb[ do init_vals.append(", NIT_NULL") - init_vals.append " \};" - v.add_decl(init_vals.to_s) + v.add_decl("struct \{struct stack_frame_t me;\} fra;") + end + v.add_instr("fra.me.prev = stack_frame_head; stack_frame_head = &fra.me;") + v.add_instr("fra.me.file = LOCATE_{v.visitor.module.name};") + v.add_instr("fra.me.line = {ll};") + v.add_instr("fra.me.meth = LOCATE_{v.basecname};") + v.add_instr("fra.me.REG_size = {std_slots_nb};") + + # Declare/initialize local variables + for i in [0..std_slots_nb[ do + v.add_instr("fra.me.REG[{i}] = NIT_NULL;") end for i in [0..tag_slots_nb[ do v.add_decl("val_t REGB{i};") @@ -319,7 +320,7 @@ redef class IRoutine # Compile body body.compile_to_c(v) - v.add_instr("stack_frame_head = frame.prev;") + v.add_instr("stack_frame_head = fra.me.prev;") v.return_label = old_rl var r = result if r != null then @@ -795,7 +796,7 @@ redef class IClosureDef v.add_instr("{closcnv}.variable = closctx->variable;") v.add_instr("{closcnv}.closurevariable = closctx->closurevariable;") else - v.add_instr("{closcnv}.variable = REG;") + v.add_instr("{closcnv}.variable = fra.me.REG;") v.add_instr("{closcnv}.closurevariable = CREG;") end -- 1.7.9.5