mirror of
https://github.com/golang/go.git
synced 2025-11-01 17:20:56 +00:00
The signature of the mapassign_fast* routines need to distinguish
the pointerness of their key argument. If the affected routines
suspend part way through, the object pointed to by the key might
get garbage collected because the key is typed as a uint{32,64}.
This is not a problem for mapaccess or mapdelete because the key
in those situations do not live beyond the call involved. If the
object referenced by the key is garbage collected prematurely, the
code still works fine. Even if that object is subsequently reallocated,
it can't be written to the map in time to affect the lookup/delete.
Fixes #22781
Change-Id: I0bbbc5e9883d5ce702faf4e655348be1191ee439
Reviewed-on: https://go-review.googlesource.com/79018
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Martin Möhrmann <moehrmann@google.com>
29 lines
680 B
Go
29 lines
680 B
Go
// run
|
|
|
|
// Copyright 2017 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
import "runtime/debug"
|
|
|
|
type T struct {
|
|
// >= 16 bytes to avoid tiny alloc.
|
|
a, b int
|
|
}
|
|
|
|
func main() {
|
|
debug.SetGCPercent(1)
|
|
for i := 0; i < 100000; i++ {
|
|
m := make(map[*T]struct{}, 0)
|
|
for j := 0; j < 20; j++ {
|
|
// During the call to mapassign_fast64, the key argument
|
|
// was incorrectly treated as a uint64. If the stack was
|
|
// scanned during that call, the only pointer to k was
|
|
// missed, leading to *k being collected prematurely.
|
|
k := new(T)
|
|
m[k] = struct{}{}
|
|
}
|
|
}
|
|
}
|