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 $
*/
#include <string.h>
#include "parse.h"
#include "global.h"
+#include "main.h"
#include "jit.h"
#include "parseRT.h"
#include "inline.h"
#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
/* 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) \
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;
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* */
}
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) {
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) */
#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)) {
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");
}
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;
{
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;
tablep = DMNEW(s4, num * 2 + 2);
}
- OP2A(opcode, 0, tablep);
+ OP2A(opcode, 0, tablep,currentline);
/* default target */
tablep = DMNEW(s4, num + 1 + 3);
}
- OP2A(opcode, 0, tablep);
+ OP2A(opcode, 0, tablep,currentline);
/* default target */
/* load and store of object fields *******************/
case JAVA_AASTORE:
- BUILTIN3(BUILTIN_aastore, TYPE_VOID);
+ BUILTIN3(BUILTIN_aastore, TYPE_VOID,currentline);
break;
case JAVA_PUTSTATIC:
{
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;
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;
descriptor2types(mi);
isleafmethod=false;
- OP2A(opcode, mi->paramcount, mi);
+ OP2A(opcode, mi->paramcount, mi,currentline);
}
break;
panic ("Static/Nonstatic mismatch calling static method");
descriptor2types(mi);
isleafmethod=false;
- OP2A(opcode, mi->paramcount, mi);
+ OP2A(opcode, mi->paramcount, mi,currentline);
}
break;
panic ("Static/Nonstatic mismatch calling static method");
descriptor2types(mi);
isleafmethod=false;
- OP2A(opcode, mi->paramcount, mi);
+ OP2A(opcode, mi->paramcount, mi,currentline);
}
break;
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:
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);
}
}
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;
case JAVA_MONITORENTER:
#ifdef USE_THREADS
if (checksync) {
- BUILTIN1(BUILTIN_monitorenter, TYPE_VOID);
+ BUILTIN1(BUILTIN_monitorenter, TYPE_VOID,currentline);
} else
#endif
{
case JAVA_MONITOREXIT:
#ifdef USE_THREADS
if (checksync) {
- BUILTIN1(BUILTIN_monitorexit, TYPE_VOID);
+ BUILTIN1(BUILTIN_monitorexit, TYPE_VOID,currentline);
}
else
#endif
#if defined(__I386__)
OP(opcode);
#else
- BUILTIN2(BUILTIN_frem, TYPE_FLOAT);
+ BUILTIN2(BUILTIN_frem, TYPE_FLOAT,currentline);
#endif
break;
#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
{
case JAVA_F2L:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1(BUILTIN_f2l, TYPE_LONG);
+ BUILTIN1(BUILTIN_f2l, TYPE_LONG,currentline);
} else
#endif
{
case JAVA_D2I:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1(BUILTIN_d2i, TYPE_INT);
+ BUILTIN1(BUILTIN_d2i, TYPE_INT,currentline);
} else
#endif
{
case JAVA_D2L:
#if defined(__ALPHA__)
if (!opt_noieee) {
- BUILTIN1(BUILTIN_d2l, TYPE_LONG);
+ BUILTIN1(BUILTIN_d2l, TYPE_LONG,currentline);
} else
#endif
{
} /* 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");
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];