Skip to content

Commit ac40c98

Browse files
committed
reflect: fix _faststr optimization
CL 345486 introduced an optimization to reflect's map accesses which is not quite correct. We can't use the optimized code if the value type is >128 bytes. See cmd/compile/internal/walk/walk.go:mapfast Fixes #48357 Change-Id: I8e3c7858693083dd4393a8de48ca5fa47bab66f2 Reviewed-on: https://go-review.googlesource.com/c/go/+/349593 Trust: Keith Randall <[email protected]> Trust: Joe Tsai <[email protected]> Trust: Josh Bleecher Snyder <[email protected]> Trust: Martin Möhrmann <[email protected]> Run-TryBot: Keith Randall <[email protected]> Run-TryBot: Joe Tsai <[email protected]> Reviewed-by: Joe Tsai <[email protected]> Reviewed-by: Josh Bleecher Snyder <[email protected]> Reviewed-by: Martin Möhrmann <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent c8a58f2 commit ac40c98

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/reflect/value.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ func (v Value) MapIndex(key Value) Value {
15171517
// of unexported fields.
15181518

15191519
var e unsafe.Pointer
1520-
if key.kind() == String && tt.key.Kind() == String {
1520+
if key.kind() == String && tt.key.Kind() == String && tt.elem.size <= maxValSize {
15211521
k := *(*string)(key.ptr)
15221522
e = mapaccess_faststr(v.typ, v.pointer(), k)
15231523
} else {
@@ -2128,7 +2128,7 @@ func (v Value) SetMapIndex(key, elem Value) {
21282128
key.mustBeExported()
21292129
tt := (*mapType)(unsafe.Pointer(v.typ))
21302130

2131-
if key.kind() == String && tt.key.Kind() == String {
2131+
if key.kind() == String && tt.key.Kind() == String && tt.elem.size <= maxValSize {
21322132
k := *(*string)(key.ptr)
21332133
if elem.typ == nil {
21342134
mapdelete_faststr(v.typ, v.pointer(), k)

test/fixedbugs/issue48357.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run
2+
3+
// Copyright 2021 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
import "reflect"
10+
11+
type T [129]byte
12+
13+
func main() {
14+
m := map[string]T{}
15+
v := reflect.ValueOf(m)
16+
v.SetMapIndex(reflect.ValueOf("a"), reflect.ValueOf(T{}))
17+
g = m["a"]
18+
}
19+
20+
var g T

0 commit comments

Comments
 (0)