diff --git a/bin/mkpeep.pike b/bin/mkpeep.pike index 66a0118ef5c6c3e864cfa4c20f3f494dc94481a3..623e817721ec9909fbe18f5d2d8d043a6c6c7dc4 100755 --- a/bin/mkpeep.pike +++ b/bin/mkpeep.pike @@ -2,7 +2,7 @@ #pragma strict_types -// $Id: mkpeep.pike,v 1.43 2006/09/16 16:39:52 grubba Exp $ +// $Id: mkpeep.pike,v 1.44 2006/09/17 15:53:31 grubba Exp $ #define SKIPWHITE(X) sscanf(X, "%*[ \t\n]%s", X) @@ -455,7 +455,7 @@ array(Switch|Breakable) make_switches(array(Rule) data) ops += ({ ({ sizeof(args)+1+", ", fcode+", ", @map(args,treat)[*]+", " }) }); } - opargs += reverse(ops) * ({}); + opargs += ({ sizeof(ops) + ", " }) + reverse(ops) * ({}); buf->add_line(" "*ind+"do_optimization(", opargs, "0);"); buf->add_line( sprintf("%*nreturn 1;", ind) ); diff --git a/src/peep.c b/src/peep.c index db2ae51914720d192dd14d2f06be9d5cf10a4eec..8fd7faabcf63293da9c0e0ab1c8edf9e93c05a4b 100644 --- a/src/peep.c +++ b/src/peep.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: peep.c,v 1.110 2006/09/16 16:50:08 grubba Exp $ +|| $Id: peep.c,v 1.111 2006/09/17 15:53:31 grubba Exp $ */ #include "global.h" @@ -57,15 +57,6 @@ static int asm_opt(void); dynamic_buffer instrbuf; long num_instrs = 0; -/* Stack holding pending instructions. - * Note that instructions must be pushed in reverse order. - * - * FIXME: Consider making the stack fixed size. - * /grubba 2006-09-16 - */ -dynamic_buffer instrstack; -long stack_depth = 0; - void init_bytecode(void) { @@ -334,9 +325,6 @@ INT32 assemble(int store_linenumbers) uses = jumps + max_label + 2; aliases = uses + max_label + 2; - initialize_buf(&instrstack); - stack_depth = 0; - while(relabel) { /* First do the relabel pass. */ @@ -471,15 +459,6 @@ INT32 assemble(int store_linenumbers) #endif /* 1 */ } -#ifdef PIKE_DEBUG - if (instrstack.s.len) { - Pike_fatal("PEEP: %d left over instructions on stack.\n", - instrstack.s.len / sizeof(p_instr)); - } -#endif - toss_buffer(&instrstack); - stack_depth = 0; - /* Time to create the actual bytecode. */ c=(p_instr *)instrbuf.s.str; @@ -803,13 +782,23 @@ INT32 assemble(int store_linenumbers) /**** Peephole optimizer ****/ -static void do_optimization(int topop, ...); +static void do_optimization(int topop, int topush, ...); static INLINE int opcode(int offset); static INLINE int argument(int offset); static INLINE int argument2(int offset); #include "peep_engine.c" +#ifndef PEEP_STACK_SIZE +#define PEEP_STACK_SIZE 256 +#endif + +/* Stack holding pending instructions. + * Note that instructions must be pushed in reverse order. + */ +static long stack_depth = 0; +static p_instr instrstack[PEEP_STACK_SIZE]; + int remove_clear_locals=0x7fffffff; static ptrdiff_t eye, len; static p_instr *instructions; @@ -826,11 +815,11 @@ static INLINE p_instr *insopt2(int f, INT32 a, INT32 b, Pike_fatal("hasarg2(%d /*%s */) is wrong!\n",f,get_f_name(f)); #endif - p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrstack); + p = instrstack + stack_depth++; #ifdef PIKE_DEBUG - if(!instrstack.s.len) - Pike_fatal("Low make buf space failed!!!!!!\n"); + if(stack_depth > PEEP_STACK_SIZE) + Pike_fatal("Instructions stacked too high!!!!!!\n"); #endif p->opcode=f; @@ -840,8 +829,6 @@ static INLINE p_instr *insopt2(int f, INT32 a, INT32 b, p->arg=a; p->arg2=b; - stack_depth++; - return p; } @@ -867,10 +854,6 @@ static INLINE p_instr *insopt0(int f, int cl, struct pike_string *cf) #ifdef PIKE_DEBUG static void debug(void) { - if(stack_depth != (long)instrstack.s.len / (long)sizeof(p_instr)) { - Pike_fatal("PEEP: instrstack out of whack (%d != %d)\n", - stack_depth, (long)instrstack.s.len / (long)sizeof(p_instr)); - } if (num_instrs != (long)instrbuf.s.len / (long)sizeof(p_instr)) { Pike_fatal("PEEP: instrbuf lost count (%d != %d)\n", num_instrs, (long)instrbuf.s.len / (long)sizeof(p_instr)); @@ -924,16 +907,14 @@ static int advance(void) p_instr *p; if(stack_depth) { - p = ((p_instr *)low_make_buf_space(0, &instrstack)) - 1; - stack_depth--; - instrstack.s.len -= sizeof(p_instr); + p = instrstack + --stack_depth; }else{ if (eye >= len) return 0; p = instructions + eye; eye++; } insert_opcode(p); - dmalloc_touch_named(struct pike_string *, p->file, "advance"); + debug_malloc_touch_named(p->file, "advance"); debug(); return 1; } @@ -958,7 +939,7 @@ static void pop_n_opcodes(int n) /* NOTE: Called with opcodes in reverse order! */ -static void do_optimization(int topop, ...) +static void do_optimization(int topop, int topush, ...) { va_list arglist; int q=0; @@ -980,12 +961,22 @@ static void do_optimization(int topop, ...) } #endif + if (stack_depth + topush > PEEP_STACK_SIZE) { + /* No place left on stack. Ignore the optimization. */ +#ifdef PIKE_DEBUG + if (a_flag) { + fprintf(stderr, "PEEP stack full.\n"); + } +#endif + return; + } + copy_shared_string(cf,dmalloc_touch_named(struct pike_string *, instr(0)->file, "do_optimization")); pop_n_opcodes(topop); - va_start(arglist, topop); + va_start(arglist, topush); while((oplen = va_arg(arglist, int))) { @@ -1034,7 +1025,7 @@ static void do_optimization(int topop, ...) #ifdef PIKE_DEBUG if(a_flag>5) { - p_instr *p = (p_instr *)low_make_buf_space(0, &instrstack); + p_instr *p = instrstack + stack_depth; int e; for(e=0;e<q;e++) { @@ -1043,6 +1034,10 @@ static void do_optimization(int topop, ...) } fprintf(stderr,"\n"); } + if (q != topush) { + Pike_fatal("PEEP: Lost track of instructions to push (%d != %d)\n", + q, topush); + } #endif /* Note: The 5 below is the longest