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 for _, cv := range fn.ClosureVars {
80 if cv.Used() {
81 visit(cv.Type())
82 }
83 }
84 }
85
86 reflectdata.ForEachRuntimeType(visit)
87
88
89
90 for _, name := range slices.Sorted(maps.Keys(types.LocalPkg.Syms)) {
91 if n, ok := types.LocalPkg.Syms[name].Def.(*ir.Name); ok && usedTypes[n.Type()] {
92 if n.Op() == ir.OTYPE && !n.Alias() && typeShouldBeIndexed(n.Type()) {
93 base.Ctxt.NumberSymEarly(reflectdata.TypeLinksym(n.Type()))
94 base.Ctxt.NumberSymEarly(reflectdata.TypeLinksym(n.Type().PtrTo()))
95 }
96 }
97 }
98 }
99
100
101
102
103
104 func lsymShouldBeIndexed(lsym *obj.LSym) bool {
105 return lsym.PkgIdx == goobj.PkgIdxInvalid && !lsym.Indexed() && !lsym.ContentAddressable() && !base.Ctxt.IsNonPkgSym(lsym)
106 }
107
108
109
110
111
112
113
114 func nameShouldBeIndexed(name *ir.Name) bool {
115 return lsymShouldBeIndexed(name.Linksym()) &&
116 name.Class == ir.PEXTERN && name.Sym().Pkg == types.LocalPkg && name.Sym().Linkname == ""
117 }
118
119
120
121
122 func typeShouldBeIndexed(typ *types.Type) bool {
123 return typ.Sym() != nil && typ.Sym().Pkg == types.LocalPkg && !reflectdata.TypeCanBeDupok(typ) &&
124 lsymShouldBeIndexed(types.TypeSym(typ).Linksym())
125 }
126
127
128 func funcShouldBeIndexed(fn *ir.Func, symABIs *ssagen.SymABIs) bool {
129 name := fn.Nname
130 if fn.ABI != obj.ABIInternal || fn.Dupok() || fn.IsClosure() || ir.IsBlank(name) || name.Sym().Linkname != "" || !lsymShouldBeIndexed(name.Linksym()) {
131 return false
132 }
133 return len(fn.Body) != 0 || fn.WasmImport != nil || needsIntrinsicBody(fn, symABIs)
134 }
135
View as plain text