Skip to content

Commit 44d3f89

Browse files
committed
cmd/link, reflect: remove some method type data
Remove reflect type information for unexported methods that do not satisfy any interface in the program. Ideally the unexported method would not appear in the method list at all, but that is tricky because the slice is built by the compiler. Reduces binary size: cmd/go: 81KB (0.8%) jujud: 258KB (0.4%) For #6853. Change-Id: I25ef8df6907e9ac03b18689d584ea46e7d773043 Reviewed-on: https://go-review.googlesource.com/21033 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Russ Cox <[email protected]> Run-TryBot: David Crawshaw <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent c1892b9 commit 44d3f89

File tree

3 files changed

+42
-25
lines changed

3 files changed

+42
-25
lines changed

src/cmd/link/internal/ld/deadcode.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,6 @@ func deadcode(ctxt *Link) {
8686
for _, m := range d.markableMethods {
8787
if (reflectSeen && m.isExported()) || d.ifaceMethod[m.m] {
8888
d.markMethod(m)
89-
} else if reflectSeen {
90-
// This ensures the Type and Func fields of
91-
// reflect.Method are filled as they were in
92-
// Go 1.
93-
//
94-
// An argument could be made for changing this
95-
// and setting those fields to nil. Doing so
96-
// would reduce the binary size of typical
97-
// programs like cmd/go by ~2%.
98-
d.mark(m.mtyp(), m.src)
99-
rem = append(rem, m)
10089
} else {
10190
rem = append(rem, m)
10291
}

src/reflect/all_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,6 +2367,32 @@ func TestNestedMethods(t *testing.T) {
23672367
}
23682368
}
23692369

2370+
type unexp struct{}
2371+
2372+
func (*unexp) f() (int32, int8) { return 7, 7 }
2373+
func (*unexp) g() (int64, int8) { return 8, 8 }
2374+
2375+
func TestUnexportedMethods(t *testing.T) {
2376+
_ = (interface {
2377+
f() (int32, int8)
2378+
})(new(unexp))
2379+
2380+
typ := TypeOf(new(unexp))
2381+
2382+
if typ.Method(0).Type == nil {
2383+
t.Error("missing type for satisfied method 'f'")
2384+
}
2385+
if !typ.Method(0).Func.IsValid() {
2386+
t.Error("missing func for satisfied method 'f'")
2387+
}
2388+
if typ.Method(1).Type != nil {
2389+
t.Error("found type for unsatisfied method 'g'")
2390+
}
2391+
if typ.Method(1).Func.IsValid() {
2392+
t.Error("found func for unsatisfied method 'g'")
2393+
}
2394+
}
2395+
23702396
type InnerInt struct {
23712397
X int
23722398
}

src/reflect/type.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -591,20 +591,22 @@ func (t *rtype) Method(i int) (m Method) {
591591
m.PkgPath = *p.pkgPath
592592
fl |= flagStickyRO
593593
}
594-
ft := (*funcType)(unsafe.Pointer(p.mtyp))
595-
in := make([]Type, 0, 1+len(ft.in()))
596-
in = append(in, t)
597-
for _, arg := range ft.in() {
598-
in = append(in, arg)
599-
}
600-
out := make([]Type, 0, len(ft.out()))
601-
for _, ret := range ft.out() {
602-
out = append(out, ret)
603-
}
604-
mt := FuncOf(in, out, p.mtyp.IsVariadic())
605-
m.Type = mt
606-
fn := unsafe.Pointer(&p.tfn)
607-
m.Func = Value{mt.(*rtype), fn, fl}
594+
if p.mtyp != nil {
595+
ft := (*funcType)(unsafe.Pointer(p.mtyp))
596+
in := make([]Type, 0, 1+len(ft.in()))
597+
in = append(in, t)
598+
for _, arg := range ft.in() {
599+
in = append(in, arg)
600+
}
601+
out := make([]Type, 0, len(ft.out()))
602+
for _, ret := range ft.out() {
603+
out = append(out, ret)
604+
}
605+
mt := FuncOf(in, out, p.mtyp.IsVariadic())
606+
m.Type = mt
607+
fn := unsafe.Pointer(&p.tfn)
608+
m.Func = Value{mt.(*rtype), fn, fl}
609+
}
608610
m.Index = i
609611
return m
610612
}

0 commit comments

Comments
 (0)