Skip to content

Commit 3ddbacb

Browse files
committed
metadata: refine fact deduplication and coverage
1 parent 97a0bbc commit 3ddbacb

8 files changed

Lines changed: 718 additions & 107 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package main
2+
3+
import "reflect"
4+
5+
type T struct{}
6+
7+
func (T) M() {}
8+
9+
func useValue() {
10+
_ = reflect.ValueOf(T{}).Method(0)
11+
}
12+
13+
func useType() {
14+
_ = reflect.TypeOf(T{}).Method(0)
15+
}
16+
17+
func main() {
18+
useValue()
19+
useType()
20+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
[TypeChildren]
2+
*_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac:
3+
_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac
4+
*_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T:
5+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T
6+
7+
[InterfaceInfo]
8+
_llgo_reflect.Type:
9+
Align _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
10+
AssignableTo _llgo_func$Kxk9fspGkjXcoNWf2ucHG1vOQ5VHxVtYionfm-DnvWE
11+
Bits _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
12+
CanSeq _llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk
13+
CanSeq2 _llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk
14+
ChanDir _llgo_func$JO3khPIbANSMBmoN6P7ybYAeUBd3Gv6toVUqNeE7qbE
15+
Comparable _llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk
16+
ConvertibleTo _llgo_func$Kxk9fspGkjXcoNWf2ucHG1vOQ5VHxVtYionfm-DnvWE
17+
Elem _llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI
18+
Field _llgo_func$Q3NYrysaKgu1MtMuLQwb-k5QcKGHihnt-tV_NlNJQFA
19+
FieldAlign _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
20+
FieldByIndex _llgo_func$LPPtiM49dEPl48CC3WRhXm3YPnfUJEZE_k8Tx3rMuSk
21+
FieldByName _llgo_func$dEvABJ5r0MMUlf4smWpIDG5dO8AuGklGdNJ1xneL3UM
22+
FieldByNameFunc _llgo_func$xySrXVFC_2LK2oP71R2UryKi6UmdEJUo9k6aQuz4TvI
23+
Implements _llgo_func$Kxk9fspGkjXcoNWf2ucHG1vOQ5VHxVtYionfm-DnvWE
24+
In _llgo_func$dPYu3A0LoGTV2Hd8PW4KPw2ITiUSo9q-4Bg9ZrPITnY
25+
IsVariadic _llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk
26+
Key _llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI
27+
Kind _llgo_func$w8Mj2LK8G5p7MIiGWR6MYjyXy3L8SVVzYlT1bb6KNXk
28+
Len _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
29+
Method _llgo_func$FmJJGomlX5kINJGxQdQDCAkD89ySoMslAYFrziWInVc
30+
MethodByName _llgo_func$aM2cVUtLQbPq1YHtnabQiM7XJ5Cg5RyV6BIDWrqey7E
31+
Name _llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to
32+
NumField _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
33+
NumIn _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
34+
NumMethod _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
35+
NumOut _llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA
36+
Out _llgo_func$dPYu3A0LoGTV2Hd8PW4KPw2ITiUSo9q-4Bg9ZrPITnY
37+
OverflowComplex _llgo_func$cGkbH-2LQOLoq64Rqj3WeO56U8al7FfVkf5K1FFbPpE
38+
OverflowFloat _llgo_func$uk7PgUVap9GZdvS8R_mZCDbAbqnAbcNryqybtDogUNI
39+
OverflowInt _llgo_func$odFOIClZoEVGbTP_BEfZxVM5ex3r8Fj1afUEeP_awp8
40+
OverflowUint _llgo_func$7I97sofX8UqJA96mVIy89KPUfSM_efkrR-mJQ9qaHfk
41+
PkgPath _llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to
42+
Size _llgo_func$1kITCsyu7hFLMxHLR7kDlvu4SOra_HtrtdFUQH9P13s
43+
String _llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to
44+
reflect.common _llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw
45+
reflect.uncommon _llgo_func$iG49bujiXjI2lVflYdE0hPXlCAABL-XKRANSNJEKOio
46+
47+
[OrdinaryEdges]
48+
*_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac:
49+
__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequalptr
50+
_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac
51+
*_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T:
52+
__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequalptr
53+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T
54+
__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequal0:
55+
github.com/goplus/llgo/runtime/internal/runtime.memequal0
56+
__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequalptr:
57+
github.com/goplus/llgo/runtime/internal/runtime.memequalptr
58+
_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac:
59+
*_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac
60+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T:
61+
__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequal0
62+
*_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T
63+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.(*T).M:
64+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T.M
65+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.init:
66+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.init$guard
67+
reflect.init
68+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.main:
69+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useValue
70+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useType
71+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useType:
72+
github.com/goplus/llgo/runtime/internal/runtime.AllocU
73+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T
74+
reflect.TypeOf
75+
github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData
76+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useValue:
77+
github.com/goplus/llgo/runtime/internal/runtime.AllocU
78+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T
79+
reflect.ValueOf
80+
reflect.Value.Method
81+
82+
[UseIface]
83+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useType:
84+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T
85+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useValue:
86+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T
87+
88+
[UseIfaceMethod]
89+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useType:
90+
_llgo_reflect.Type Method _llgo_func$FmJJGomlX5kINJGxQdQDCAkD89ySoMslAYFrziWInVc
91+
92+
[MethodInfo]
93+
*_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T:
94+
0 M _llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac github.com/goplus/llgo/cl/_testmeta/reflect_method_index.(*T).M github.com/goplus/llgo/cl/_testmeta/reflect_method_index.(*T).M
95+
_llgo_github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T:
96+
0 M _llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac github.com/goplus/llgo/cl/_testmeta/reflect_method_index.(*T).M github.com/goplus/llgo/cl/_testmeta/reflect_method_index.T.M
97+
98+
[ReflectMethod]
99+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useType
100+
github.com/goplus/llgo/cl/_testmeta/reflect_method_index.useValue
101+

internal/metadata/builder.go

Lines changed: 61 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,27 @@ package metadata
22

33
// Builder accumulates per-package metadata facts and builds a PackageMeta.
44
type Builder struct {
5-
pm *PackageMeta
6-
strToID map[string]uint32
5+
pm *PackageMeta
6+
strToID map[string]uint32
7+
seenEdge map[[2]Symbol]struct{}
8+
seenTypeChild map[[2]Symbol]struct{}
9+
seenInterfaceInfo map[interfaceInfoKey]struct{}
10+
seenUseIface map[[2]Symbol]struct{}
11+
seenUseIfaceMethod map[useIfaceMethodKey]struct{}
12+
seenUseNamedMethod map[useNamedMethodKey]struct{}
713
}
814

915
// NewBuilder creates an empty metadata builder.
1016
func NewBuilder() *Builder {
1117
return &Builder{
12-
pm: NewPackageMeta(nil),
13-
strToID: make(map[string]uint32),
18+
pm: NewPackageMeta(nil),
19+
strToID: make(map[string]uint32),
20+
seenEdge: make(map[[2]Symbol]struct{}),
21+
seenTypeChild: make(map[[2]Symbol]struct{}),
22+
seenInterfaceInfo: make(map[interfaceInfoKey]struct{}),
23+
seenUseIface: make(map[[2]Symbol]struct{}),
24+
seenUseIfaceMethod: make(map[useIfaceMethodKey]struct{}),
25+
seenUseNamedMethod: make(map[useNamedMethodKey]struct{}),
1426
}
1527
}
1628

@@ -35,32 +47,57 @@ func (b *Builder) intern(s string) uint32 {
3547

3648
// AddEdge records an ordinary reachability edge src -> dst.
3749
func (b *Builder) AddEdge(src, dst Symbol) {
38-
addUniqueSymbol(&b.pm.ordinaryEdges, src, dst)
50+
key := [2]Symbol{src, dst}
51+
if _, ok := b.seenEdge[key]; ok {
52+
return
53+
}
54+
b.seenEdge[key] = struct{}{}
55+
b.pm.ordinaryEdges[src] = append(b.pm.ordinaryEdges[src], dst)
3956
}
4057

4158
// AddTypeChild records that parent type references child type.
4259
func (b *Builder) AddTypeChild(parent, child Symbol) {
43-
addUniqueSymbol(&b.pm.typeChildren, parent, child)
60+
key := [2]Symbol{parent, child}
61+
if _, ok := b.seenTypeChild[key]; ok {
62+
return
63+
}
64+
b.seenTypeChild[key] = struct{}{}
65+
b.pm.typeChildren[parent] = append(b.pm.typeChildren[parent], child)
4466
}
4567

4668
// AddIfaceEntry records the method set of an interface type.
4769
func (b *Builder) AddIfaceEntry(iface Symbol, methods []MethodSig) {
4870
for _, method := range methods {
49-
addUniqueMethodSig(&b.pm.interfaceInfo, iface, method)
71+
key := interfaceInfoKey{Iface: iface, Sig: method}
72+
if _, ok := b.seenInterfaceInfo[key]; ok {
73+
continue
74+
}
75+
b.seenInterfaceInfo[key] = struct{}{}
76+
b.pm.interfaceInfo[iface] = append(b.pm.interfaceInfo[iface], method)
5077
}
5178
}
5279

5380
// AddUseIface records types converted to interface when owner is reachable.
5481
func (b *Builder) AddUseIface(owner Symbol, types []Symbol) {
5582
for _, typ := range types {
56-
addUniqueSymbol(&b.pm.useIface, owner, typ)
83+
key := [2]Symbol{owner, typ}
84+
if _, ok := b.seenUseIface[key]; ok {
85+
continue
86+
}
87+
b.seenUseIface[key] = struct{}{}
88+
b.pm.useIface[owner] = append(b.pm.useIface[owner], typ)
5789
}
5890
}
5991

6092
// AddUseIfaceMethod records interface method calls when owner is reachable.
6193
func (b *Builder) AddUseIfaceMethod(owner Symbol, demands []IfaceMethodDemand) {
6294
for _, demand := range demands {
63-
addUniqueIfaceMethodDemand(&b.pm.useIfaceMethod, owner, demand)
95+
key := useIfaceMethodKey{Owner: owner, Demand: demand}
96+
if _, ok := b.seenUseIfaceMethod[key]; ok {
97+
continue
98+
}
99+
b.seenUseIfaceMethod[key] = struct{}{}
100+
b.pm.useIfaceMethod[owner] = append(b.pm.useIfaceMethod[owner], demand)
64101
}
65102
}
66103

@@ -75,7 +112,12 @@ func (b *Builder) AddMethodInfo(typeID Symbol, slots []MethodSlot) {
75112
// AddUseNamedMethod records constant MethodByName method names.
76113
func (b *Builder) AddUseNamedMethod(owner Symbol, names []Name) {
77114
for _, name := range names {
78-
addUniqueName(&b.pm.useNamedMethod, owner, name)
115+
key := useNamedMethodKey{Owner: owner, Name: name}
116+
if _, ok := b.seenUseNamedMethod[key]; ok {
117+
continue
118+
}
119+
b.seenUseNamedMethod[key] = struct{}{}
120+
b.pm.useNamedMethod[owner] = append(b.pm.useNamedMethod[owner], name)
79121
}
80122
}
81123

@@ -94,42 +136,17 @@ func (b *Builder) Build() *PackageMeta {
94136
return b.pm
95137
}
96138

97-
func addUniqueSymbol(m *map[Symbol][]Symbol, key, value Symbol) {
98-
values := (*m)[key]
99-
for _, existing := range values {
100-
if existing == value {
101-
return
102-
}
103-
}
104-
(*m)[key] = append(values, value)
105-
}
106-
107-
func addUniqueName(m *map[Symbol][]Name, key Symbol, value Name) {
108-
values := (*m)[key]
109-
for _, existing := range values {
110-
if existing == value {
111-
return
112-
}
113-
}
114-
(*m)[key] = append(values, value)
139+
type interfaceInfoKey struct {
140+
Iface Symbol
141+
Sig MethodSig
115142
}
116143

117-
func addUniqueMethodSig(m *map[Symbol][]MethodSig, key Symbol, value MethodSig) {
118-
values := (*m)[key]
119-
for _, existing := range values {
120-
if existing == value {
121-
return
122-
}
123-
}
124-
(*m)[key] = append(values, value)
144+
type useIfaceMethodKey struct {
145+
Owner Symbol
146+
Demand IfaceMethodDemand
125147
}
126148

127-
func addUniqueIfaceMethodDemand(m *map[Symbol][]IfaceMethodDemand, key Symbol, value IfaceMethodDemand) {
128-
values := (*m)[key]
129-
for _, existing := range values {
130-
if existing == value {
131-
return
132-
}
133-
}
134-
(*m)[key] = append(values, value)
149+
type useNamedMethodKey struct {
150+
Owner Symbol
151+
Name Name
135152
}

0 commit comments

Comments
 (0)