From 515f3c0da643a3c2dfcf494ac0a7cf8f65002f38 Mon Sep 17 00:00:00 2001 From: Jes Cok Date: Mon, 20 Nov 2023 13:37:33 +0000 Subject: [PATCH] reflect: tweak logic for 'case Array' in IsZero For 'case Array' in IsZero, check 'v.flag&flagIndir == 0' in the first place, rename 'array' to 'typ' for consistency, and remove stale comment. Add line breaks for long sentence in isZero. Change-Id: Id06d01fd61eefd205bf4626e6b920ae82b459455 GitHub-Last-Rev: 7225ca3f7b55cbef58387365ed8f3ff104236a06 GitHub-Pull-Request: golang/go#64270 Reviewed-on: https://go-review.googlesource.com/c/go/+/543656 TryBot-Result: Gopher Robot Reviewed-by: Keith Randall Run-TryBot: Jes Cok Reviewed-by: Keith Randall Auto-Submit: Keith Randall Reviewed-by: Cherry Mui --- src/reflect/value.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/reflect/value.go b/src/reflect/value.go index 2bd41f37fd..068bac0050 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -1598,24 +1598,23 @@ func (v Value) IsZero() bool { case Complex64, Complex128: return v.Complex() == 0 case Array: - array := (*abi.ArrayType)(unsafe.Pointer(v.typ())) - // Avoid performance degradation of small benchmarks. + if v.flag&flagIndir == 0 { + return v.ptr == nil + } + typ := (*abi.ArrayType)(unsafe.Pointer(v.typ())) // If the type is comparable, then compare directly with zero. - if array.Equal != nil && array.Size() <= maxZero { - if v.flag&flagIndir == 0 { - return v.ptr == nil - } + if typ.Equal != nil && typ.Size() <= maxZero { // v.ptr doesn't escape, as Equal functions are compiler generated // and never escape. The escape analysis doesn't know, as it is a // function pointer call. - return array.Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0])) + return typ.Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0])) } - if array.TFlag&abi.TFlagRegularMemory != 0 { + if typ.TFlag&abi.TFlagRegularMemory != 0 { // For some types where the zero value is a value where all bits of this type are 0 // optimize it. - return isZero(unsafe.Slice(((*byte)(v.ptr)), array.Size())) + return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size())) } - n := int(array.Len) + n := int(typ.Len) for i := 0; i < n; i++ { if !v.Index(i).IsZero() { return false @@ -1663,7 +1662,7 @@ func isZero(b []byte) bool { return true } const n = 32 - // Align memory addresses to 8 bytes + // Align memory addresses to 8 bytes. for uintptr(unsafe.Pointer(&b[0]))%8 != 0 { if b[0] != 0 { return false @@ -1690,7 +1689,14 @@ func isZero(b []byte) bool { w = w[1:] } for len(w) >= n { - if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 || w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 || w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 || w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 || w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 || w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 || w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 || w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 { + if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 || + w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 || + w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 || + w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 || + w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 || + w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 || + w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 || + w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 { return false } w = w[n:]