Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bufio: Writer.Writer's []byte argument escapes #5492

Closed
bradfitz opened this issue May 16, 2013 · 3 comments
Closed

bufio: Writer.Writer's []byte argument escapes #5492

bradfitz opened this issue May 16, 2013 · 3 comments

Comments

@bradfitz
Copy link
Contributor

It's not possible to Write to a *bufio.Writer without the []byte argument escaping, due
to the fast path passing p through an interface value:

package bufio
...
func (b *Writer) Write(p []byte) (nn int, err error) {
    for len(p) > b.Available() && b.err == nil {
                var n int
        if b.Buffered() == 0 {
            // Large write, empty buffer.
            // Write directly from p to avoid copy.
            n, b.err = b.wr.Write(p)    // <------------ escapes
        } else {
                        n = copy(b.buf[b.n:], p)
            b.n += n
            b.Flush()
        }
                nn += n
        p = p[n:]
    }
        if b.err != nil {
        return nn, b.err
    }
        n := copy(b.buf[b.n:], p)
    b.n += n
    nn += n
    return nn, nil
}


Possible solutions:

0) do nothing.  accept that it's not possible to have a caller do a small write from a
stack-local byte array.  I don't like this option.

1) remove the fast path above.  that's also sad, since it'd be worse in the common cases.

2) add a new public method on *bufio.Writer that's like Write, but without its p []byte
argument escaping.  This is gross, because it's new API for a performance thing.

3) instead of passing p to b.wr.Write in the line of code labeled above, instead play a
game where we pass a copy of p if &p[0] is on the stack, otherwise pass p directly
(but this would probably involve gross unsafe tricks to avoid the compiler thinking that
p escapes)

4) caller can do a loop on its stack-local byte array and call WriteByte for each input.
 this is what I've done so far.
@minux
Copy link
Member

minux commented May 17, 2013

Comment 1:

the buffer passed to Write method of Writer interface shouldn't escape at all,
could we introduce a mechanism to label a method argument can't escape
and enforce the check at compile time and runtime?

@ianlancetaylor
Copy link
Contributor

Comment 2:

Injecting any such notion into the type system gets pretty hairy pretty quickly.  But if
anybody has a specific proposal, we can look at it.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 3:

The only option that doesn't get bad fast is "do nothing".

Status changed to Unfortunate.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants