aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2023-06-28 12:03:22 +0700
committerGopher Robot <gobot@golang.org>2023-08-16 21:01:11 +0000
commit14a3ffc3d2165ef03c3ffd0037a4fa6dbb776026 (patch)
tree0595c8a1ab8d181ef31fa9e79309a25fab0e9733 /src
parent5fa4aac0cec637fd9415fb260e3fbc2975377e00 (diff)
downloadgo-14a3ffc3d2165ef03c3ffd0037a4fa6dbb776026.tar.xz
cmd/compile: use types2.Sizes instead of compiler own implementation
With #61035 fixed, types2.Sizes matches the compiler behavior, so use its Sizes implementation instead of rolling our own copy. Updates #61035 Change-Id: I7b9efd27a01f729a04c79cd6b4ee5f417fe6e664 Reviewed-on: https://go-review.googlesource.com/c/go/+/506716 TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/noder/irgen.go3
-rw-r--r--src/cmd/compile/internal/noder/sizes.go185
2 files changed, 2 insertions, 186 deletions
diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go
index 6019c5986c..f7b6d191fb 100644
--- a/src/cmd/compile/internal/noder/irgen.go
+++ b/src/cmd/compile/internal/noder/irgen.go
@@ -6,6 +6,7 @@ package noder
import (
"fmt"
+ "internal/buildcfg"
"internal/types/errors"
"regexp"
"sort"
@@ -51,7 +52,7 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) {
base.ErrorfAt(m.makeXPos(terr.Pos), terr.Code, "%s", msg)
},
Importer: &importer,
- Sizes: &gcSizes{},
+ Sizes: types2.SizesFor("gc", buildcfg.GOARCH),
}
if base.Flag.ErrorURL {
conf.ErrorURL = " [go.dev/e/%s]"
diff --git a/src/cmd/compile/internal/noder/sizes.go b/src/cmd/compile/internal/noder/sizes.go
deleted file mode 100644
index dff8d7bb9a..0000000000
--- a/src/cmd/compile/internal/noder/sizes.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2021 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 noder
-
-import (
- "fmt"
-
- "cmd/compile/internal/types"
- "cmd/compile/internal/types2"
-)
-
-// Code below based on go/types.StdSizes.
-// Intentional differences are marked with "gc:".
-
-type gcSizes struct{}
-
-func (s *gcSizes) Alignof(T types2.Type) int64 {
- // For arrays and structs, alignment is defined in terms
- // of alignment of the elements and fields, respectively.
- switch t := T.Underlying().(type) {
- case *types2.Array:
- // spec: "For a variable x of array type: unsafe.Alignof(x)
- // is the same as unsafe.Alignof(x[0]), but at least 1."
- return s.Alignof(t.Elem())
- case *types2.Struct:
- if t.NumFields() == 0 && types2.IsSyncAtomicAlign64(T) {
- // Special case: sync/atomic.align64 is an
- // empty struct we recognize as a signal that
- // the struct it contains must be
- // 64-bit-aligned.
- //
- // This logic is equivalent to the logic in
- // cmd/compile/internal/types/size.go:calcStructOffset
- return 8
- }
-
- // spec: "For a variable x of struct type: unsafe.Alignof(x)
- // is the largest of the values unsafe.Alignof(x.f) for each
- // field f of x, but at least 1."
- max := int64(1)
- for i, nf := 0, t.NumFields(); i < nf; i++ {
- if a := s.Alignof(t.Field(i).Type()); a > max {
- max = a
- }
- }
- return max
- case *types2.Slice, *types2.Interface:
- // Multiword data structures are effectively structs
- // in which each element has size PtrSize.
- return int64(types.PtrSize)
- case *types2.Basic:
- // Strings are like slices and interfaces.
- if t.Info()&types2.IsString != 0 {
- return int64(types.PtrSize)
- }
- }
- a := s.Sizeof(T) // may be 0
- // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
- if a < 1 {
- return 1
- }
- // complex{64,128} are aligned like [2]float{32,64}.
- if isComplex(T) {
- a /= 2
- }
- if a > int64(types.RegSize) {
- return int64(types.RegSize)
- }
- return a
-}
-
-func isComplex(T types2.Type) bool {
- basic, ok := T.Underlying().(*types2.Basic)
- return ok && basic.Info()&types2.IsComplex != 0
-}
-
-func (s *gcSizes) Offsetsof(fields []*types2.Var) []int64 {
- offsets := make([]int64, len(fields))
- var offs int64
- for i, f := range fields {
- if offs < 0 {
- // all remaining offsets are too large
- offsets[i] = -1
- continue
- }
- // offs >= 0
- typ := f.Type()
- a := s.Alignof(typ)
- offs = types.RoundUp(offs, a) // possibly < 0 if align overflows
- offsets[i] = offs
- if d := s.Sizeof(typ); d >= 0 && offs >= 0 {
- offs += d // ok to overflow to < 0
- } else {
- offs = -1
- }
- }
- return offsets
-}
-
-func (s *gcSizes) Sizeof(T types2.Type) int64 {
- switch t := T.Underlying().(type) {
- case *types2.Basic:
- k := t.Kind()
- if int(k) < len(basicSizes) {
- if s := basicSizes[k]; s > 0 {
- return int64(s)
- }
- }
- switch k {
- case types2.String:
- return int64(types.PtrSize) * 2
- case types2.Int, types2.Uint, types2.Uintptr, types2.UnsafePointer:
- return int64(types.PtrSize)
- }
- panic(fmt.Sprintf("unimplemented basic: %v (kind %v)", T, k))
- case *types2.Array:
- n := t.Len()
- if n <= 0 {
- return 0
- }
- // n > 0
- // gc: Size includes alignment padding.
- esize := s.Sizeof(t.Elem())
- if esize < 0 {
- return -1 // array element too large
- }
- if esize == 0 {
- return 0 // 0-size element
- }
- // esize > 0
- // Final size is esize * n; and size must be <= maxInt64.
- const maxInt64 = 1<<63 - 1
- if esize > maxInt64/n {
- return -1 // esize * n overflows
- }
- return esize * n
- case *types2.Slice:
- return int64(types.PtrSize) * 3
- case *types2.Struct:
- n := t.NumFields()
- if n == 0 {
- return 0
- }
- fields := make([]*types2.Var, n)
- for i := range fields {
- fields[i] = t.Field(i)
- }
- offsets := s.Offsetsof(fields)
-
- // gc: The last field of a non-zero-sized struct is not allowed to
- // have size 0.
- last := s.Sizeof(fields[n-1].Type())
- if last == 0 && offsets[n-1] > 0 {
- last = 1
- }
-
- // gc: Size includes alignment padding.
- return types.RoundUp(offsets[n-1]+last, s.Alignof(t)) // may overflow to < 0 which is ok
- case *types2.Interface:
- return int64(types.PtrSize) * 2
- case *types2.Chan, *types2.Map, *types2.Pointer, *types2.Signature:
- return int64(types.PtrSize)
- default:
- panic(fmt.Sprintf("unimplemented type: %T", t))
- }
-}
-
-var basicSizes = [...]byte{
- types2.Invalid: 1,
- types2.Bool: 1,
- types2.Int8: 1,
- types2.Int16: 2,
- types2.Int32: 4,
- types2.Int64: 8,
- types2.Uint8: 1,
- types2.Uint16: 2,
- types2.Uint32: 4,
- types2.Uint64: 8,
- types2.Float32: 4,
- types2.Float64: 8,
- types2.Complex64: 8,
- types2.Complex128: 16,
-}