Commit 44d3f89e authored by David Crawshaw's avatar David Crawshaw

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/21033Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent c1892b9c
......@@ -86,17 +86,6 @@ func deadcode(ctxt *Link) {
for _, m := range d.markableMethods {
if (reflectSeen && m.isExported()) || d.ifaceMethod[m.m] {
d.markMethod(m)
} else if reflectSeen {
// This ensures the Type and Func fields of
// reflect.Method are filled as they were in
// Go 1.
//
// An argument could be made for changing this
// and setting those fields to nil. Doing so
// would reduce the binary size of typical
// programs like cmd/go by ~2%.
d.mark(m.mtyp(), m.src)
rem = append(rem, m)
} else {
rem = append(rem, m)
}
......
......@@ -2367,6 +2367,32 @@ func TestNestedMethods(t *testing.T) {
}
}
type unexp struct{}
func (*unexp) f() (int32, int8) { return 7, 7 }
func (*unexp) g() (int64, int8) { return 8, 8 }
func TestUnexportedMethods(t *testing.T) {
_ = (interface {
f() (int32, int8)
})(new(unexp))
typ := TypeOf(new(unexp))
if typ.Method(0).Type == nil {
t.Error("missing type for satisfied method 'f'")
}
if !typ.Method(0).Func.IsValid() {
t.Error("missing func for satisfied method 'f'")
}
if typ.Method(1).Type != nil {
t.Error("found type for unsatisfied method 'g'")
}
if typ.Method(1).Func.IsValid() {
t.Error("found func for unsatisfied method 'g'")
}
}
type InnerInt struct {
X int
}
......
......@@ -591,20 +591,22 @@ func (t *rtype) Method(i int) (m Method) {
m.PkgPath = *p.pkgPath
fl |= flagStickyRO
}
ft := (*funcType)(unsafe.Pointer(p.mtyp))
in := make([]Type, 0, 1+len(ft.in()))
in = append(in, t)
for _, arg := range ft.in() {
in = append(in, arg)
}
out := make([]Type, 0, len(ft.out()))
for _, ret := range ft.out() {
out = append(out, ret)
}
mt := FuncOf(in, out, p.mtyp.IsVariadic())
m.Type = mt
fn := unsafe.Pointer(&p.tfn)
m.Func = Value{mt.(*rtype), fn, fl}
if p.mtyp != nil {
ft := (*funcType)(unsafe.Pointer(p.mtyp))
in := make([]Type, 0, 1+len(ft.in()))
in = append(in, t)
for _, arg := range ft.in() {
in = append(in, arg)
}
out := make([]Type, 0, len(ft.out()))
for _, ret := range ft.out() {
out = append(out, ret)
}
mt := FuncOf(in, out, p.mtyp.IsVariadic())
m.Type = mt
fn := unsafe.Pointer(&p.tfn)
m.Func = Value{mt.(*rtype), fn, fl}
}
m.Index = i
return m
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment