compiler: calculate max number of entries in slice at compile time

This avoids difficult multiply-with-overflow code and avoids a multiply
at runtime.
This commit is contained in:
Ayke van Laethem
2019-02-07 17:37:22 +01:00
committed by Ron Evans
parent 26e7e93478
commit b837c94366
3 changed files with 39 additions and 28 deletions
+4 -10
View File
@@ -57,21 +57,15 @@ func sliceBoundsCheck64(capacity uintptr, low, high uint64) {
}
// Check for bounds in *ssa.MakeSlice.
func sliceBoundsCheckMake(length, capacity uintptr, elementSizeDoubled uintptr) {
overflow := uint64(capacity*elementSizeDoubled) != uint64(capacity)*uint64(elementSizeDoubled)
if length > capacity || overflow {
func sliceBoundsCheckMake(length, capacity uintptr, max uintptr) {
if length > capacity || capacity > max {
runtimePanic("slice size out of range")
}
}
// Check for bounds in *ssa.MakeSlice. Supports 64-bit indexes.
func sliceBoundsCheckMake64(length, capacity uint64, elementSizeDoubled uintptr) {
// This function is only ever called on systems where uintptr is smaller
// than uint64 (thus must be 32-bit or less). So multiplying as uint64 will
// never overflow if we know that capacity fits in uintptr.
// That elementSizeDoubled fits in uintptr is checked by the compiler.
overflow := capacity != uint64(uintptr(capacity)) || capacity != uint64(uintptr(capacity*uint64(elementSizeDoubled)))
if length > capacity || overflow {
func sliceBoundsCheckMake64(length, capacity uint64, max uintptr) {
if length > capacity || capacity > uint64(max) {
runtimePanic("slice size out of range")
}
}