[go] internal/abi, runtime: put type descriptor sizes in internal/abi

2 views
Skip to first unread message

Ian Lance Taylor (Gerrit)

unread,
12:14 AM (4 hours ago) 12:14 AM
to Keith Randall, goph...@pubsubhelper.golang.org, Ian Lance Taylor, golang-co...@googlegroups.com
Attention needed from Keith Randall

Ian Lance Taylor has uploaded the change for review

Ian Lance Taylor would like Keith Randall to review this change.

Commit message

internal/abi, runtime: put type descriptor sizes in internal/abi
Change-Id: I4ecfda9f85b00a228e8cf51d7ff4457ef7f83ce5

Change diff

diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go
index 8a2b15a..c3f041e 100644
--- a/src/cmd/compile/internal/reflectdata/reflect.go
+++ b/src/cmd/compile/internal/reflectdata/reflect.go
@@ -756,7 +756,7 @@
// | method list, if any | dextratype
// +--------------------------------+ - E

- // runtime.moduleTypelinks is aware of this type layout,
+ // internal/abi.Type.DescriptorSize is aware of this type layout,
// and must be changed if the layout change.

// UncommonType section is included if we have a name or a method.
diff --git a/src/internal/abi/type.go b/src/internal/abi/type.go
index 243b787..e420ce2 100644
--- a/src/internal/abi/type.go
+++ b/src/internal/abi/type.go
@@ -5,6 +5,7 @@
package abi

import (
+ "internal/goarch"
"unsafe"
)

@@ -412,6 +413,22 @@
return (*MapType)(unsafe.Pointer(t))
}

