clib: move REG to the stack frames
authorJean Privat <jean@pryen.org>
Tue, 18 Aug 2009 17:05:23 +0000 (12:05 -0500)
committerJean Privat <jean@pryen.org>
Tue, 18 Aug 2009 23:09:38 +0000 (19:09 -0400)
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 <jean@pryen.org>

clib/gc.c
clib/nit_common.h
src/compiling/compiling_icode.nit

index 25629d0..227b83b 100644 (file)
--- 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;
index e267682..93a42c3 100644 (file)
@@ -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;
 
index e0a987b..75ceb7c 100644 (file)
@@ -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 **)&REG;")
-
-               # 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