]> Cypherpunks repositories - gostls13.git/commitdiff
fmt: avoid reflect.Value.Pointer to help escape analysis
authorthepudds <thepudds1460@gmail.com>
Wed, 21 Jun 2023 18:18:56 +0000 (14:18 -0400)
committerGopher Robot <gobot@golang.org>
Thu, 7 Sep 2023 01:47:02 +0000 (01:47 +0000)
This is part of a series of CLs that aim to reduce how often
interface arguments escape for the print functions in fmt.

Prior to this change, one reason arguments escape is because
fmtPointer calls reflect.Value.Pointer:

./print.go:551:39: parameter value leaks to <heap> for (*pp).fmtPointer with derefs=0:
./print.go:551:39:   flow: <heap> ← value:
./print.go:551:39:     from reflect.Value.Pointer(value) (call parameter) at ./print.go:555:20

printValue also has its value argument escape for this reason,
among others.

This CL changes those uses to reflect.Value.UnsafePointer instead,
which does not cause an escape.

Arguments still escape for other reasons.

Change-Id: I81c4f737f11fe835c5ccb122caee40a39b553451
Reviewed-on: https://go-review.googlesource.com/c/go/+/524939
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: t hepudds <thepudds1460@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/fmt/print.go

index 50381f785f490662fe49b10b0aea79f9724a31bc..9225e2e28cca08785499e99ea8d513aebed90167 100644 (file)
@@ -550,7 +550,7 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune) {
        var u uintptr
        switch value.Kind() {
        case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:
-               u = value.Pointer()
+               u = uintptr(value.UnsafePointer())
        default:
                p.badVerb(verb)
                return
@@ -916,7 +916,7 @@ func (p *pp) printValue(value reflect.Value, verb rune, depth int) {
        case reflect.Pointer:
                // pointer to array or slice or struct? ok at top level
                // but not embedded (avoid loops)
-               if depth == 0 && f.Pointer() != 0 {
+               if depth == 0 && f.UnsafePointer() != nil {
                        switch a := f.Elem(); a.Kind() {
                        case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
                                p.buf.writeByte('&')