all: make benchmarks standalone binaries

This has better modularity, since it will let us add other benchamrks
that have different drivers. It also isolates the benchmarks better,
since it avoids contaminating the heap with data allocated at init
time by other benchmarks (e.g., the json benchmark does this).

For golang/go#14304.

Change-Id: I5636152c5ebbd4e416e4979f99c7eb192513a717
Reviewed-on: https://go-review.googlesource.com/33580
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/bench/bench.go b/bench/bench.go
deleted file mode 100644
index 5a0bb77..0000000
--- a/bench/bench.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 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.
-
-/*
-Bench contains benchmarks for the Go performance dashboard:
-	http://build.golang.org/perf
-Run without flags to get list of available benchmarks:
-	./bench
-	build,garbage,http,json
-To run a benchmark execute:
-	./bench -bench=json
-See the README file for more details.
-*/
-package main // import "golang.org/x/benchmarks/bench"
-
-import (
-	"golang.org/x/benchmarks/driver"
-
-	_ "golang.org/x/benchmarks/build"
-	_ "golang.org/x/benchmarks/garbage"
-	_ "golang.org/x/benchmarks/http"
-	_ "golang.org/x/benchmarks/json"
-)
-
-func main() {
-	driver.Main()
-}
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/build/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/build/build.go b/build/build.go
index f7a7b38..302bdd8 100644
--- a/build/build.go
+++ b/build/build.go
@@ -4,7 +4,7 @@
 
 // Build is a benchmark that examines compiler and linker performance.
 // It executes 'go build -a cmd/go'.
-package build // import "golang.org/x/benchmarks/build"
+package main
 
 import (
 	"log"
@@ -14,8 +14,8 @@
 	"golang.org/x/benchmarks/driver"
 )
 
