retrieve line number information
[cacao.git] / src / vm / jit / parse.c
index 669848608050e12bf8203b21dfad5cc2a7588ded..93cb649e9e79a1d1fd2d032647a2f4cab4122dc8 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Carolyn Oates
             Edwin Steiner
 
-   $Id: parse.c 813 2003-12-31 00:21:52Z edwin $
+   $Id: parse.c 941 2004-03-06 17:27:56Z jowenn $
 
 */
 
@@ -37,6 +37,7 @@
 #include <string.h>
 #include "parse.h"
 #include "global.h"
+#include "main.h"
 #include "jit.h"
 #include "parseRT.h"
 #include "inline.h"
@@ -66,54 +67,6 @@ u1  *rt_jcode;           /* pointer to start of JavaVM-code            */
 #define debug_writebranch
 
 
-
-/* functionc compiler_addinitclass *********************************************
-
-       add class into the list of classes to initialize
-
-*******************************************************************************/
-                                
-void compiler_addinitclass(classinfo *c)
-{
-       classinfo *cl;
-
-       if (c->initialized) return;
-       
-       cl = chain_first(uninitializedclasses);
-       if (cl == c)
-               return;
-       
-       if (cl == class)
-               cl = chain_next(uninitializedclasses);
-       for (;;) {
-               if (cl == c)
-                       return;
-               if (cl == NULL) {
-                       if (runverbose) {
-                               char logtext[MAXLOGTEXT];
-                               sprintf(logtext, "compiler_addinitclass: ");
-                               utf_sprint(logtext+strlen(logtext), c->name);
-                               log_text(logtext);
-                       }
-                       chain_addlast(uninitializedclasses, c);
-                       return;
-               }
-               if (c < cl) {
-                       if (runverbose) {
-                               char logtext[MAXLOGTEXT];
-                               sprintf(logtext, "compiler_addinitclass: ");
-                               utf_sprint(logtext+strlen(logtext), c->name);
-                               log_text(logtext);
-                       }
-                       chain_addbefore(uninitializedclasses, c);
-                       return;
-               }
-               cl = chain_next(uninitializedclasses);
-       }
-}                       
-
-
-
 /* function descriptor2typesL ***************************************************
 
        decodes a already checked method descriptor. The parameter count, the
@@ -376,21 +329,31 @@ void descriptor2types(methodinfo *m)
 /* intermediate code generating macros */
 
 #define PINC           iptr++;ipc++
-#define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
-#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
-#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
-#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
-#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
-#define OP(o)          iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
-#define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
+#define LOADCONST_I(v) iptr->opc=ICMD_ICONST;/*iptr->op1=0*/;iptr->val.i=(v);PINC
+#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;/*iptr->op1=0*/;iptr->val.l=(v);PINC
+#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;/*iptr->op1=0*/;iptr->val.f=(v);PINC
+#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;/*iptr->op1=0*/;iptr->val.d=(v);PINC
+#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;/*iptr->op1=0*/;iptr->val.a=(v);PINC
+
+/* ACONST instructions generated as arguments for builtin functions
+ * have op1 set to non-zero. This is used for stack overflow checking
+ * in stack.c. */
+#define LOADCONST_A_BUILTIN(v) \
+                       iptr->opc=ICMD_ACONST;iptr->op1=1;iptr->val.a=(v);PINC
+
+#define OP(o)          iptr->opc=(o);/*iptr->op1=0*/;/*iptr->val.l=0*/;PINC
+#define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);/*iptr->val.l=(0)*/;PINC
 #define OP2I(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
-#define OP2A(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
-#define BUILTIN1(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
-                       iptr->val.a=(v);PINC
-#define BUILTIN2(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
-                       iptr->val.a=(v);PINC
-#define BUILTIN3(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
-                       iptr->val.a=(v);PINC
+#define OP2A(o,o1,v,l)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);iptr->line=l;PINC
+#define BUILTIN1(v,t,l)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
+                       iptr->val.a=(v);iptr->line=l;PINC
+#define BUILTIN2(v,t,l)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
+                       iptr->val.a=(v);iptr->line=l;PINC
+#define BUILTIN3(v,t,l)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
+                       iptr->val.a=(v);iptr->line=l;PINC
+
+/* We have to check local variables indices here because they are
+ * used in stack.c to index the locals array. */
 
 #define INDEX_ONEWORD(num)                                                                             \
        do { if((num)<0 || (num)>=maxlocals)                                            \
@@ -451,8 +414,8 @@ static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exc
                return extable;
        
        b_count = *block_count;
+
        for (i = 0; i < exceptiontablelength; i++) {
-                                                                
                p = raw_extable[i].startpc;
                if (label_index != NULL) p = label_index[p];
                extable[i].startpc = p;
@@ -477,8 +440,9 @@ static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exc
                extable[i].catchtype  = raw_extable[i].catchtype;
 
                extable[i].next = NULL;
-               extable[i].down = &extable[i+1];
-               }
+               extable[i].down = &extable[i + 1];
+       }
+
        *block_count = b_count;
        return &extable[i];  /* return the next free xtable* */
 }
