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