Description
It would be nice to optimize Write([]byte(stringVal))
to not copy the string value. This is normally safe because most Write
methods do not modify the byte slice passed in. In fact, the documentation for io.Writer
requires that the Write
method not modify the byte slice, although this is not (and can not be) enforced.
Here is how we can do this.
For each function and method that takes a parameter of slice type, record whether the slice's underlying array is modified. This will require generating annotations similar to the ones we generate for escape analysis. Assembly functions will require an annotation similar to //go:noescape. (Naturally, a slice that escapes must be treated as modified.)
For each call of the form F([]byte(stringVal))
, where we know that F
does not modify the slice, we can pass the string value directly. This would do essentially the same thing as the existing optimization for map lookups in which a []byte
is converted to a string
. This fixes direct calls, but of course the interesting cases all involve calls to methods of values of type io.Writer
.
For any type with a Write
method that does modify the slice, generate at compile time an additional Write·2
method that makes a copy of the slice and then calls the Write
method. The method is named Write·2
to ensure that it does not conflict with any user written method.
When converting any type to io.Writer
(or any interface type that inherits from io.Writer
), check for the presence of a Write·2
method. If that method exists, add it to the interface as an additional entry in the itab.
For any call to an interface method Write([]byte(stringVal))
, modify the call to call a special function doWrite
in the io package, without copying the string. doWrite
will check for a Write·2
method, and call it if it exists; that will cause the string to be copied as happens today. If the Write·2
method does not exist, which will be the normal case, doWrite
will call the Write
method as usual, knowing that the Write
method does not modify the slice.
Generalizing this to other methods is left as an exercise for the reader.