@@ -507,6 +471,10 @@ void parse()
        xtable* nextex;             /* points next free entry in extable          */
        u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
 
+       u2 lineindex=0;
+       u2 currentline=0;
+       u2 linepcchange=0;
+
        bool useinltmp;
 
        if (compileverbose) {
@@ -568,7 +536,8 @@ void parse()
        
        iptr = instr = DMNEW(instruction, cumjcodelength + 5);
 
-       /* XXX zero fields in the instructions loop? */
+       /* Zero the intermediate instructions array so we don't have any
+        * invalid pointers in it if we cannot finish analyse_stack(). */
        memset(iptr,0,sizeof(instruction) * (cumjcodelength + 5));
        
        /* initialize block_index table (unrolled four times) */
@@ -623,14 +592,31 @@ void parse()
 #endif
 
        /* scan all java instructions */
+       currentline=0;
+       linepcchange=0;
+       if (jlinenumbercount==0) {
+               lineindex=0;
+       } else {
+               linepcchange=jlinenumbers[0].start_pc;
+       }
 
        for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
          
-               /* DEBUG XXX */   /*printf("p:%d gp:%d ",p,gp);*/
+               /* DEBUG */       /*printf("p:%d gp:%d ",p,gp);*/
 
                /* mark this position as a valid instruction start */
-               if (!iswide)
+               if (!iswide) {
                        instructionstart[p] = 1;
+                       if (linepcchange==p) {
+                               if (jlinenumbercount>lineindex) {
+                                       currentline=jlinenumbers[lineindex].line_number;
+                                       lineindex++;
+                                       if (lineindex<jlinenumbercount)
+                                               linepcchange=jlinenumbers[lineindex].start_pc;
+/*                                     printf("Line number changed to: %ld\n",currentline);*/
+                               }
+                       }
+               }
 
                /*INLINING*/
                if ((useinlining) && (gp == nextgp)) {
@@ -917,28 +903,28 @@ void parse()
                        OP2I(ICMD_CHECKASIZE, 0, 0);
                        switch (code_get_s1(p + 1)) {
                        case 4:
-                               BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR,currentline);
                                break;
                        case 5:
-                               BUILTIN1(BUILTIN_newarray_char, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_char, TYPE_ADR,currentline);
                                break;
                        case 6:
-                               BUILTIN1(BUILTIN_newarray_float, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_float, TYPE_ADR,currentline);
                                break;
                        case 7:
-                               BUILTIN1(BUILTIN_newarray_double, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_double, TYPE_ADR,currentline);
                                break;
                        case 8:
-                               BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR,currentline);
                                break;
                        case 9:
-                               BUILTIN1(BUILTIN_newarray_short, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_short, TYPE_ADR,currentline);
                                break;
                        case 10:
-                               BUILTIN1(BUILTIN_newarray_int, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_int, TYPE_ADR,currentline);
                                break;
                        case 11:
-                               BUILTIN1(BUILTIN_newarray_long, TYPE_ADR);
+                               BUILTIN1(BUILTIN_newarray_long, TYPE_ADR,currentline);
                                break;
                        default: panic("Invalid array-type to create");
                        }
@@ -949,11 +935,11 @@ void parse()
                        i = code_get_u2(p + 1);
                        {
                                        classinfo *component = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
-                                       LOADCONST_A(class_array_of(component)->vftbl);
+                                       LOADCONST_A_BUILTIN(class_array_of(component)->vftbl);
 
                                s_count++;
 
-                               BUILTIN2(BUILTIN_newarray, TYPE_ADR);
+                               BUILTIN2(BUILTIN_newarray, TYPE_ADR,currentline);
                        }
                        break;
 
