aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2023-12-12 21:03:09 -0800
committerKeith Randall <khr@golang.org>2024-02-08 03:01:15 +0000
commit977803e796eed6efaa85bbc6a7b6b03629291989 (patch)
treeab41dcc953fd73375eb18d06efb8038399abb61d /src
parente0ee5b1afa4d6b53d80fbba1195fe148b7505d99 (diff)
downloadgo-977803e796eed6efaa85bbc6a7b6b03629291989.tar.xz
cmd/compile: generate itabs using rttype mechanism
Change-Id: I9a85704c57e978c8c6303b21da3e4627d3446f3e Reviewed-on: https://go-review.googlesource.com/c/go/+/549455 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/reflectdata/reflect.go25
-rw-r--r--src/cmd/compile/internal/rttype/rttype.go22
2 files changed, 37 insertions, 10 deletions
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go
index 8ef1a913e8..fd64b2ebfe 100644
--- a/src/cmd/compile/internal/reflectdata/reflect.go
+++ b/src/cmd/compile/internal/reflectdata/reflect.go
@@ -1331,20 +1331,25 @@ func writeITab(lsym *obj.LSym, typ, iface *types.Type, allowNonImplement bool) {
// _ [4]byte
// fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
// }
- o := objw.SymPtr(lsym, 0, writeType(iface), 0)
- o = objw.SymPtr(lsym, o, writeType(typ), 0)
- o = objw.Uint32(lsym, o, types.TypeHash(typ)) // copy of type hash
- o += 4 // skip unused field
+ c := rttype.NewCursor(lsym, 0, rttype.ITab)
+ c.Field("Inter").WritePtr(writeType(iface))
+ c.Field("Type").WritePtr(writeType(typ))
+ c.Field("Hash").WriteUint32(types.TypeHash(typ)) // copy of type hash
+
+ var delta int64
+ c = c.Field("Fun")
if !completeItab {
// If typ doesn't implement iface, make method entries be zero.
- o = objw.Uintptr(lsym, o, 0)
- entries = entries[:0]
- }
- for _, fn := range entries {
- o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
+ c.Elem(0).WriteUintptr(0)
+ } else {
+ var a rttype.ArrayCursor
+ a, delta = c.ModifyArray(len(entries))
+ for i, fn := range entries {
+ a.Elem(i).WritePtrWeak(fn) // method pointer for each method
+ }
}
// Nothing writes static itabs, so they are read only.
- objw.Global(lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
+ objw.Global(lsym, int32(rttype.ITab.Size()+delta), int16(obj.DUPOK|obj.RODATA))
lsym.Set(obj.AttrContentAddressable, true)
}
diff --git a/src/cmd/compile/internal/rttype/rttype.go b/src/cmd/compile/internal/rttype/rttype.go
index cdc399d9cf..b53ed8001f 100644
--- a/src/cmd/compile/internal/rttype/rttype.go
+++ b/src/cmd/compile/internal/rttype/rttype.go
@@ -42,6 +42,9 @@ var UncommonType *types.Type
var InterfaceSwitch *types.Type
var TypeAssert *types.Type
+// Interface tables (itabs)
+var ITab *types.Type
+
func Init() {
// Note: this has to be called explicitly instead of being
// an init function so it runs after the types package has
@@ -64,6 +67,8 @@ func Init() {
InterfaceSwitch = fromReflect(reflect.TypeOf(abi.InterfaceSwitch{}))
TypeAssert = fromReflect(reflect.TypeOf(abi.TypeAssert{}))
+ ITab = fromReflect(reflect.TypeOf(abi.ITab{}))
+
// Make sure abi functions are correct. These functions are used
// by the linker which doesn't have the ability to do type layout,
// so we check the functions it uses here.
@@ -154,6 +159,12 @@ func (c Cursor) WritePtr(target *obj.LSym) {
objw.SymPtr(c.lsym, int(c.offset), target, 0)
}
}
+func (c Cursor) WritePtrWeak(target *obj.LSym) {
+ if c.typ.Kind() != types.TUINTPTR {
+ base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
+ }
+ objw.SymPtrWeak(c.lsym, int(c.offset), target, 0)
+}
func (c Cursor) WriteUintptr(val uint64) {
if c.typ.Kind() != types.TUINTPTR {
base.Fatalf("can't write uintptr, it has kind %s", c.typ.Kind())
@@ -250,6 +261,17 @@ func (c Cursor) Field(name string) Cursor {
return Cursor{}
}
+func (c Cursor) Elem(i int64) Cursor {
+ if c.typ.Kind() != types.TARRAY {
+ base.Fatalf("can't call Elem on non-array %v", c.typ)
+ }
+ if i < 0 || i >= c.typ.NumElem() {
+ base.Fatalf("element access out of bounds [%d] in [0:%d]", i, c.typ.NumElem())
+ }
+ elem := c.typ.Elem()
+ return Cursor{lsym: c.lsym, offset: c.offset + i*elem.Size(), typ: elem}
+}
+
type ArrayCursor struct {
c Cursor // cursor pointing at first element
n int // number of elements