mirror of
https://github.com/golang/go
synced 2024-10-04 15:09:59 +00:00
cmd/compile: add structs.HostLayout
This is for the proposal, plus a few bug fixes that would/will be necessary when this is put into actual use. Fixes #66408. Updates #63131. Change-Id: I3a66e09d707dd579c59f155e7f53367f41214c30 Reviewed-on: https://go-review.googlesource.com/c/go/+/578355 Reviewed-by: Austin Clements <austin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: David Chase <drchase@google.com>
This commit is contained in:
parent
ecad164da7
commit
22344e11f2
1
api/next/66408.txt
Normal file
1
api/next/66408.txt
Normal file
|
@ -0,0 +1 @@
|
|||
pkg structs, type HostLayout struct #66408
|
12
doc/next/6-stdlib/3-structs.md
Normal file
12
doc/next/6-stdlib/3-structs.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
### New structs package
|
||||
|
||||
|
||||
The new [structs](/pkg/structs) package provides
|
||||
types for struct fields that modify properties of
|
||||
the containing struct type such as memory layout.
|
||||
|
||||
In this release, the only such type is
|
||||
[`HostLayout`](/pkg/structs#HostLayout)
|
||||
which indicates that a structure with a field of that
|
||||
type has a layout that conforms to host platform
|
||||
expectations.
|
1
doc/next/6-stdlib/99-minor/structs/66408.md
Normal file
1
doc/next/6-stdlib/99-minor/structs/66408.md
Normal file
|
@ -0,0 +1 @@
|
|||
<!-- This is a new package; covered in 6-stdlib/3-structs.md. -->
|
|
@ -141,7 +141,7 @@ func (pa *ABIParamAssignment) RegisterTypesAndOffsets() ([]*types.Type, []int64)
|
|||
}
|
||||
typs := make([]*types.Type, 0, l)
|
||||
offs := make([]int64, 0, l)
|
||||
offs, _ = appendParamOffsets(offs, 0, pa.Type)
|
||||
offs, _ = appendParamOffsets(offs, 0, pa.Type) // 0 is aligned for everything.
|
||||
return appendParamTypes(typs, pa.Type), offs
|
||||
}
|
||||
|
||||
|
@ -193,8 +193,8 @@ func appendParamTypes(rts []*types.Type, t *types.Type) []*types.Type {
|
|||
|
||||
// appendParamOffsets appends the offset(s) of type t, starting from "at",
|
||||
// to input offsets, and returns the longer slice and the next unused offset.
|
||||
// at should already be aligned for t.
|
||||
func appendParamOffsets(offsets []int64, at int64, t *types.Type) ([]int64, int64) {
|
||||
at = align(at, t)
|
||||
w := t.Size()
|
||||
if w == 0 {
|
||||
return offsets, at
|
||||
|
@ -210,11 +210,15 @@ func appendParamOffsets(offsets []int64, at int64, t *types.Type) ([]int64, int6
|
|||
typ := t.Kind()
|
||||
switch typ {
|
||||
case types.TARRAY:
|
||||
te := t.Elem()
|
||||
for i := int64(0); i < t.NumElem(); i++ {
|
||||
offsets, at = appendParamOffsets(offsets, at, t.Elem())
|
||||
at = align(at, te)
|
||||
offsets, at = appendParamOffsets(offsets, at, te)
|
||||
}
|
||||
case types.TSTRUCT:
|
||||
at0 := at
|
||||
for i, f := range t.Fields() {
|
||||
at = at0 + f.Offset // Fields may be over-aligned, see wasm32.
|
||||
offsets, at = appendParamOffsets(offsets, at, f.Type)
|
||||
if f.Type.Size() == 0 && i == t.NumFields()-1 {
|
||||
at++ // last field has zero width
|
||||
|
@ -668,12 +672,13 @@ func (pa *ABIParamAssignment) ComputePadding(storage []uint64) []uint64 {
|
|||
if len(types) != nr {
|
||||
panic("internal error")
|
||||
}
|
||||
offsets, _ := appendParamOffsets([]int64{}, 0, pa.Type)
|
||||
off := int64(0)
|
||||
for idx, t := range types {
|
||||
ts := t.Size()
|
||||
off += int64(ts)
|
||||
if idx < len(types)-1 {
|
||||
noff := align(off, types[idx+1])
|
||||
noff := offsets[idx+1]
|
||||
if noff != off {
|
||||
padding[idx] = uint64(noff - off)
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ func init() {
|
|||
types.PtrSize = 8
|
||||
types.RegSize = 8
|
||||
types.MaxWidth = 1 << 50
|
||||
typecheck.InitUniverse()
|
||||
base.Ctxt = &obj.Link{Arch: &obj.LinkArch{Arch: &sys.Arch{Alignment: 1, CanMergeLoads: true}}}
|
||||
typecheck.InitUniverse()
|
||||
}
|
||||
|
||||
func TestEqStructCost(t *testing.T) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"cmd/internal/obj"
|
||||
"cmd/internal/pgo"
|
||||
"cmd/internal/src"
|
||||
"cmd/internal/sys"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -23,8 +24,8 @@ func init() {
|
|||
types.PtrSize = 8
|
||||
types.RegSize = 8
|
||||
types.MaxWidth = 1 << 50
|
||||
base.Ctxt = &obj.Link{Arch: &obj.LinkArch{Arch: &sys.Arch{Alignment: 1, CanMergeLoads: true}}}
|
||||
typecheck.InitUniverse()
|
||||
base.Ctxt = &obj.Link{}
|
||||
base.Debug.PGODebug = 3
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
package inlheur
|
||||
|
||||
import (
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/ir"
|
||||
"cmd/compile/internal/typecheck"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/src"
|
||||
"cmd/internal/sys"
|
||||
"go/constant"
|
||||
"testing"
|
||||
)
|
||||
|
@ -21,6 +24,8 @@ func init() {
|
|||
types.PtrSize = 8
|
||||
types.RegSize = 8
|
||||
types.MaxWidth = 1 << 50
|
||||
base.Ctxt = &obj.Link{Arch: &obj.LinkArch{Arch: &sys.Arch{Alignment: 1, CanMergeLoads: true}}}
|
||||
|
||||
typecheck.InitUniverse()
|
||||
local = types.NewPkg("", "")
|
||||
fsym := &types.Sym{
|
||||
|
|
|
@ -7,6 +7,7 @@ package ssa
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/ir"
|
||||
"cmd/compile/internal/typecheck"
|
||||
"cmd/compile/internal/types"
|
||||
|
@ -15,6 +16,7 @@ import (
|
|||
"cmd/internal/obj/s390x"
|
||||
"cmd/internal/obj/x86"
|
||||
"cmd/internal/src"
|
||||
"cmd/internal/sys"
|
||||
)
|
||||
|
||||
var CheckFunc = checkFunc
|
||||
|
@ -115,6 +117,7 @@ func init() {
|
|||
types.RegSize = 8
|
||||
types.MaxWidth = 1 << 50
|
||||
|
||||
base.Ctxt = &obj.Link{Arch: &obj.LinkArch{Arch: &sys.Arch{Alignment: 1, CanMergeLoads: true}}}
|
||||
typecheck.InitUniverse()
|
||||
testTypes.SetTypPtrs()
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ var stdPkgs = []string{
|
|||
"sort",
|
||||
"strconv",
|
||||
"strings",
|
||||
"structs",
|
||||
"sync",
|
||||
"syscall",
|
||||
"testing",
|
||||
|
|
10
src/structs/doc.go
Normal file
10
src/structs/doc.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2024 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 structs defines marker types that can be used as struct fields
|
||||
// to modify the properties of a struct.
|
||||
//
|
||||
// By convention, a marker type should be used as the type of a field
|
||||
// named "_", placed at the beginning of a struct type definition.
|
||||
package structs
|
30
src/structs/hostlayout.go
Normal file
30
src/structs/hostlayout.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2024 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 structs
|
||||
|
||||
// HostLayout marks a struct as using host memory layout. A struct with a
|
||||
// field of type HostLayout will be laid out in memory according to host
|
||||
// expectations, generally following the host's C ABI.
|
||||
//
|
||||
// HostLayout does not affect layout within any other struct-typed fields
|
||||
// of the containing struct, nor does it affect layout of structs
|
||||
// containing the struct marked as host layout.
|
||||
//
|
||||
// By convention, HostLayout should be used as the type of a field
|
||||
// named "_", placed at the beginning of the struct type definition.
|
||||
type HostLayout struct {
|
||||
_ hostLayout // prevent accidental conversion with plain struct{}
|
||||
}
|
||||
|
||||
// We use an unexported type within the exported type to give the marker
|
||||
// type itself, rather than merely its name, a recognizable identity in
|
||||
// the type system. The main consequence of this is that a user can give
|
||||
// the type a new name and it will still have the same properties, e.g.,
|
||||
//
|
||||
// type HL structs.HostLayout
|
||||
//
|
||||
// It also prevents unintentional conversion of struct{} to a named marker type.
|
||||
type hostLayout struct {
|
||||
}
|
Loading…
Reference in a new issue