aboutsummaryrefslogtreecommitdiff
path: root/src/reflect/value.go
AgeCommit message (Collapse)Author
2026-03-16reflect: document corner cases of TypeAssertMateusz Poliwczak
These cases might not be obvious just by looking at the generic function signature and might be worth explicitly mentioning in the doc comment. Updates #78007 Updates #62121 Change-Id: Ic0b0f78f4f87d35d0463c09ed5476c336a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/753741 Reviewed-by: Carlos Amedee <carlos@golang.org> Reviewed-by: Joseph Tsai <joetsai@digital-static.net> Reviewed-by: Mark Freeman <markfreeman@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Auto-Submit: Mateusz Poliwczak <mpoliwczak34@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2026-03-02reflect: outlilne []runtimeSelect allocation in SelectMateusz Poliwczak
With CL 707255 doing so we don't cause heap alloaction of the sllice, instead it is stored on the stack. goos: linux goarch: amd64 pkg: reflect cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz │ /tmp/before │ /tmp/after │ │ sec/op │ sec/op vs base │ Select/1-8 41.66n ± 1% 41.89n ± 0% ~ (p=0.151 n=20) Select/4-8 149.3n ± 1% 149.1n ± 8% ~ (p=0.324 n=20) Select/8-8 355.0n ± 1% 358.1n ± 1% +0.87% (p=0.002 n=20) SelectStaticLit/[4]SelectCase-8 153.3n ± 0% 151.9n ± 1% -0.88% (p=0.005 n=20) SelectStaticLit/[8]SelectCase-8 363.1n ± 1% 299.9n ± 0% -17.42% (p=0.000 n=20) geomean 165.2n 159.1n -3.69% │ /tmp/before │ /tmp/after │ │ B/op │ B/op vs base │ Select/1-8 8.000 ± 0% 8.000 ± 0% ~ (p=1.000 n=20) ¹ Select/4-8 96.00 ± 0% 96.00 ± 0% ~ (p=1.000 n=20) ¹ Select/8-8 512.0 ± 0% 512.0 ± 0% ~ (p=1.000 n=20) ¹ SelectStaticLit/[4]SelectCase-8 96.00 ± 0% 96.00 ± 0% ~ (p=1.000 n=20) ¹ SelectStaticLit/[8]SelectCase-8 512.0 ± 0% 256.0 ± 0% -50.00% (p=0.000 n=20) geomean 114.1 99.32 -12.94% ¹ all samples are equal │ /tmp/before │ /tmp/after │ │ allocs/op │ allocs/op vs base │ Select/1-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=20) ¹ Select/4-8 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=20) ¹ Select/8-8 11.00 ± 0% 11.00 ± 0% ~ (p=1.000 n=20) ¹ SelectStaticLit/[4]SelectCase-8 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=20) ¹ SelectStaticLit/[8]SelectCase-8 11.00 ± 0% 10.00 ± 0% -9.09% (p=0.000 n=20) geomean 4.968 4.874 -1.89% Updates #75620 Change-Id: I6a6a696492a4c07d8a3c03de0a36edbf400af506 Reviewed-on: https://go-review.googlesource.com/c/go/+/707275 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: David Chase <drchase@google.com>
2026-02-24reflect: use &zeroVal[0] instead of nil for data field for zero-sized payloadsKeith Randall
Because our wrapper functions barf if the pointer is nil, even if we don't actually dereference the pointer. Fixes #77779 Change-Id: Ib1b93d9f0fdc771cd884137007508ba2b1da4b7a Reviewed-on: https://go-review.googlesource.com/c/go/+/748660 Reviewed-by: Ian Lance Taylor <iant@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Keith Randall <khr@google.com>
2026-01-27reflect: allow conversions between slices of named {byte,rune} and stringKeith Randall
So the reflect behavior matches that of the language. These conversions are allowed: []myByte <-> string []myRune <-> string []myByte <-> myString []myRune <-> myString And even if the left-hand-side is named, e.g. myBytes([]myByte) <-> string Fixes #53523 Change-Id: I6562e72bc233a45dc7b02f75f68020831ad399ea Reviewed-on: https://go-review.googlesource.com/c/go/+/739680 Auto-Submit: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-12-29reflect: document Call/CallSlice panic when v is unexported fieldqiulaidongfeng
Fixes #74377 Change-Id: I250d67ef2a4bf4dac939be669eeaf1091523ac06 Reviewed-on: https://go-review.googlesource.com/c/go/+/690617 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2025-11-25reflect: add iterator equivalents for NumField, NumIn, NumOut and NumMethodQuentin Quaadgras
The new methods are Type.Fields, Type.Methods, Type.Ins, Type.Outs, Value.Fields and Value.Methods. These methods have been introduced into the reflect package (as well as tests) replacing three-clause for loops where possible. Fixes #66631 Change-Id: Iab346e52c0eadd7817afae96d9ef73a35db65fd2 GitHub-Last-Rev: 8768ef71b9fd74536094cb1072c7075dc732cd5c GitHub-Pull-Request: golang/go#75646 Reviewed-on: https://go-review.googlesource.com/c/go/+/707356 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Alan Donovan <adonovan@google.com> Auto-Submit: Alan Donovan <adonovan@google.com>
2025-11-14cmd/compile: allow multi-field structs to be stored directly in interfacesKeith Randall
If the struct is a bunch of 0-sized fields and one pointer field. Merged revert-of-revert for 4 CLs. original revert 681937 695016 693415 694996 693615 695015 694195 694995 Fixes #74092 Update #74888 Update #74908 Update #74935 (updated issues are bugs in the last attempt at this) Change-Id: I32246d49b8bac3bb080972dc06ab432a5480d560 Reviewed-on: https://go-review.googlesource.com/c/go/+/714421 Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
2025-10-29internal/itoa, internal/runtime/strconv: deleteRuss Cox
Replaced by internal/strconv. Change-Id: I0656a9ad5075e60339e963fbae7d194d2f3e16be Reviewed-on: https://go-review.googlesource.com/c/go/+/716001 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-23reflect: remove stale comment in unpackEfaceMateusz Poliwczak
e.word (or more properly e.Data) is always a pointer now. Change-Id: I6a6a6964b17797e234829691ced842ab431ec38f Reviewed-on: https://go-review.googlesource.com/c/go/+/705535 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-23reflect: allocate memory in TypeAssert[I] only when the assertion succeedsMateusz Poliwczak
goos: linux goarch: amd64 pkg: reflect cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz │ /tmp/before │ /tmp/after │ │ sec/op │ sec/op vs base │ TypeAssert/TypeAssert[int](int)-8 2.599n ± 1% 2.558n ± 0% -1.56% (p=0.000 n=30) TypeAssert/TypeAssert[uint8](int)-8 2.506n ± 1% 2.579n ± 2% +2.93% (p=0.008 n=30) TypeAssert/TypeAssert[fmt.Stringer](reflect_test.testTypeWithMethod)-8 7.449n ± 2% 7.776n ± 2% +4.39% (p=0.000 n=30) TypeAssert/TypeAssert[fmt.Stringer](*reflect_test.testTypeWithMethod)-8 7.220n ± 2% 7.439n ± 1% +3.04% (p=0.000 n=30) TypeAssert/TypeAssert[interface_{}](int)-8 4.015n ± 1% 4.207n ± 1% +4.79% (p=0.000 n=30) TypeAssert/TypeAssert[interface_{}](reflect_test.testTypeWithMethod)-8 4.003n ± 1% 4.190n ± 2% +4.66% (p=0.000 n=30) TypeAssert/TypeAssert[time.Time](time.Time)-8 2.933n ± 1% 2.942n ± 1% ~ (p=0.327 n=20+30) TypeAssert/TypeAssert[func()_string](func()_string)-8 111.5n ± 1% geomean 4.004n 6.208n +2.62% Change-Id: I6a6a6964d6f9c794adc15dc5ff3dc8634b30df89 Reviewed-on: https://go-review.googlesource.com/c/go/+/705255 Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Mateusz Poliwczak <mpoliwczak34@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Junyang Shao <shaojunyang@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-08-11Revert "reflect: handle zero-sized fields of directly-stored structures ↵Keith Randall
correctly" This reverts commit b3388569a187ea6be48caa41265f2b4dbc2fdfd3 (CL 694195) Reason for revert: still causing compiler failures on Google test code Change-Id: I2a9b0f9a57fe2b6977238bbfbefb572545210b9f Reviewed-on: https://go-review.googlesource.com/c/go/+/694995 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2025-08-08reflect: handle zero-sized fields of directly-stored structures correctlyKeith Randall
type W struct { E struct{} X *byte } type W is a "direct" type. That is, it is a pointer-ish type that can be stored directly as the second word of an interface. But if we ask reflect for W's first field, that value must *not* be direct, as zero-sized things cannot be stored directly. This was a problem introduced in CL 681937. Before that, types like W were not eligible for directness. Fixes #74935 Change-Id: Idefb55c23eaa59153009f863bad611593981e5cb Reviewed-on: https://go-review.googlesource.com/c/go/+/694195 Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-07-29internal/abi: move direct/indirect flag from Kind to TFlagKeith Randall
This info makes more sense in the flags instead of as a high bit of the kind. This makes kind access simpler because we now don't need to mask anything. Cleaned up most direct field accesses to use methods instead. (reflect making new types is the only remaining direct accessor.) IfaceIndir -> !IsDirectIface everywhere. gocore has been updated to handle the new location. So has delve. TODO: any other tools need updating? Change-Id: I123f97a4d4bdd0bff1641ee7e276d1cc0bd7e8eb Reviewed-on: https://go-review.googlesource.com/c/go/+/681936 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-06-27reflect: fix TypeAssert on nil interface valuesJoe Tsai
In the Go language a type assertion of a nil interface value will always report false: var err error v, ok := err.(error) // always reports (nil, false) Consequently, assertion on a reflect.Value.Interface() will also report false: var err error rv := ValueOf(&err).Elem() v, ok := rv.Interface().(error) // reports (nil, false) However, prior to this change, a TypeAssert would report true: var err error rv := ValueOf(&err).Elem() v, ok := TypeAssert[error](rv) // reports (nil, true) when it should report false. This fixes TypeAssert to match the Go language by pushing the typ != v.typ check to the very end after we have validated that neither v nor T are interface kinds. Fixes #74404 Change-Id: Ie14d5cf18c8370c3e27ce4bdf4570c89519d8a16 Reviewed-on: https://go-review.googlesource.com/c/go/+/684675 Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Joseph Tsai <joetsai@digital-static.net> Reviewed-by: Mateusz Poliwczak <mpoliwczak34@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-05-21reflect: leak packEface input to result rather than heapthepudds
This is part of a series of CLs that aim to help allocations in reflect and reduce how often interface arguments escape for the print functions in fmt. Before this change, the reflect.Value parameter for packEface leaks immediately to the heap due to the various ODOTPTR operations on the *emptyInterface. The -m=2 logs report: parameter v leaks to <heap> for packEface with derefs=0: flow: <heap> ← v: from v.ptr (dot) at .\value.go:145:13 from e.word = v.ptr (assign) at .\value.go:145:10 After this change, the input leaks to the result, which is what we want: parameter v leaks to ~r0 with derefs=0: flow: e = v: from v.ptr (dot) at .\value.go:143:13 from e.Data = v.ptr (assign) at .\value.go:143:10 flow: ~r0 = e: from &e (address-of) at .\value.go:147:32 from *(*any)(unsafe.Pointer(&e)) (indirection) at .\value.go:147:9 from return *(*any)(unsafe.Pointer(&e)) (return) at .\value.go:147:2 This change here is needed, but reflect.Value.Interface still leaks its input to the heap for other reasons having to do with method values, which we attempt to address in CL 530097, CL 530095, and CL 530096. Updates #8618 Updates #71349 Change-Id: Ie77bc850ff261212eeafe190bd6f9a879676a51d Reviewed-on: https://go-review.googlesource.com/c/go/+/528535 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: qiu laidongfeng2 <2645477756@qq.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
2025-05-21reflect: optimize IsZero with a pointer comparison to global zeroValthepudds
Our prior CL 649078 teaches the compiler to use a pointer to runtime.zeroVal as the data pointer for an interface in cases it where it can see that a zero value struct or array is being used in an interface conversion. This applies to some uses with reflect, such as: s := S{} v := reflect.ValueOf(s) This CL builds on that to do a cheap pointer check in reflect.IsZero to see if the Value points to runtime.zeroVal, which means it is a zero value. An alternative might be to do an initial pointer check in the typ.Equal function for types where it makes sense to do but doesn't already. This CL gives a performance boost of -51.71% geomean for BenchmarkZero/IsZero, with most of the impact there on arrays of structs. (The left column is CL 649078 and the right column is this CL). goos: linux goarch: amd64 pkg: reflect cpu: Intel(R) Xeon(R) CPU @ 2.80GHz │ find-zeroVal │ check-zeroVal │ │ sec/op │ sec/op vs base │ Zero/IsZero/ByteArray/size=16-4 4.171n ± 0% 3.123n ± 0% -25.13% (p=0.000 n=20) Zero/IsZero/ByteArray/size=64-4 3.864n ± 0% 3.129n ± 0% -19.02% (p=0.000 n=20) Zero/IsZero/ByteArray/size=1024-4 3.878n ± 0% 3.126n ± 0% -19.39% (p=0.000 n=20) Zero/IsZero/BigStruct/size=1024-4 5.061n ± 0% 3.273n ± 0% -35.34% (p=0.000 n=20) Zero/IsZero/SmallStruct/size=16-4 4.191n ± 0% 3.275n ± 0% -21.87% (p=0.000 n=20) Zero/IsZero/SmallStructArray/size=64-4 8.636n ± 0% 3.127n ± 0% -63.79% (p=0.000 n=20) Zero/IsZero/SmallStructArray/size=1024-4 80.055n ± 0% 3.126n ± 0% -96.10% (p=0.000 n=20) Zero/IsZero/Time/size=24-4 3.865n ± 0% 3.274n ± 0% -15.29% (p=0.000 n=20) geomean 6.587n 3.181n -51.71% Note these are of course micro benchmarks with easily predicted branches. The extra branch we introduce in the CL might hurt if there was for example a tight loop where 50% of the values used the global zeroVal and 50% didn't in a way that is not well predicted, although if the typ.Equal for many types already does an initial pointer check, it might not matter much. For the older BenchmarkIsZero in reflect, this change does not help. (The compiler does not use the global zeroVal as the data word for the interfaces in this benchmark because values are part of a larger value that is too big to be used in the global zeroVal, and also a piece of the larger value is mutated and is not zero). │ find-zeroVal │ check-zeroVal │ │ sec/op │ sec/op vs base │ IsZero/ArrayComparable-4 14.58n ± 0% 14.59n ± 0% ~ (p=0.177 n=20) IsZero/ArrayIncomparable-4 163.8n ± 0% 167.5n ± 0% +2.26% (p=0.000 n=20) IsZero/StructComparable-4 6.847n ± 0% 6.847n ± 0% ~ (p=0.703 n=20) IsZero/StructIncomparable-4 35.41n ± 0% 35.10n ± 0% -0.86% (p=0.000 n=20) IsZero/ArrayInt_4-4 8.631n ± 0% 8.363n ± 0% -3.10% (p=0.000 n=20) IsZero/ArrayInt_1024-4 265.5n ± 0% 265.4n ± 0% ~ (p=0.288 n=20) IsZero/ArrayInt_1024_NoZero-4 135.8n ± 0% 136.2n ± 0% +0.33% (p=0.000 n=20) IsZero/Struct4Int-4 8.451n ± 0% 8.386n ± 0% -0.77% (p=0.000 n=20) IsZero/ArrayStruct4Int_1024-4 265.2n ± 0% 266.0n ± 0% +0.30% (p=0.000 n=20) IsZero/ArrayChanInt_1024-4 265.5n ± 0% 265.4n ± 0% ~ (p=0.605 n=20) IsZero/StructInt_512-4 135.8n ± 0% 135.8n ± 0% ~ (p=0.396 n=20) geomean 55.22n 55.12n -0.18% Updates #71323 Change-Id: Ie083853a5bff03856277a293d94532a681f4a8d5 Reviewed-on: https://go-review.googlesource.com/c/go/+/654135 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org>
2025-05-20reflect: add TypeAssert[T]Mateusz Poliwczak
This implementation is zero-alloc when T is a concrete type, allocates when val contains a method or when T is a interface and Value was obtained for example through Elem(), in which case it has to be allocated to avoid sharing the same memory. goos: linux goarch: amd64 pkg: reflect cpu: AMD Ryzen 5 4600G with Radeon Graphics │ /tmp/bench2 │ │ sec/op │ TypeAssert/TypeAssert[int](int)-12 2.725n ± 1% TypeAssert/TypeAssert[uint8](int)-12 2.599n ± 1% TypeAssert/TypeAssert[fmt.Stringer](reflect_test.testTypeWithMethod)-12 8.470n ± 0% TypeAssert/TypeAssert[fmt.Stringer](*reflect_test.testTypeWithMethod)-12 8.460n ± 1% TypeAssert/TypeAssert[interface_{}](int)-12 4.181n ± 1% TypeAssert/TypeAssert[interface_{}](reflect_test.testTypeWithMethod)-12 4.178n ± 1% TypeAssert/TypeAssert[time.Time](time.Time)-12 2.839n ± 0% TypeAssert/TypeAssert[func()_string](func()_string)-12 151.1n ± 1% geomean 6.645n │ /tmp/bench2 │ │ B/op │ TypeAssert/TypeAssert[int](int)-12 0.000 ± 0% TypeAssert/TypeAssert[uint8](int)-12 0.000 ± 0% TypeAssert/TypeAssert[fmt.Stringer](reflect_test.testTypeWithMethod)-12 0.000 ± 0% TypeAssert/TypeAssert[fmt.Stringer](*reflect_test.testTypeWithMethod)-12 0.000 ± 0% TypeAssert/TypeAssert[interface_{}](int)-12 0.000 ± 0% TypeAssert/TypeAssert[interface_{}](reflect_test.testTypeWithMethod)-12 0.000 ± 0% TypeAssert/TypeAssert[time.Time](time.Time)-12 0.000 ± 0% TypeAssert/TypeAssert[func()_string](func()_string)-12 72.00 ± 0% geomean ¹ Fixes #62121 Change-Id: I0911c70c5966672c930d387438643f94a40441c4 GitHub-Last-Rev: ce89a53097b53fc59ff3ce3996917f8484ad3967 GitHub-Pull-Request: golang/go#71639 Reviewed-on: https://go-review.googlesource.com/c/go/+/648056 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
2025-03-17reflect: document Method(ByName) w.r.t dead code eliminationIlya Priven
The behavior is described in src/cmd/link/internal/ld/deadcode.go but is not otherwise documented. Since the usage of those functions could have significant caveats (longer builds, larger binaries), we are informing the user. Change-Id: I87571dd14aa16d7aac59fe45dfc52cb7c5b956c1 Reviewed-on: https://go-review.googlesource.com/c/go/+/658255 Auto-Submit: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2025-02-21reflect: correctly handle method values in SeqMichael Anthony Knyszek
Currently method values aren't correctly handled in Seq because we call canRangeFunc on the reciever type, not the method value type, when we're handling a method value. reflect.Value.Type has the logic to obtain the method value type from the Value. This change slightly refactors reflect.Value.Type into a separate function so we can obtain the correct type as an abi.Type and pass it off to canRangeFunc (and canRangeFunc2). Fixes #71874. Change-Id: Ie62dfca2a84b8f2f816bb87ff1ed1a58a7bb8122 Reviewed-on: https://go-review.googlesource.com/c/go/+/651416 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-28runtime: rename mapiterinit and mapiternextMichael Pratt
mapiterinit allows external linkname. These users must allocate their own iter struct for initialization by mapiterinit. Since the type is unexported, they also must define the struct themselves. As a result, they of course define the struct matching the old hiter definition (in map_noswiss.go). The old definition is smaller on 32-bit platforms. On those platforms, mapiternext will clobber memory outside of the caller's allocation. On all platforms, the pointer layout between the old hiter and new maps.Iter does not match. Thus the GC may miss pointers and free reachable objects early, or it may see non-pointers that look like heap pointers and throw due to invalid references to free objects. To avoid these issues, we must keep mapiterinit and mapiternext with the old hiter definition. The most straightforward way to do this is to use mapiterinit and mapiternext as a compatibility layer between the old and new iter types. The first step to that is to move normal map use off of these functions, which is what this CL does. Introduce new mapIterStart and mapIterNext functions that replace the former functions everywhere in the toolchain. These have the same behavior as the old functions. This CL temporarily makes the old functions throw to ensure we don't have hidden dependencies on them. We cannot remove them entirely because GOEXPERIMENT=noswissmap still uses the old names, and internal/goobj requires all builtins to exist regardless of GOEXPERIMENT. The next CL will introduce the compatibility layer. I want to avoid using linkname between runtime and reflect, as that would also allow external linknames. So mapIterStart and mapIterNext are duplicated in reflect, which can be done trivially, as it imports internal/runtime/maps. For #71408. Change-Id: I6a6a636c6d4bd1392618c67ca648d3f061afe669 Reviewed-on: https://go-review.googlesource.com/c/go/+/643898 Auto-Submit: Michael Pratt <mpratt@google.com> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org>
2024-12-11reflect: consistently document when value must be settableIan Lance Taylor
Fixes #70760 Change-Id: Ia00723698b7e502fa2c63f8f1dbe1143af22e0a5 Reviewed-on: https://go-review.googlesource.com/c/go/+/634799 Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Commit-Queue: Ian Lance Taylor <iant@google.com> Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Ian Lance Taylor <iant@golang.org> Auto-Submit: Ian Lance Taylor <iant@google.com>
2024-09-18reflect: remove calling mapiterkey, mapiterelemKyle Xiao
It makes use of the hiter structure which matches runtime.hiter's. This change mainly improves the performance of Next method of MapIter. goos: darwin goarch: arm64 pkg: reflect cpu: Apple M2 │ ./old.txt │ ./new.txt │ │ sec/op │ sec/op vs base │ MapIterNext-8 61.95n ± 0% 54.95n ± 0% -11.28% (p=0.000 n=10) for the change of `test/escape_reflect.go`: removing mapiterkey, mapiterelem would cause leaking MapIter content when calling SetIterKey and SetIterValue, and this may cause map bucket to be allocated on heap instead of stack. Reproduce: ``` { m := map[int]int{1: 2} // escapes to heap after this change it := reflect.ValueOf(m).MapRange() it.Next() var k, v int reflect.ValueOf(&k).Elem().SetIterKey(it) reflect.ValueOf(&v).Elem().SetIterValue(it) println(k, v) } ``` This CL would not introduce abi.NoEscape to fix this. It may need futher optimization and tests on hiter field usage and its escape analysis. Fixes #69416 Change-Id: Ibaa33bcf86228070b4a505b9512680791aa59f04 Reviewed-on: https://go-review.googlesource.com/c/go/+/612616 Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-08-02all: create swissmap experiment and fork filesMichael Pratt
The _swiss.go files are identical to the originals (except build tag). Later CLs will change them. For #54766. Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest-swissmap Change-Id: I9943e2d6f1cfa227ffbf27c9ddc9ce853695d225 Reviewed-on: https://go-review.googlesource.com/c/go/+/580778 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Michael Pratt <mpratt@google.com> Commit-Queue: Michael Pratt <mpratt@google.com> Reviewed-by: Keith Randall <khr@google.com>
2024-07-26cmd/compile, reflect: treat abi.NoEscape as cheap callCuong Manh Le
The abi.NoEscape function is introduced to replace all usages of noescape wrapper in the standard library. However, the last usage in reflect package is still present, because the inlining test failed if abi.NoEscape were used. The reason is that reflect.noescape is treated as a cheap call, while abi.NoEscape is not. By treating abi.NoEscape a cheap call, the last usage of noescape in reflect package can now be removed. Change-Id: I798079780129221a5a26cbcb18c95ee30855b784 Reviewed-on: https://go-review.googlesource.com/c/go/+/601275 Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
2024-05-22all: document legacy //go:linkname for modules with ≥50,000 dependentsRuss Cox
Note that this depends on the revert of CL 581395 to move zeroVal back. For #67401. Change-Id: I507c27c2404ad1348aabf1ffa3740e6b1957495b Reviewed-on: https://go-review.googlesource.com/c/go/+/587217 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Russ Cox <rsc@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2024-05-22runtime: revert "move zeroVal to internal/abi"Russ Cox
This reverts CL 581395, commit 2f5b420fb5984842afab37a9c2e66e6599107483. It breaks a linkname from github.com/ugorji/go/codec. For #67401. A followup CL will document this dependence. Change-Id: I66d6c39c03e769ab829ca4c3f4f61277b93380d3 Reviewed-on: https://go-review.googlesource.com/c/go/+/587216 TryBot-Bypass: Russ Cox <rsc@golang.org> Auto-Submit: Russ Cox <rsc@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2024-05-22all: document legacy //go:linkname for modules with ≥100,000 dependentsRuss Cox
For #67401. Change-Id: I51f5b561ee11eb242e3b1585d591281d0df4fc24 Reviewed-on: https://go-review.googlesource.com/c/go/+/587215 Auto-Submit: Russ Cox <rsc@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-07reflect: remove redundent ifaceIndirapocelipes
Use abi.(*Type).IfaceIndir instead. Change-Id: I31197cbf0edaf53bbb0455fa76d2a4a2ab40b420 GitHub-Last-Rev: 2659b696ef3680e13e22bdf6a63e5d82b7b1ecdf GitHub-Pull-Request: golang/go#67227 Reviewed-on: https://go-review.googlesource.com/c/go/+/583755 Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-03runtime,reflect: move zeroVal to internal/abiqiulaidongfeng
Change-Id: I0e19e4aa2ea47a714e27b8d66c23c449e27861f2 GitHub-Last-Rev: 2d59b9589efcf4ade6cfd7c8feffc46bf9ba912c GitHub-Pull-Request: golang/go#67014 Reviewed-on: https://go-review.googlesource.com/c/go/+/581395 Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Joedian Reid <joedian@google.com>
2024-04-17internal/abi: define EmptyInterface, TypeOf, and NoEscapeMichael Anthony Knyszek
This change defines two commonly-defined functions and a commonly-defined type in internal/abi to try and deduplicate some definitions. This is motivated by a follow-up CL which will want access to TypeOf in yet another package. There still exist duplicate definitions of all three of these things in the runtime, and this CL doesn't try to handle that yet. There are far too many uses in the runtime to handle manually in a way that feels comfortable; automated refactoring will help. For #62483. Change-Id: I02fc64a28f11af618f6071f94d27f45c135fa8ac Reviewed-on: https://go-review.googlesource.com/c/go/+/573955 Auto-Submit: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com>
2024-04-03reflect: add missing String case in Value.UnsafePointer docCuong Manh Le
CL 516596 changes Value.UnsafePointer to handle String case. However, the method's doc comment is not updated to reflect this change. Updates #61308 Change-Id: I84e02fd969ae0244184e1a2f05cac4651cdf7bff Reviewed-on: https://go-review.googlesource.com/c/go/+/575956 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2024-04-02all: add reflect.SliceAt functionCuong Manh Le
Fixes #61308 Change-Id: Ic17d737fda055a60779985d5da497745c80d5cfa Reviewed-on: https://go-review.googlesource.com/c/go/+/516597 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
2024-04-02reflect: handle String kind in Value.{Pointer,UnsafePointer}Cuong Manh Le
Updates #61308 Change-Id: I92d459383c520d137787ce5c8f135d205af74e5d Reviewed-on: https://go-review.googlesource.com/c/go/+/516596 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2024-04-02reflect: add available godoc linkcui fliter
Change-Id: Ib199ce1a781e8e3a66d3dc8bda617e6bc30b290e Reviewed-on: https://go-review.googlesource.com/c/go/+/539578 Auto-Submit: Ian Lance Taylor <iant@google.com> Run-TryBot: shuang cui <imcusg@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: qiulaidongfeng <2645477756@qq.com>
2024-03-04runtime: use .Pointers() instead of manual checkingPouriya
Change-Id: Ib78c1513616089f4942297cd17212b1b11871fd5 GitHub-Last-Rev: f97fe5b5bffffe25dc31de7964588640cb70ec41 GitHub-Pull-Request: golang/go#65819 Reviewed-on: https://go-review.googlesource.com/c/go/+/565515 Reviewed-by: Jorropo <jorropo.pgm@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org>
2024-02-27reflect: fix typo in commentguoguangwu
Change-Id: Ia8e666b128622391d72e42449c01c4e10f3c9e1e GitHub-Last-Rev: c74cf13b70772a965a14630108544a89690d1383 GitHub-Pull-Request: golang/go#65938 Reviewed-on: https://go-review.googlesource.com/c/go/+/566855 Reviewed-by: Carlos Amedee <carlos@golang.org> Reviewed-by: qiulaidongfeng <2645477756@qq.com> Auto-Submit: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2024-02-17reflect: make Value.Comparable return true for nil interface valueJes Cok
Fixes #65718 Change-Id: I0b3edf9085f2d71f915bdf8ff9d312509b438c5f GitHub-Last-Rev: 9fb1ca1a631c648d1f38f75b1fcb2f878048706b GitHub-Pull-Request: golang/go#65750 Reviewed-on: https://go-review.googlesource.com/c/go/+/564795 Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Commit-Queue: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-02-16reflect: use internal/abi itab typeKeith Randall
Change-Id: I4a40d9cda41d3601169ef0daf0f25fb1509bdcb7 Reviewed-on: https://go-review.googlesource.com/c/go/+/549458 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: David Chase <drchase@google.com>
2024-01-26reflect: use MapMaxKeyBytes,MapMaxElemBytes,MapBucketCount of internal/abiqiulaidongfeng
For #59670 Change-Id: I63a6e2cfaf9eec03866ea61064164a059fc42bb2 GitHub-Last-Rev: a3aa46a36444b08382ddac79c10a064b314bd971 GitHub-Pull-Request: golang/go#64773 Reviewed-on: https://go-review.googlesource.com/c/go/+/550595 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
2024-01-23reflect: delete TODO pass safe to packEface don't need to copy if safe==trueqiulaidongfeng
valueInterface not copy result in the follow incorrect behavior w1. x := ValueOf(&v).Elem() r1. iface := Value.Interface() w2. x.Set() or x.SetT() The write operation of W2 will be observed by the read operation of r1, but the existing behavior is not. The valueInterface in deepValueEqual can, in theory, pass safe==true to not copy the object, but there is no benchmark to indicate that the memory allocation has changed, maybe we don't actually need safe==true here. Change-Id: I55c423fd50adac8822a7fdbfe67af89ee223eace GitHub-Last-Rev: 4a6386709817f3ea6055711dd39d2694d58b3043 GitHub-Pull-Request: golang/go#64618 Reviewed-on: https://go-review.googlesource.com/c/go/+/548436 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org>
2023-11-22internal/abi, runtime, reflect, cmd: merge maxZero const into internal/abiqiulaidongfeng
For #59670 Change-Id: If38a74ad067a3ea3ff551c0c25c8ef41abec114b GitHub-Last-Rev: fb1f2f3c9f320017627bc3342b061e1e7f6f7fad GitHub-Pull-Request: golang/go#64268 Reviewed-on: https://go-review.googlesource.com/c/go/+/543655 Run-TryBot: qiulaidongfeng <2645477756@qq.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org>
2023-11-21reflect: tweak logic for 'case Array' in IsZeroJes Cok
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 <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com> Run-TryBot: Jes Cok <xigua67damn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-11-19reflect: optimize Value.IsZero for struct typesqiulaidongfeng
For some types where the zero value is a value where all bits of this type are 0 optimize it. goos: windows goarch: amd64 pkg: reflect cpu: AMD Ryzen 7 7840HS w/ Radeon 780M Graphics │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ IsZero/StructInt_512-16 109.75n ± 0% 72.61n ± 1% -33.84% (p=0.000 n=12) Change-Id: I56de8b95f4d4482068960d6f38938763fa1caa90 GitHub-Last-Rev: c143f0cd7616cb3be52c59879f748e49a3c5cbf1 GitHub-Pull-Request: golang/go#64220 Reviewed-on: https://go-review.googlesource.com/c/go/+/543355 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2023-11-16reflect: remove go121noForceValueEscapeCherry Mui
Before Go 1.21, ValueOf always escapes and a Value's content is always heap allocated. In Go 1.21, we made it no longer always escape, guarded by go121noForceValueEscape. This behavior has been released for some time and there is no issue so far. We can remove the guard now. Change-Id: I81f5366412390f6c63b642f4c7c016da534da76a Reviewed-on: https://go-review.googlesource.com/c/go/+/542795 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-11-16runtime: optimize bulkBarrierPreWrite with allocheadersMichael Anthony Knyszek
Currently bulkBarrierPreWrite follows a fairly slow path wherein it calls typePointersOf, which ends up calling into fastForward. This does some fairly heavy computation to move the iterator forward without any assumptions about where it lands at all. It needs to be completely general to support splitting at arbitrary boundaries, for example for scanning oblets. This means that copying objects during the GC mark phase is fairly expensive, and is a regression from before allocheaders. However, in almost all cases bulkBarrierPreWrite and bulkBarrierPreWriteSrcOnly have perfect type information. We can do a lot better in these cases because we're starting on a type-size boundary, which is exactly what the iterator is built around. This change adds the typePointersOfType method which produces a typePointers iterator from a pointer and a type. This change significantly improves the performance of these bulk write barriers, eliminating some performance regressions that were noticed on the perf dashboard. There are still just a couple cases where we have to use the more general typePointersOf calls, but they're fairly rare; most bulk barriers have perfect type information. This change is tested by the GCInfo tests in the runtime and the GCBits tests in the reflect package via an additional check in getgcmask. Results for tile38 before and after allocheaders. There was previous a regression in the p90, now it's gone. Also, the overall win has been boosted slightly. tile38 $ benchstat noallocheaders.results allocheaders.results name old time/op new time/op delta Tile38QueryLoad 481µs ± 1% 468µs ± 1% -2.71% (p=0.000 n=10+10) name old average-RSS-bytes new average-RSS-bytes delta Tile38QueryLoad 6.32GB ± 1% 6.23GB ± 0% -1.38% (p=0.000 n=9+8) name old peak-RSS-bytes new peak-RSS-bytes delta Tile38QueryLoad 6.49GB ± 1% 6.40GB ± 1% -1.38% (p=0.002 n=10+10) name old peak-VM-bytes new peak-VM-bytes delta Tile38QueryLoad 7.72GB ± 1% 7.64GB ± 1% -1.07% (p=0.007 n=10+10) name old p50-latency-ns new p50-latency-ns delta Tile38QueryLoad 212k ± 1% 205k ± 0% -3.02% (p=0.000 n=10+9) name old p90-latency-ns new p90-latency-ns delta Tile38QueryLoad 622k ± 1% 616k ± 1% -1.03% (p=0.005 n=10+10) name old p99-latency-ns new p99-latency-ns delta Tile38QueryLoad 4.55M ± 2% 4.39M ± 2% -3.51% (p=0.000 n=10+10) name old ops/s new ops/s delta Tile38QueryLoad 12.5k ± 1% 12.8k ± 1% +2.78% (p=0.000 n=10+10) Change-Id: I0a48f848eae8777d0fd6769c3a1fe449f8d9d0a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/542219 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-11-15reflect: optimize Value.IsZero for array typesqiulaidongfeng
For some types where the zero value is a value where all bits of this type are 0 optimize it goos: windows goarch: amd64 pkg: reflect cpu: AMD Ryzen 7 7840HS w/ Radeon 780M Graphics │ std.txt │ new.txt │ │ sec/op │ sec/op vs base │ IsZero/ArrayComparable-16 8.483n ± 0% 8.470n ± 2% ~ (p=0.542 n=10) IsZero/ArrayIncomparable-16 88.13n ± 1% 87.34n ± 2% ~ (p=0.110 n=10) IsZero/StructComparable-16 4.050n ± 2% 4.011n ± 1% ~ (p=0.093 n=10) IsZero/StructIncomparable-16 19.93n ± 1% 19.81n ± 1% ~ (p=0.493 n=10) IsZero/ArrayInt_4-16 4.445n ± 2% 4.478n ± 2% ~ (p=0.306 n=10) IsZero/ArrayInt_1024-16 3381.5n ± 3% 140.8n ± 1% -95.84% (p=0.000 n=10) IsZero/ArrayInt_1024_NoZero-16 1760.50n ± 3% 72.17n ± 1% -95.90% (p=0.000 n=10) IsZero/Struct4Int-16 4.495n ± 3% 4.478n ± 1% ~ (p=0.579 n=10) IsZero/ArrayStruct4Int_1024-16 1404.0n ± 3% 140.5n ± 0% -90.00% (p=0.000 n=10) IsZero/ArrayChanInt_1024-16 3437.0n ± 6% 140.5n ± 1% -95.91% (p=0.000 n=10) geomean 89.94n 27.38n -69.56% Change-Id: I835231a79b9cd89686d44c5b8c2fbe629ccd98ba GitHub-Last-Rev: 3abe118a108faf0070b56ba9098871746daa1ac1 GitHub-Pull-Request: golang/go#63661 Reviewed-on: https://go-review.googlesource.com/c/go/+/536855 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
2023-09-01reflect: make Value.IsZero identical to v == zeroJoe Tsai
The upcoming built-in zero value provides an idiomatic way to test for zero by comparing to the zero literal: v == zero. The reflect package is meant to provide a programmatic way to perform operations that the Go language itself provides. Thus, it seems prudent that reflect.ValueOf(&v).Elem().IsZero() is identical to v == zero. This change alters the behavior of Value.IsZero in two concrete ways: * negative zero is identical to zero * blank fields in a struct are ignored Prior to this change, we were already in an inconsistent state due to a regression introduced by CL 411478. The new behavior was already the case for comparable composite types. This change makes it consistent for all other types (in particular incomparable composite types and standalone numbers). Updates #61372 Fixes #61827 Change-Id: Id23fb97eb3b8921417cc75a1d3ead963e22dc3d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/517777 Reviewed-by: Russ Cox <rsc@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-08-01reflect: make linkable cross-references in documentationKeith Randall
This makes it easier to click around in documentation on pkg.go.dev. Change-Id: Idc67c312bc72c612e660607e5400b43ecc110bc1 Reviewed-on: https://go-review.googlesource.com/c/go/+/514895 Run-TryBot: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-07-21reflect: panic on recv channel closeMauri de Souza Meneguzzo
It is possible to call reflect.ValueOf(ch).Close() on a recv-only channel, while close(ch) is a compile-time error. Following the same reflect semantics as send and recv this should result in a panic. Fixes #61445 Change-Id: I2a9ee8f45963593a37bd6df4643dd64fb322f9f9 GitHub-Last-Rev: fe2d5e09f5bb5536ac25d1606cf3744fb7a0a4a9 GitHub-Pull-Request: golang/go#61453 Reviewed-on: https://go-review.googlesource.com/c/go/+/511295 Auto-Submit: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Ian Lance Taylor <iant@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-05-12reflect: make Value.IsZero not escapeCherry Mui
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 <drchase@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>