-func init() {
-	driver.Register("build", benchmark)
+func main() {
+	driver.Main(benchmark)
 }
 
 func benchmark() driver.Result {
diff --git a/driver/driver.go b/driver/driver.go
index 2938644..d407724 100644
--- a/driver/driver.go
+++ b/driver/driver.go
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Driver contains common benchmarking logic shared between benchmarks.
-// It defines the main function which calls one of the benchmarks registered
-// with Register function.
-// When a benchmark is invoked it has 2 choices:
+// Package driver provides common benchmarking logic shared between benchmarks.
+//
+// A benchmark should call Main with a benchmark function. The
+// benchmark function can do one of two things when invoked:
 //  1. Do whatever it wants, fill and return Result object.
 //  2. Call Benchmark helper function and provide benchmarking function
 //  func(N uint64), similar to standard testing benchmarks. The rest is handled
@@ -30,7 +30,6 @@
 )
 
 var (
-	bench     = flag.String("bench", "", "benchmark to run")
 	flake     = flag.Int("flake", 0, "test flakiness of a benchmark")
 	benchNum  = flag.Int("benchnum", 5, "number of benchmark runs")
 	benchMem  = flag.Int("benchmem", 64, "approx RSS value to aim at in benchmarks, in MB")
@@ -44,8 +43,6 @@
 	BenchTime time.Duration
 	WorkDir   string
 
-	benchmarks = make(map[string]func() Result)
-
 	// startTrace starts runtime tracing if supported and
 	// requested and returns a function to stop tracing.
 	startTrace = func() func() {
@@ -53,11 +50,7 @@
 	}
 )
 
-func Register(name string, f func() Result) {
-	benchmarks[name] = f
-}
-
-func Main() {
+func Main(f func() Result) {
 	flag.Parse()
 	// Copy to public variables, so that benchmarks can access the values.
 	BenchNum = *benchNum
@@ -69,16 +62,6 @@
 		setProcessAffinity(*affinity)
 	}
 
-	if *bench == "" {
-		printBenchmarks()
-		return
-	}
-	f := benchmarks[*bench]
-	if f == nil {
-		fmt.Printf("unknown benchmark '%v'\n", *bench)
-		os.Exit(1)
-	}
-
 	setupWatchdog()
 
 	if *flake > 0 {
@@ -110,21 +93,6 @@
 	}
 }
 
-func printBenchmarks() {
-	var bb []string
-	for name, _ := range benchmarks {
-		bb = append(bb, name)
-	}
-	sort.Strings(bb)
-	for i, name := range bb {
-		if i != 0 {
-			fmt.Print(",")
-		}
-		fmt.Print(name)
-	}
-	fmt.Print("\n")
-}
-
 func setupWatchdog() {
 	t := *benchTime
 	// Be somewhat conservative, and build benchmark does not care about benchTime.
diff --git a/garbage/.gitignore b/garbage/.gitignore
new file mode 100644
index 0000000..656d5d8
--- /dev/null
+++ b/garbage/.gitignore
@@ -0,0 +1 @@
+/garbage
diff --git a/garbage/garbage.go b/garbage/garbage.go
index d96ba67..f1ac2d6 100644
--- a/garbage/garbage.go
+++ b/garbage/garbage.go
@@ -4,7 +4,7 @@
 
 // Garbage is a benchmark that stresses garbage collector.
 // It repeatedly parses net/http package with go/parser and then discards results.
-package garbage // import "golang.org/x/benchmarks/garbage"
+package main
 
 // The source of net/http was captured at git tag go1.5.2 by
 //go:generate sh -c "(echo 'package garbage'; echo 'var src = `'; bundle net/http http '' | sed 's/`/`+\"`\"+`/g'; echo '`') > nethttp.go"
@@ -21,10 +21,14 @@
 	"golang.org/x/benchmarks/driver"
 )
 
-func init() {
-	driver.Register("garbage", benchmark)
+func main() {
+	driver.Main(benchmark)
 }
 
+// func init() {
+// 	driver.Register("garbage", benchmark)
+// }
+
 type ParsedPackage *ast.File
 
 var (
diff --git a/garbage/nethttp.go b/garbage/nethttp.go
index 8580789..851a049 100644
--- a/garbage/nethttp.go
+++ b/garbage/nethttp.go
@@ -1,4 +1,4 @@
-package garbage
+package main
 
 var src = `
 // Code generated by golang.org/x/tools/cmd/bundle command:
diff --git a/http/.gitignore b/http/.gitignore
new file mode 100644
index 0000000..92c8a80
--- /dev/null
+++ b/http/.gitignore
@@ -0,0 +1 @@
+/http
diff --git a/http/http.go b/http/http.go
index 10144d8..97d5f8f 100644
--- a/http/http.go
+++ b/http/http.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // HTTP is a benchmark that examines client/server http performance.
-package http // import "golang.org/x/benchmarks/http"
+package main
 
 import (
 	"fmt"
@@ -18,8 +18,8 @@
 	"golang.org/x/benchmarks/driver"
 )
 
-func init() {
-	driver.Register("http", benchmark)
+func main() {
+	driver.Main(benchmark)
 }
 
 func benchmark() driver.Result {
diff --git a/json/.gitignore b/json/.gitignore
new file mode 100644
index 0000000..957206d
--- /dev/null
+++ b/json/.gitignore
@@ -0,0 +1 @@
+/json
diff --git a/json/json.go b/json/json.go
index 3507163..ffc5a11 100644
--- a/json/json.go
+++ b/json/json.go
@@ -4,7 +4,7 @@
 
 // JSON benchmark marshals and unmarshals ~2MB json string
 // with a tree-like object hierarchy, in 4*GOMAXPROCS goroutines.
-package json // import "golang.org/x/benchmarks/json"
+package main
 
 import (
 	"bytes"
@@ -17,8 +17,8 @@
 	"golang.org/x/benchmarks/driver"
 )
 
-func init() {
-	driver.Register("json", benchmark)
+func main() {
+	driver.Main(benchmark)
 }
 
 func benchmark() driver.Result {
diff --git a/json/json_data.go b/json/json_data.go
index 689b92b..2f76c63 100644
--- a/json/json_data.go
+++ b/json/json_data.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package json
+package main
 
 var jsonbz2_base64 = []byte(`
 QlpoOTFBWSZTWZ0H0LkG0bxfgFH8UAf/8D////q////6YSvJveAAAAAH3ddt7gAN