Reduces binary size of cmd/go by 0.5%.
For #6853.
Change-Id: I5a4b814049580ab5098ad252d979f80b70d8a5f9
Reviewed-on: https://go-review.googlesource.com/19694
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
ot := off
s := sym
- if t.Sym != nil {
- ot = dgostringptr(s, ot, t.Sym.Name)
- if t != Types[t.Etype] && t != errortype {
- ot = dgopkgpath(s, ot, t.Sym.Pkg)
- } else {
- ot = dgostringptr(s, ot, "")
- }
+ if t.Sym != nil && t != Types[t.Etype] && t != errortype {
+ ot = dgopkgpath(s, ot, t.Sym.Pkg)
} else {
ot = dgostringptr(s, ot, "")
- ot = dgostringptr(s, ot, "")
}
// slice header
// a limitation of escape analysis. If that is ever fixed the
// allocs < 0.5 condition will trigger and this test should be fixed.
}
+
+type nameTest struct {
+ v interface{}
+ want string
+}
+
+var nameTests = []nameTest{
+ {int32(0), "int32"},
+ {D1{}, "D1"},
+ {[]D1{}, ""},
+ {(chan D1)(nil), ""},
+ {(func() D1)(nil), ""},
+}
+
+func TestNames(t *testing.T) {
+ for _, test := range nameTests {
+ if got := TypeOf(test.v).Name(); got != test.want {
+ t.Errorf("%T Name()=%q, want %q", test.v, got, test.want)
+ }
+ }
+}
// Using a pointer to this struct reduces the overall size required
// to describe an unnamed type with no methods.
type uncommonType struct {
- name *string // name of type
pkgPath *string // import path; nil for built-in types like int, string
methods []method // methods associated with type
}
return *t.pkgPath
}
-func (t *uncommonType) Name() string {
- if t == nil || t.name == nil {
- return ""
- }
- return *t.name
-}
-
func (t *rtype) String() string { return t.string }
func (t *rtype) Size() uintptr { return t.size }
return t.uncommonType.PkgPath()
}
+func hasPrefix(s, prefix string) bool {
+ return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
+
func (t *rtype) Name() string {
- return t.uncommonType.Name()
+ if hasPrefix(t.string, "map[") {
+ return ""
+ }
+ if hasPrefix(t.string, "struct {") {
+ return ""
+ }
+ if hasPrefix(t.string, "chan ") {
+ return ""
+ }
+ if hasPrefix(t.string, "func(") {
+ return ""
+ }
+ if t.string[0] == '[' || t.string[0] == '*' {
+ return ""
+ }
+ i := len(t.string) - 1
+ for i >= 0 {
+ if t.string[i] == '.' {
+ break
+ }
+ i--
+ }
+ return t.string[i+1:]
}
func (t *rtype) ChanDir() ChanDir {
dumpint(tagType)
dumpint(uint64(uintptr(unsafe.Pointer(t))))
dumpint(uint64(t.size))
- if t.x == nil || t.x.pkgpath == nil || t.x.name == nil {
+ if t.x == nil || t.x.pkgpath == nil {
dumpstr(t._string)
} else {
pkgpath := stringStructOf(t.x.pkgpath)
- name := stringStructOf(t.x.name)
+ namestr := t.name()
+ name := stringStructOf(&namestr)
dumpint(uint64(uintptr(pkgpath.len) + 1 + uintptr(name.len)))
dwrite(pkgpath.str, uintptr(pkgpath.len))
dwritebyte('.')
// ok - same type
goto okarg
case fint.kind&kindMask == kindPtr:
- if (fint.x == nil || fint.x.name == nil || etyp.x == nil || etyp.x.name == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
+ if (fint.x == nil || etyp.x == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
// ok - not same type, but both pointers,
// one or the other is unnamed, and same element type, so assignable.
goto okarg
x *uncommontype
}
+func hasPrefix(s, prefix string) bool {
+ return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
+
+func (t *_type) name() string {
+ if hasPrefix(t._string, "map[") {
+ return ""
+ }
+ if hasPrefix(t._string, "struct {") {
+ return ""
+ }
+ if hasPrefix(t._string, "chan ") {
+ return ""
+ }
+ if hasPrefix(t._string, "func(") {
+ return ""
+ }
+ if t._string[0] == '[' || t._string[0] == '*' {
+ return ""
+ }
+ i := len(t._string) - 1
+ for i >= 0 {
+ if t._string[i] == '.' {
+ break
+ }
+ i--
+ }
+ return t._string[i+1:]
+}
+
type method struct {
name *string
pkgpath *string
}
type uncommontype struct {
- name *string
pkgpath *string
mhdr []method
}