@@ -963,7 +949,7 @@ void parse()
                        {
                                int v = code_get_u1(p + 3);
                                vftbl *arrayvftbl = ((classinfo*)class_getconstant (class, i, CONSTANT_Class))->vftbl;
-                               OP2A(opcode, v, arrayvftbl);                    
+                               OP2A(opcode, v, arrayvftbl,currentline);                        
                        }
                        break;
 
@@ -1073,7 +1059,7 @@ void parse()
                                        tablep = DMNEW(s4, num * 2 + 2);
                                }
 
-                               OP2A(opcode, 0, tablep);
+                               OP2A(opcode, 0, tablep,currentline);
 
                                /* default target */
 
@@ -1143,7 +1129,7 @@ void parse()
                                        tablep = DMNEW(s4, num + 1 + 3);
                                }
 
-                               OP2A(opcode, 0, tablep);
+                               OP2A(opcode, 0, tablep,currentline);
 
                                /* default target */
 
@@ -1195,7 +1181,7 @@ void parse()
                        /* load and store of object fields *******************/
 
                case JAVA_AASTORE:
-                       BUILTIN3(BUILTIN_aastore, TYPE_VOID);
+                       BUILTIN3(BUILTIN_aastore, TYPE_VOID,currentline);
                        break;
 
                case JAVA_PUTSTATIC:
@@ -1204,10 +1190,12 @@ void parse()
                        {
                                constant_FMIref *fr;
                                fieldinfo *fi;
-                               fr = class_getconstant (class, i, CONSTANT_Fieldref);
-                               fi = class_findfield (fr->class, fr->name, fr->descriptor);
-                               compiler_addinitclass (fr->class);
-                               OP2A(opcode, fi->type, fi);
+                               fr = class_getconstant(class, i, CONSTANT_Fieldref);
+                               fi = class_findfield(fr->class, fr->name, fr->descriptor);
+                               OP2A(opcode, fi->type, fi,currentline);
+                               if (!fi->class->initialized) {
+                                       isleafmethod = false;
+                               }
                        }
                        break;
 
@@ -1219,7 +1207,7 @@ void parse()
                                fieldinfo *fi;
                                fr = class_getconstant (class, i, CONSTANT_Fieldref);
                                fi = class_findfield (fr->class, fr->name, fr->descriptor);
-                               OP2A(opcode, fi->type, fi);
+                               OP2A(opcode, fi->type, fi,currentline);
                        }
                        break;
 
@@ -1244,7 +1232,7 @@ void parse()
                                descriptor2types(mi);
 
                                isleafmethod=false;
-                               OP2A(opcode, mi->paramcount, mi);
+                               OP2A(opcode, mi->paramcount, mi,currentline);
                        }
                        break;
 
@@ -1268,7 +1256,7 @@ void parse()
                                        panic ("Static/Nonstatic mismatch calling static method");
                                descriptor2types(mi);
                                isleafmethod=false;
-                               OP2A(opcode, mi->paramcount, mi);
+                               OP2A(opcode, mi->paramcount, mi,currentline);
                        }
                        break;
 
@@ -1284,7 +1272,7 @@ void parse()
                                        panic ("Static/Nonstatic mismatch calling static method");
                                descriptor2types(mi);
                                isleafmethod=false;
-                               OP2A(opcode, mi->paramcount, mi);
+                               OP2A(opcode, mi->paramcount, mi,currentline);
                        }
                        break;
 
@@ -1293,9 +1281,9 @@ void parse()
                case JAVA_NEW:
                        i = code_get_u2 (p+1);
 
-                       LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                       LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
                        s_count++;
-                       BUILTIN1(BUILTIN_new, TYPE_ADR);
+                       BUILTIN1(BUILTIN_new, TYPE_ADR,currentline);
                        break;
 
                case JAVA_CHECKCAST:
@@ -1307,17 +1295,17 @@ void parse()
                                        classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
                                        if (cls->vftbl->arraydesc) {
                                                /* array type cast-check */
-                                               LOADCONST_A(cls->vftbl);
+                                               LOADCONST_A_BUILTIN(cls->vftbl);
                                                s_count++;
-                                               BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR);
+                                               BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR,currentline);
                                        }
                                        else { /* object type cast-check */
                                                /*
-+                                                LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
++                                                LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
 +                                                s_count++;
-+                                                BUILTIN2(BUILTIN_checkcast, TYPE_ADR);
++                                                BUILTIN2(BUILTIN_checkcast, TYPE_ADR,currentline);
 +                                              */
-                                               OP2A(opcode, 1, cls);
+                                               OP2A(opcode, 1, cls,currentline);
                                        }
                                }
 
