XO0531: a large parameter is only stored while each caller passes its last use
Reported by xo vet, not xo check. A parameter is borrowed from the caller: storing it (in a struct literal, a list or map literal, a push, put, or insert, rt.any_of) shares every reference counted field of the value (Str, Bytes, List, Map, handles), and the caller then releases its own copy after the call. When every caller passes a local it does not use again, storing the value at the caller (or returning it from the function) moves it instead and does neither walk. For a value with at least 8 such fields a profile of the HTTP/2 server found about 5,600 instructions a call. See decision 0263.
Example
struct Conn {
a: Str, b: Str, c: Str, d: Str
e: Str, f: Str, g: Str, h: Str
}
struct Saved {
conn: Conn
}
fn save(c: Conn) -> Saved {
Saved{conn: c}
}
fn handle(c: Conn) -> Saved {
let d = c
save(d)
}Fix
struct Conn {
a: Str, b: Str, c: Str, d: Str
e: Str, f: Str, g: Str, h: Str
}
struct Saved {
conn: Conn
}
fn handle(c: Conn) -> Saved {
let d = c
Saved{conn: d}
}Run xo explain XO0531 for this text in a terminal, or see
section 10.6 of the specification.