From 977803e796eed6efaa85bbc6a7b6b03629291989 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 12 Dec 2023 21:03:09 -0800 Subject: [PATCH] cmd/compile: generate itabs using rttype mechanism Change-Id: I9a85704c57e978c8c6303b21da3e4627d3446f3e Reviewed-on: https://go-review.googlesource.com/c/go/+/549455 Reviewed-by: David Chase LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- .../compile/internal/reflectdata/reflect.go | 25 +++++++++++-------- src/cmd/compile/internal/rttype/rttype.go | 22 ++++++++++++++++ 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 -- 2.48.1