+// PointerType returns t cast to a PtrType, or nil if its tag does not match.
+func (t *Type) PointerType() *PtrType {
+ if t.Kind() != Pointer {
+ return nil
+ }
+ return (*PtrType)(unsafe.Pointer(t))
+}
+
+// SliceType returns t cast to a *SliceType, or nil if its tag does not match.
+func (t *Type) SliceType() *SliceType {
+ if t.Kind() != Slice {
+ return nil
+ }
+ return (*SliceType)(unsafe.Pointer(t))
+}
+
// ArrayType returns t cast to a *ArrayType, or nil if its tag does not match.
func (t *Type) ArrayType() *ArrayType {
if t.Kind() != Array {
@@ -420,6 +437,14 @@
return (*ArrayType)(unsafe.Pointer(t))
}

+// ChanType returns t cast to a *ChanType, or nil if its tag does not match.
+func (t *Type) ChanType() *ChanType {
+ if t.Kind() != Chan {
+ return nil
+ }
+ return (*ChanType)(unsafe.Pointer(t))
+}
+
// FuncType returns t cast to a *FuncType, or nil if its tag does not match.
func (t *Type) FuncType() *FuncType {
if t.Kind() != Func {
@@ -712,6 +737,105 @@
return Name{Bytes: &b[0]}
}

+// DescriptorSize returns the contiguous size taken in memory by the
+// type descriptor. This is the size of the Type struct,
+// plus other fields used by some type kinds, plus the UncommonType
+// struct if present, plus other optional information.
+// This is just the size of the bytes that appear contiguously in memory.
+// It does not include the size of things like type strings
+// and field names that appear elsewhere.
+//
+// This code must match the data structures build by
+// cmd/compile/internal/reflectdata/reflect.go:writeType.
+func (t *Type) DescriptorSize() int {
+ var baseSize, addSize int
+ switch t.Kind_ {
+ case Array:
+ baseSize, addSize = t.ArrayType().descriptorSizes()
+ case Chan:
+ baseSize, addSize = t.ChanType().descriptorSizes()
+ case Func:
+ baseSize, addSize = t.FuncType().descriptorSizes()
+ case Interface:
+ baseSize, addSize = t.InterfaceType().descriptorSizes()
+ case Map:
+ baseSize, addSize = t.MapType().descriptorSizes()
+ case Pointer:
+ baseSize, addSize = t.PointerType().descriptorSizes()
+ case Slice:
+ baseSize, addSize = t.SliceType().descriptorSizes()
+ case Struct:
+ baseSize, addSize = t.StructType().descriptorSizes()
+ case Bool,
+ Int, Int8, Int16, Int32, Int64,
+ Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
+ Float32, Float64, Complex64, Complex128,
+ String, UnsafePointer:
+
+ baseSize = int(unsafe.Sizeof(*t))
+ addSize = 0
+
+ default:
+ panic("DescriptorSize: invalid type descriptor")
+ }
+
+ // For clarity, we add the sizes together in the order
+ // they appear in memory.
+
+ ret := baseSize
+
+ mcount := 0
+ ut := t.Uncommon()
+ if ut != nil {
+ ret += int(unsafe.Sizeof(*ut))
+ mcount = int(ut.Mcount)
+ }
+
+ ret += addSize
+
+ ret += mcount * int(unsafe.Sizeof(Method{}))
+
+ return ret
+}
+
+func (at *ArrayType) descriptorSizes() (base, add int) {
+ return int(unsafe.Sizeof(*at)), 0
+}
+
+func (ct *ChanType) descriptorSizes() (base, add int) {
+ return int(unsafe.Sizeof(*ct)), 0
+}
+
+func (ft *FuncType) descriptorSizes() (base, add int) {
+ base = int(unsafe.Sizeof(*ft))
+ add = (ft.NumIn() + ft.NumOut()) * goarch.PtrSize
+ return base, add
+}
+
+func (it *InterfaceType) descriptorSizes() (base, add int) {
+ base = int(unsafe.Sizeof(*it))
+ add = len(it.Methods) * int(unsafe.Sizeof(Imethod{}))
+ return base, add
+}
+
+func (mt *MapType) descriptorSizes() (base, add int) {
+ return int(unsafe.Sizeof(*mt)), 0
+}
+
+func (pt *PtrType) descriptorSizes() (base, add int) {
+ return int(unsafe.Sizeof(*pt)), 0
+}
+
+func (st *SliceType) descriptorSizes() (base, add int) {
+ return int(unsafe.Sizeof(*st)), 0
+}
+
+func (st *StructType) descriptorSizes() (base, add int) {
+ base = int(unsafe.Sizeof(*st))
+ add = len(st.Fields) * int(unsafe.Sizeof(StructField{}))
+ return base, add
+}
+
const (
TraceArgsLimit = 10 // print no more than 10 args/components
TraceArgsMaxDepth = 5 // no more than 5 layers of nesting
diff --git a/src/runtime/type.go b/src/runtime/type.go
index 893c7940..215ffa9 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -527,67 +527,10 @@
// 0x20 does not make sense.
td = alignUp(td, 0x20)

- // This code must match the data structures built by
- // cmd/compile/internal/reflectdata/reflect.go:writeType.
-
typ := (*_type)(unsafe.Pointer(td))
-
ret = append(ret, typ)

- var typSize, add uintptr
- switch typ.Kind_ {
- case abi.Array:
- typSize = unsafe.Sizeof(abi.ArrayType{})
- case abi.Chan:
- typSize = unsafe.Sizeof(abi.ChanType{})
- case abi.Func:
- typSize = unsafe.Sizeof(abi.FuncType{})
- ft := (*abi.FuncType)(unsafe.Pointer(typ))
- add = uintptr(ft.NumIn()+ft.NumOut()) * goarch.PtrSize
- case abi.Interface:
- typSize = unsafe.Sizeof(abi.InterfaceType{})
- it := (*abi.InterfaceType)(unsafe.Pointer(typ))
- add = uintptr(len(it.Methods)) * unsafe.Sizeof(abi.Imethod{})
- case abi.Map:
- typSize = unsafe.Sizeof(abi.MapType{})
- case abi.Pointer:
- typSize = unsafe.Sizeof(abi.PtrType{})
- case abi.Slice:
- typSize = unsafe.Sizeof(abi.SliceType{})
- case abi.Struct:
- typSize = unsafe.Sizeof(abi.StructType{})
- st := (*abi.StructType)(unsafe.Pointer(typ))
- add = uintptr(len(st.Fields)) * unsafe.Sizeof(abi.StructField{})
-
- case abi.Bool,
- abi.Int, abi.Int8, abi.Int16, abi.Int32, abi.Int64,
- abi.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uint64, abi.Uintptr,
- abi.Float32, abi.Float64,
- abi.Complex64, abi.Complex128,
- abi.String,
- abi.UnsafePointer:
-
- typSize = unsafe.Sizeof(_type{})
-
- default:
- println("type descriptor at", hex(td), "is kind", typ.Kind_)
- throw("invalid type descriptor")
- }
-
- td += typSize
-
- mcount := uintptr(0)
- if typ.TFlag&abi.TFlagUncommon != 0 {
- ut := (*abi.UncommonType)(unsafe.Pointer(td))
- mcount = uintptr(ut.Mcount)
- td += unsafe.Sizeof(abi.UncommonType{})
- }
-
- td += add
-
- if mcount > 0 {
- td += mcount * unsafe.Sizeof(abi.Method{})
- }
+ td += uintptr(typ.DescriptorSize())
}

if moduleToTypelinks == nil {

Change information

Files:
  • M src/cmd/compile/internal/reflectdata/reflect.go
  • M src/internal/abi/type.go
  • M src/runtime/type.go
Change size: M
Delta: 3 files changed, 126 insertions(+), 59 deletions(-)
Open in Gerrit

Related details

Attention is currently required from:
  • Keith Randall
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I4ecfda9f85b00a228e8cf51d7ff4457ef7f83ce5
Gerrit-Change-Number: 726160
Gerrit-PatchSet: 1
Gerrit-Owner: Ian Lance Taylor <ia...@golang.org>
Gerrit-Reviewer: Keith Randall <k...@google.com>
Gerrit-Attention: Keith Randall <k...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Ian Lance Taylor (Gerrit)

unread,
12:14 AM (4 hours ago) 12:14 AM
to Ian Lance Taylor, goph...@pubsubhelper.golang.org, Keith Randall, golang-co...@googlegroups.com
Attention needed from Keith Randall

Ian Lance Taylor voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Keith Randall
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I4ecfda9f85b00a228e8cf51d7ff4457ef7f83ce5
Gerrit-Change-Number: 726160
Gerrit-PatchSet: 1
Gerrit-Owner: Ian Lance Taylor <ia...@golang.org>
Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
Gerrit-Reviewer: Keith Randall <k...@google.com>
Gerrit-Attention: Keith Randall <k...@google.com>
Gerrit-Comment-Date: Wed, 03 Dec 2025 05:14:24 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages