]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: generate itabs using rttype mechanism
authorKeith Randall <khr@golang.org>
Wed, 13 Dec 2023 05:03:09 +0000 (21:03 -0800)
committerKeith Randall <khr@golang.org>
Thu, 8 Feb 2024 03:01:15 +0000 (03:01 +0000)
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>
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/compile/internal/rttype/rttype.go

index 8ef1a913e8257faab76877c76bb1632d10717dd7..fd64b2ebfe3679ba126bca99bb2189246db24e9d 100644 (file)
@@ -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)
 }
 
index cdc399d9cfff45e87acd465abbc29e2229d32600..b53ed8001f08f7257b2125b1b56e78d8923770e5 100644 (file)
@@ -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