net: reduce number of memory allocations during IO operations
Embed all data necessary for read/write operations directly into netFD.

benchmark                    old ns/op    new ns/op    delta
BenchmarkTCP4Persistent          27669        23341  -15.64%
BenchmarkTCP4Persistent-2        18173        12558  -30.90%
BenchmarkTCP4Persistent-4        10390         7319  -29.56%

This change will intentionally break all builders to see
how many allocations they do per read/write.
This will be fixed soon afterwards.

R=golang-dev, alex.brainman
CC=golang-dev
https://golang.org/cl/12413043
diff --git a/src/pkg/net/tcp_test.go b/src/pkg/net/tcp_test.go
index f356f92..dedd41d 100644
--- a/src/pkg/net/tcp_test.go
+++ b/src/pkg/net/tcp_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"fmt"
+	"io"
 	"reflect"
 	"runtime"
 	"sync"
@@ -327,3 +328,46 @@
 	ln.Close()
 	wg.Wait()
 }
+
+func TestTCPReadWriteMallocs(t *testing.T) {
+	maxMallocs := 0
+	switch runtime.GOOS {
+	// Add other OSes if you know how many mallocs they do.
+	case "windows":
+		maxMallocs = 0
+	}
+	ln, err := Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("Listen failed: %v", err)
+	}
+	defer ln.Close()
+	var server Conn
+	errc := make(chan error)
+	go func() {
+		var err error
+		server, err = ln.Accept()
+		errc <- err
+	}()
+	client, err := Dial("tcp", ln.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial failed: %v", err)
+	}
+	if err := <-errc; err != nil {
+		t.Fatalf("Accept failed: %v", err)
+	}
+	defer server.Close()
+	var buf [128]byte
+	mallocs := testing.AllocsPerRun(1000, func() {
+		_, err := server.Write(buf[:])
+		if err != nil {
+			t.Fatalf("Write failed: %v", err)
+		}
+		_, err = io.ReadFull(client, buf[:])
+		if err != nil {
+			t.Fatalf("Read failed: %v", err)
+		}
+	})
+	if int(mallocs) > maxMallocs {
+		t.Fatalf("Got %v allocs, want %v", mallocs, maxMallocs)
+	}
+}