@@ -1333,17 +1321,17 @@ void parse()
                                        classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
                                        if (cls->vftbl->arraydesc) {
                                                /* array type cast-check */
-                                               LOADCONST_A(cls->vftbl);
+                                               LOADCONST_A_BUILTIN(cls->vftbl);
                                                s_count++;
-                                               BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT);
+                                               BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT,currentline);
                                        }
                                        else { /* object type cast-check */
                                                /*
-                                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+                                                 LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
                                                  s_count++;
-                                                 BUILTIN2(BUILTIN_instanceof, TYPE_INT);
+                                                 BUILTIN2(BUILTIN_instanceof, TYPE_INT,currentline);
 +                                              */
-                                               OP2A(opcode, 1, cls);
+                                               OP2A(opcode, 1, cls,currentline);
                                        }
                                }
                        break;
@@ -1351,7 +1339,7 @@ void parse()
                case JAVA_MONITORENTER:
 #ifdef USE_THREADS
                        if (checksync) {
-                               BUILTIN1(BUILTIN_monitorenter, TYPE_VOID);
+                               BUILTIN1(BUILTIN_monitorenter, TYPE_VOID,currentline);
                        } else
 #endif
                                {
@@ -1362,7 +1350,7 @@ void parse()
                case JAVA_MONITOREXIT:
 #ifdef USE_THREADS
                        if (checksync) {
-                               BUILTIN1(BUILTIN_monitorexit, TYPE_VOID);
+                               BUILTIN1(BUILTIN_monitorexit, TYPE_VOID,currentline);
                        }
                        else
 #endif
@@ -1393,7 +1381,7 @@ void parse()
 #if defined(__I386__)
                        OP(opcode);
 #else
-                       BUILTIN2(BUILTIN_frem, TYPE_FLOAT);
+                       BUILTIN2(BUILTIN_frem, TYPE_FLOAT,currentline);
 #endif
                        break;
 
@@ -1401,14 +1389,14 @@ void parse()
 #if defined(__I386__)
                        OP(opcode);
 #else
-                       BUILTIN2(BUILTIN_drem, TYPE_DOUBLE);
+                       BUILTIN2(BUILTIN_drem, TYPE_DOUBLE,currentline);
 #endif
                        break;
 
                case JAVA_F2I:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1(BUILTIN_f2i, TYPE_INT);
+                               BUILTIN1(BUILTIN_f2i, TYPE_INT,currentline);
                        } else
 #endif
                                {
@@ -1419,7 +1407,7 @@ void parse()
                case JAVA_F2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1(BUILTIN_f2l, TYPE_LONG);
+                               BUILTIN1(BUILTIN_f2l, TYPE_LONG,currentline);
                        } else 
 #endif
                                {
@@ -1430,7 +1418,7 @@ void parse()
                case JAVA_D2I:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1(BUILTIN_d2i, TYPE_INT);
+                               BUILTIN1(BUILTIN_d2i, TYPE_INT,currentline);
                        } else
 #endif
                                {
@@ -1441,7 +1429,7 @@ void parse()
                case JAVA_D2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
-                               BUILTIN1(BUILTIN_d2l, TYPE_LONG);
+                               BUILTIN1(BUILTIN_d2l, TYPE_LONG,currentline);
                        } else
 #endif
                                {
@@ -1541,7 +1529,7 @@ void parse()
        } /* end for */
 
        if (p != jcodelength)
-               panic("Command-sequence crosses code-boundary"); /* XXX change message */
+               panic("Command-sequence crosses code-boundary");
 
        if (!blockend)
                panic("Code does not end with branch/return/athrow - stmt");    
@@ -1638,7 +1626,7 @@ void parse()
                        extable[i].start = block + block_index[p];
 
                        p = extable[i].endpc;
-                       extable[i].end = block + block_index[p]; 
+                       extable[i].end = (p == cumjcodelength) ? last_block : (block + block_index[p]);
 
                        p = extable[i].handlerpc;
                        extable[i].handler = block + block_index[p];