-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
In a number of cases, an input argument only escapes through the error value. Examples of this:
net.UDPConn.WriteToUDP
, theaddr
input only escapes when constructing an errorstrconv.ParseXXX
, the input strings
only escapes when constructing an error
In order to avoid escaping the input, one possibility is to copy the input before placing it in an error. This has the unfortunate downside of always allocating in the error case in situations when the input would have already been treated as being escaped.
Another way to work around this is to take advantage of "function outlining", where the part that causes an input to escape is moved to an inlineable wrapper function so that the compiler can better prove whether to allocate depending on how the function is used by the caller.
Example attempt at function outlining in strconv
:
func ParseFloat(s string, bitSize int) (float64, error) {
n, err := parseFloat(s, bitSize)
if err != nil {
err = &NumError{"ParseFloat", s, err}
}
return n, err
}
func parseFloat(s string, bitSize int) (float64, error)
Unfortunately ParseFloat
is not inlineable since it exceeds the inline budget. However, if it were within budget, then there are situations where we can avoid the NumError
allocation and treating s
as escaping. For example:
n, err := strconv.ParseFloat(s, 64)
ok := err == nil
return n, ok
In this snippet, the caller doesn't even care about the error value other than the fact that it was non-nil. If ParseFloat
was inlineable, the compiler can prove that NumError
does not escape and avoid heap allocating it. In fact, the compiler can (in theory) go a step further and realize that the error wrapping is dead code and eliminate it entirely (all we cared about was whether it was nil).
It would be nice if functions of the following pattern could be inlinable:
func Foo(...in) (...out, error) {
out..., err := foo(in...)
if err != nil {
err = ... // wrap the error somehow
}
return out..., err
}
I don't know if this means increasing the inline budget or matching on such code patterns.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status