malloc bug fixes.

use malloc by default.
free stacks.

R=r
DELTA=424  (333 added, 29 deleted, 62 changed)
OCL=21553
CL=21584
diff --git a/test/mallocrep1.go b/test/mallocrep1.go
new file mode 100644
index 0000000..50f557b
--- /dev/null
+++ b/test/mallocrep1.go
@@ -0,0 +1,130 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Repeated malloc test.
+
+package main
+
+import (
+	"flag";
+	"fmt";
+	"malloc";
+	"strconv"
+)
+
+var chatty bool;
+var chatty_flag = flag.Bool("v", false, &chatty, "chatty");
+var reverse bool;
+var reverse_flag = flag.Bool("r", false, &reverse, "reverse");
+var longtest bool;
+var longtest_flag = flag.Bool("l", false, &longtest, "long test");
+
+var b *[]*byte;
+var stats = malloc.GetStats();
+
+func OkAmount(size, n uint64) bool {
+	if n < size {
+		return false
+	}
+	if size < 16*8 {
+		if n > size+16 {
+			return false
+		}
+	} else {
+		if n > size*9/8 {
+			return false
+		}
+	}
+	return true
+}
+
+func AllocAndFree(size, count int) {
+	if chatty {
+		fmt.printf("size=%d count=%d ...\n", size, count);
+	}
+	n1 := stats.alloc;
+	for i := 0; i < count; i++ {
+		b[i] = malloc.Alloc(uint64(size));
+		base, n := malloc.Lookup(b[i]);
+		if base != b[i] || !OkAmount(uint64(size), n) {
+			panicln("lookup failed: got", base, n, "for", b[i]);
+		}
+		if malloc.GetStats().sys > 1e9 {
+			panicln("too much memory allocated");
+		}
+	}
+	n2 := stats.alloc;
+	if chatty {
+		fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats);
+	}
+	n3 := stats.alloc;
+	for j := 0; j < count; j++ {
+		i := j;
+		if reverse {
+			i = count - 1 - j;
+		}
+		alloc := stats.alloc;
+		base, n := malloc.Lookup(b[i]);
+		if base != b[i] || !OkAmount(uint64(size), n) {
+			panicln("lookup failed: got", base, n, "for", b[i]);
+		}
+		malloc.Free(b[i]);
+		if stats.alloc != alloc - n {
+			panicln("free alloc got", stats.alloc, "expected", alloc - n, "after free of", n);
+		}
+		if malloc.GetStats().sys > 1e9 {
+			panicln("too much memory allocated");
+		}
+	}
+	n4 := stats.alloc;
+
+	if chatty {
+		fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats);
+	}
+	if n2-n1 != n3-n4 {
+		panicln("wrong alloc count: ", n2-n1, n3-n4);
+	}
+}
+
+func atoi(s string) int {
+	i, xx1 := strconv.atoi(s);
+	return i
+}
+
+func main() {
+	flag.Parse();
+	b = new([]*byte, 10000);
+	if flag.NArg() > 0 {
+		AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1)));
+		return;
+	}
+	for j := 1; j <= 1<<22; j<<=1 {
+		n := len(b);
+		max := uint64(1<<28);
+		if !longtest {
+			max = 1<<22;
+		}
+		if uint64(j)*uint64(n) > max {
+			n = int(max / uint64(j));
+		}
+		if n < 10 {
+			n = 10;
+		}
+		for m := 1; m <= n; {
+			AllocAndFree(j, m);
+			if m == n {
+				break
+			}
+			m = 5*m/4;
+			if m < 4 {
+				m++
+			}
+			if m > n {
+				m = n
+			}
+		}
+	}
+}