diff options
| author | Michael Pratt <mpratt@google.com> | 2024-05-03 13:03:04 -0400 |
|---|---|---|
| committer | Michael Pratt <mpratt@google.com> | 2024-10-14 19:58:47 +0000 |
| commit | c39bc22c141bc6990e4e2abf604dcf56669ff779 (patch) | |
| tree | 5384243aaaa9d9f9796674223cf186ee3ceb63a9 /src/cmd/compile/internal/walk | |
| parent | 48849e0866f64a40d04a9151e44e5a73acdfc17b (diff) | |
| download | go-c39bc22c141bc6990e4e2abf604dcf56669ff779.tar.xz | |
all: wire up swisstable maps
Use the new SwissTable-based map in internal/runtime/maps as the basis
for the runtime map when GOEXPERIMENT=swissmap.
Integration is complete enough to pass all.bash. Notable missing
features:
* Race integration / concurrent write detection
* Stack-allocated maps
* Specialized "fast" map variants
* Indirect key / elem
For #54766.
Cq-Include-Trybots: luci.golang.try:gotip-linux-ppc64_power10,gotip-linux-amd64-longtest-swissmap
Change-Id: Ie97b656b6d8e05c0403311ae08fef9f51756a639
Reviewed-on: https://go-review.googlesource.com/c/go/+/594596
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/compile/internal/walk')
| -rw-r--r-- | src/cmd/compile/internal/walk/builtin.go | 60 | ||||
| -rw-r--r-- | src/cmd/compile/internal/walk/range.go | 11 |
2 files changed, 12 insertions, 59 deletions
diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go index 19ec8d30fa..51c5e0b94b 100644 --- a/src/cmd/compile/internal/walk/builtin.go +++ b/src/cmd/compile/internal/walk/builtin.go @@ -1,4 +1,4 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2009 The Go Authors. All rights reserved.walk/bui // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -332,62 +332,8 @@ func walkMakeSwissMap(n *ir.MakeExpr, init *ir.Nodes) ir.Node { // h = &hv h = stackTempAddr(init, hmapType) - // Allocate one bucket pointed to by hmap.buckets on stack if hint - // is not larger than BUCKETSIZE. In case hint is larger than - // BUCKETSIZE runtime.makemap will allocate the buckets on the heap. - // Maximum key and elem size is 128 bytes, larger objects - // are stored with an indirection. So max bucket size is 2048+eps. - if !ir.IsConst(hint, constant.Int) || - constant.Compare(hint.Val(), token.LEQ, constant.MakeInt64(abi.SwissMapBucketCount)) { - - // In case hint is larger than BUCKETSIZE runtime.makemap - // will allocate the buckets on the heap, see #20184 - // - // if hint <= BUCKETSIZE { - // var bv bmap - // b = &bv - // h.buckets = b - // } - - nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, hint, ir.NewInt(base.Pos, abi.SwissMapBucketCount)), nil, nil) - nif.Likely = true - - // var bv bmap - // b = &bv - b := stackTempAddr(&nif.Body, reflectdata.SwissMapBucketType(t)) - - // h.buckets = b - bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap - na := ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, h, bsym), typecheck.ConvNop(b, types.Types[types.TUNSAFEPTR])) - nif.Body.Append(na) - appendWalkStmt(init, nif) - } - } - - if ir.IsConst(hint, constant.Int) && constant.Compare(hint.Val(), token.LEQ, constant.MakeInt64(abi.SwissMapBucketCount)) { - // Handling make(map[any]any) and - // make(map[any]any, hint) where hint <= BUCKETSIZE - // special allows for faster map initialization and - // improves binary size by using calls with fewer arguments. - // For hint <= BUCKETSIZE overLoadFactor(hint, 0) is false - // and no buckets will be allocated by makemap. Therefore, - // no buckets need to be allocated in this code path. - if n.Esc() == ir.EscNone { - // Only need to initialize h.hash0 since - // hmap h has been allocated on the stack already. - // h.hash0 = rand32() - rand := mkcall("rand32", types.Types[types.TUINT32], init) - hashsym := hmapType.Field(4).Sym // hmap.hash0 see reflect.go:hmap - appendWalkStmt(init, ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, h, hashsym), rand)) - return typecheck.ConvNop(h, t) - } - // Call runtime.makehmap to allocate an - // hmap on the heap and initialize hmap's hash0 field. - fn := typecheck.LookupRuntime("makemap_small", t.Key(), t.Elem()) - return mkcall1(fn, n.Type(), init) - } - - if n.Esc() != ir.EscNone { + // TODO(go.dev/issue/54766): Stack allocated table/groups. + } else { h = typecheck.NodNil() } // Map initialization with a variable or large hint is diff --git a/src/cmd/compile/internal/walk/range.go b/src/cmd/compile/internal/walk/range.go index 93898b3a66..27e71425c1 100644 --- a/src/cmd/compile/internal/walk/range.go +++ b/src/cmd/compile/internal/walk/range.go @@ -5,6 +5,7 @@ package walk import ( + "internal/buildcfg" "unicode/utf8" "cmd/compile/internal/base" @@ -242,8 +243,14 @@ func walkRange(nrange *ir.RangeStmt) ir.Node { th := hit.Type() // depends on layout of iterator struct. // See cmd/compile/internal/reflectdata/reflect.go:MapIterType - keysym := th.Field(0).Sym - elemsym := th.Field(1).Sym // ditto + var keysym, elemsym *types.Sym + if buildcfg.Experiment.SwissMap { + keysym = th.Field(0).Sym + elemsym = th.Field(1).Sym // ditto + } else { + keysym = th.Field(0).Sym + elemsym = th.Field(1).Sym // ditto + } fn := typecheck.LookupRuntime("mapiterinit", t.Key(), t.Elem(), th) init = append(init, mkcallstmt1(fn, reflectdata.RangeMapRType(base.Pos, nrange), ha, typecheck.NodAddr(hit))) |
