From 3e19dc2b237339420fc7e97a2766710a68ac29c2 Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Fri, 7 Oct 2022 18:11:10 -0400 Subject: [PATCH] reflect: make Value.IsZero not escape With CL 408826 reflect.Value not always escape. IsZero still escapes the Value because in some cases it passes the Value pointer to the equal function, which is function pointer. Equal functions are compiler generated and never escapes, but the escape analysis doesn't know. Add noescape to help. Change-Id: Ica397c2be77cac9e8a46d03d70bac385b0aa9e82 Reviewed-on: https://go-review.googlesource.com/c/go/+/441937 Reviewed-by: David Chase Run-TryBot: Cherry Mui TryBot-Result: Gopher Robot --- src/reflect/value.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/reflect/value.go b/src/reflect/value.go index b2b3fd1e3d..616da6a5c7 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -1598,7 +1598,10 @@ func (v Value) IsZero() bool { if v.flag&flagIndir == 0 { return v.ptr == nil } - return v.typ().Equal(v.ptr, unsafe.Pointer(&zeroVal[0])) + // 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 v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0])) } n := v.Len() @@ -1618,7 +1621,8 @@ func (v Value) IsZero() bool { if v.flag&flagIndir == 0 { return v.ptr == nil } - return v.typ().Equal(v.ptr, unsafe.Pointer(&zeroVal[0])) + // See noescape justification above. + return v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0])) } n := v.NumField() -- 2.48.1