Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
proposal: cmd/compile: report index and length values in bounds panics #30116
Instead of reporting bounds check violations like this:
We could report them like this:
We've long assumed that it would be too expensive to provide this information in a panic. But I've done some experiments, and it seems not very expensive. Adding information for both index and slice expressions has a space overhead of about 0.8% (using the go binary as the guinea pig). There is approximately no performance overhead, other than the icache cost, as the non-panic instruction path is identical.
To first order, the cost is 2 extra instructions in each panic path. We'd go from
That's 5 to 14 bytes on amd64. Cost will vary somewhat based on circumstances (constant indexes, for instance). Also, stack frames might need to be a bit bigger due to the extra outargs space.
The main benefit is a improved debugging experience. Especially with slicing, when an out-of-bounds panic happens it is often not clear which part of the slice expression is to blame.
I think there's some need for discussion about what the panic strings would look like. Particularly for slice expressions, how do we report the message? Should we include just the two values which triggered the violation (low and high if low > high, or high and cap if high > cap), or report all the slice args + the cap? Also, should we provide some programmatic way of accessing the failing index values, or just provide an updated string? (I vote the latter.)
This proposal was sort of discussed in #29435. The two main objections were the overhead (discussed above) and the fact that people might be depending on the text of the current messages.
I seem to remember that when the compiler is made a bit slower for a wanted feature, it's "paid for" by unrelated optimizations that offset the slowness. In light of #6853, perhaps we should do the same here to ensure that binaries don't keep getting bigger and bigger, like they've already been doing in 1.11 and 1.12.
I believe the compiler did this very early, but then we backed it out for code size reasons.
There is another way to do this, which is to arrange that the index and address are always in the same place when you call panicindex.
Note also that we could further reduce the space overhead on amd64 by writing 16*15 different panicindex functions (or just jump into different entry points in one long function), one for each pair of registers holding the numbers we want. Probably not worth it but if that 0.8% really needs to come down...
I've updated my experimental CL to use a register-based calling convention for bounds check panics.
There are a bunch of reasons why the register-based convention isn't more advantageous:
All 16*15 panicindex functions would help, but...
There are still things we could do:
I think we're getting toward diminishing return ideas here, though.
Turns out this makes the fix for 28797 unnecessary, because this order ensures that the RHS of IsSliceInBounds ops are always nonnegative. The real reason for this change is that it also makes dealing with <0 values easier for reporting values in bounds check panics (issue #30116). Makes cmd/go negligibly smaller. Update #28797 Change-Id: I1f25ba6d2b3b3d4a72df3105828aa0a4b629ce85 Reviewed-on: https://go-review.googlesource.com/c/go/+/166377 Run-TryBot: Keith Randall <email@example.com> Reviewed-by: Brad Fitzpatrick <firstname.lastname@example.org> TryBot-Result: Gobot Gobot <email@example.com>
Bounds check errors should now be reporting index+length on failures. Time to bikeshed the text!
A few examples (for accessing a slice of length 3):
You can see a complete list of errors in the test in the CL. If you think you have a better wording, send me a CL modifying the format strings in runtime/error.go.
Some of the registers in which indexes + length were supposed to be passed were wrong. Update #30116 Change-Id: I1089366b7429c1e0ecad9219b847db069ce6b5d6 Reviewed-on: https://go-review.googlesource.com/c/go/+/168041 Run-TryBot: Keith Randall <firstname.lastname@example.org> Reviewed-by: Brad Fitzpatrick <email@example.com> TryBot-Result: Gobot Gobot <firstname.lastname@example.org>
This implements https://golang.org/cl/161477 in the gofrontend. Updates golang/go#30116 Change-Id: Iec6c26d630131cfefb56391ef1b58035451e13bc Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191881 Reviewed-by: Cherry Zhang <email@example.com> Reviewed-by: Than McIntosh <firstname.lastname@example.org>
This implements https://golang.org/cl/161477 in the gofrontend. Updates golang/go#30116 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191881 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@274998 138bc75d-0d04-0410-961f-82ee72b054a4