1
2
3
4
5 package gc
6
7 import (
8 "maps"
9 "slices"
10
11 "cmd/compile/internal/base"
12 "cmd/compile/internal/ir"
13 "cmd/compile/internal/reflectdata"
14 "cmd/compile/internal/ssagen"
15 "cmd/compile/internal/typecheck"
16 "cmd/compile/internal/types"
17 "cmd/internal/goobj"
18 "cmd/internal/obj"
19 )
20
21
22
23 func preassignSymIdxs(symABIs *ssagen.SymABIs) {
24
25
26
27
28 usedTypes := make(map[*types.Type]bool)
29 var visit func(*types.Type)
30 visit = func(t *types.Type) {
31 if t == nil || usedTypes[t] {
32 return
33 }
34 usedTypes[t] = true
35 switch t.Kind() {
36 case types.TPTR, types.TSLICE, types.TARRAY, types.TCHAN:
37 visit(t.Elem())
38 case types.TMAP:
39 visit(t.Key())
40 visit(t.Elem())
41 case types.TSTRUCT:
42 for _, f := range t.Fields() {
43 visit(f.Type)
44 }
45 case types.TFUNC:
46 for _, f := range t.RecvParamsResults() {
47 visit(f.Type)
48 }
49 case types.TINTER:
50 for _, m := range t.AllMethods() {
51 visit(m.Type)
52 }
53 }
54 if t.Sym() != nil && !t.IsInterface() {
55 for _, m := range t.Methods() {
56 visit(m.Type)
57 }
58 }
59 }
60
61 for _, n := range typecheck.Target.Externs {
62 if n.Op() == ir.ONAME && nameShouldBeIndexed(n) {
63 base.Ctxt.NumberSymEarly(n.Linksym())
64 }
65 if n.Op() == ir.OTYPE {
66 visit(n.Type())
67 }
68 }
69
70 for _, fn := range typecheck.Target.Funcs {
71 if funcShouldBeIndexed(fn, symABIs) {
72 base.Ctxt.NumberSymEarly(fn.Nname.Linksym())
73 }
74 for _, dcl := range fn.Dcl {
75 if dcl.Op() == ir.ONAME && dcl.Used() {
76 visit(dcl.Type())
77 }
78 }
79 }
80
81 reflectdata.ForEachRuntimeType(visit)
82
83
84
85 for _, name := range slices.Sorted(maps.Keys(types.LocalPkg.Syms)) {
86 if n, ok := types.LocalPkg.Syms[name].Def.(*ir.Name); ok && usedTypes[n.Type()] {
87 if n.Op() == ir.OTYPE && !n.Alias() && typeShouldBeIndexed(n.Type()) {
88 base.Ctxt.NumberSymEarly(reflectdata.TypeLinksym(n.Type()))
89 base.Ctxt.NumberSymEarly(reflectdata.TypeLinksym(n.Type().PtrTo()))
90 }
91 }
92 }
93 }
94
95
96
97
98
99 func lsymShouldBeIndexed(lsym *obj.LSym) bool {
100 return lsym.PkgIdx == goobj.PkgIdxInvalid && !lsym.Indexed() && !lsym.ContentAddressable() && !base.Ctxt.IsNonPkgSym(lsym)
101 }
102
103
104
105
106
107
108
109 func nameShouldBeIndexed(name *ir.Name) bool {
110 return lsymShouldBeIndexed(name.Linksym()) &&
111 name.Class == ir.PEXTERN && name.Sym().Pkg == types.LocalPkg && name.Sym().Linkname == ""
112 }
113
114
115
116
117 func typeShouldBeIndexed(typ *types.Type) bool {
118 return typ.Sym() != nil && typ.Sym().Pkg == types.LocalPkg && !reflectdata.TypeCanBeDupok(typ) &&
119 lsymShouldBeIndexed(types.TypeSym(typ).Linksym())
120 }
121
122
123 func funcShouldBeIndexed(fn *ir.Func, symABIs *ssagen.SymABIs) bool {
124 name := fn.Nname
125 if fn.ABI != obj.ABIInternal || fn.Dupok() || fn.IsClosure() || ir.IsBlank(name) || name.Sym().Linkname != "" || !lsymShouldBeIndexed(name.Linksym()) {
126 return false
127 }
128 return len(fn.Body) != 0 || fn.WasmImport != nil || needsIntrinsicBody(fn, symABIs)
129 }
130
View as plain text