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/sendfile_windows.go b/src/pkg/net/sendfile_windows.go
index 5012583..e9b9f91 100644
--- a/src/pkg/net/sendfile_windows.go
+++ b/src/pkg/net/sendfile_windows.go
@@ -10,20 +10,6 @@
 	"syscall"
 )
 
-type sendfileOp struct {
-	anOp
-	src syscall.Handle // source
-	n   uint32
-}
-
-func (o *sendfileOp) Submit() (err error) {
-	return syscall.TransmitFile(o.fd.sysfd, o.src, o.n, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
-}
-
-func (o *sendfileOp) Name() string {
-	return "TransmitFile"
-}
-
 // sendFile copies the contents of r to c using the TransmitFile
 // system call to minimize copies.
 //
@@ -33,7 +19,7 @@
 // if handled == false, sendFile performed no work.
 //
 // Note that sendfile for windows does not suppport >2GB file.
-func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
+func sendFile(fd *netFD, r io.Reader) (written int64, err error, handled bool) {
 	var n int64 = 0 // by default, copy until EOF
 
 	lr, ok := r.(*io.LimitedReader)
@@ -48,18 +34,18 @@
 		return 0, nil, false
 	}
 
-	if err := c.incref(false); err != nil {
+	if err := fd.incref(false); err != nil {
 		return 0, err, true
 	}
-	defer c.decref()
-	c.wio.Lock()
-	defer c.wio.Unlock()
-
-	var o sendfileOp
-	o.Init(c, 'w')
-	o.n = uint32(n)
-	o.src = syscall.Handle(f.Fd())
-	done, err := iosrv.ExecIO(&o)
+	defer fd.decref()
+	o := &fd.wop
+	o.mu.Lock()
+	defer o.mu.Unlock()
+	o.qty = uint32(n)
+	o.handle = syscall.Handle(f.Fd())
+	done, err := iosrv.ExecIO(o, "TransmitFile", func(o *operation) error {
+		return syscall.TransmitFile(o.fd.sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
+	})
 	if err != nil {
 		return 0, err, false
 	}