aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/type.go
diff options
context:
space:
mode:
authorDavid Crawshaw <crawshaw@golang.org>2016-03-28 21:51:10 -0400
committerDavid Crawshaw <crawshaw@golang.org>2016-04-18 09:12:41 +0000
commit95df0c6ab93f6a42bdc9fd45500fd4d56bfc9add (patch)
tree29fe9162ca68298b592ff154bff3637632aedbac /src/runtime/type.go
parent3c8d6af8e02bbf230c2bef9f181d8ea393068299 (diff)
downloadgo-95df0c6ab93f6a42bdc9fd45500fd4d56bfc9add.tar.xz
cmd/compile, etc: use name offset in method tables
Introduce and start using nameOff for two encoded names. This pair of changes is best done together because the linker's method decoder expects the method layouts to match. Precursor to converting all existing name and *string fields to nameOff. linux/amd64: cmd/go: -45KB (0.5%) jujud: -389KB (0.6%) linux/amd64 PIE: cmd/go: -170KB (1.4%) jujud: -1.5MB (1.8%) For #6853. Change-Id: Ia044423f010fb987ce070b94c46a16fc78666ff6 Reviewed-on: https://go-review.googlesource.com/21396 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/type.go')
-rw-r--r--src/runtime/type.go46
1 files changed, 29 insertions, 17 deletions
diff --git a/src/runtime/type.go b/src/runtime/type.go
index 711753bab5..31f7ff81b8 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -161,11 +161,17 @@ func resolveNameOff(ptrInModule unsafe.Pointer, off nameOff) name {
}
}
if md == nil {
- println("runtime: nameOff", hex(off), "base", hex(base), "not in ranges:")
- for next := &firstmoduledata; next != nil; next = next.next {
- println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
+ lock(&reflectOffs.lock)
+ res, found := reflectOffs.m[int32(off)]
+ unlock(&reflectOffs.lock)
+ if !found {
+ println("runtime: nameOff", hex(off), "base", hex(base), "not in ranges:")
+ for next := &firstmoduledata; next != nil; next = next.next {
+ println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
+ }
+ throw("runtime: name offset base pointer out of range")
}
- throw("runtime: name offset base pointer out of range")
+ return name{(*byte)(res)}
}
res := md.types + uintptr(off)
if res > md.etypes {
@@ -175,6 +181,10 @@ func resolveNameOff(ptrInModule unsafe.Pointer, off nameOff) name {
return name{(*byte)(unsafe.Pointer(res))}
}
+func (t *_type) nameOff(off nameOff) name {
+ return resolveNameOff(unsafe.Pointer(t), off)
+}
+
func (t *_type) typeOff(off typeOff) *_type {
if off == 0 {
return nil
@@ -269,7 +279,7 @@ type typeOff int32
type textOff int32
type method struct {
- name name
+ name nameOff
mtyp typeOff
ifn textOff
tfn textOff
@@ -282,8 +292,8 @@ type uncommontype struct {
}
type imethod struct {
- name name
- _type *_type
+ name nameOff
+ ityp typeOff
}
type interfacetype struct {
@@ -354,19 +364,19 @@ type name struct {
bytes *byte
}
-func (n *name) data(off int) *byte {
+func (n name) data(off int) *byte {
return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off)))
}
-func (n *name) isExported() bool {
+func (n name) isExported() bool {
return (*n.bytes)&(1<<0) != 0
}
-func (n *name) nameLen() int {
+func (n name) nameLen() int {
return int(uint16(*n.data(1))<<8 | uint16(*n.data(2)))
}
-func (n *name) tagLen() int {
+func (n name) tagLen() int {
if *n.data(0)&(1<<1) == 0 {
return 0
}
@@ -374,7 +384,7 @@ func (n *name) tagLen() int {
return int(uint16(*n.data(off))<<8 | uint16(*n.data(off + 1)))
}
-func (n *name) name() (s string) {
+func (n name) name() (s string) {
if n.bytes == nil {
return ""
}
@@ -388,7 +398,7 @@ func (n *name) name() (s string) {
return s
}
-func (n *name) tag() (s string) {
+func (n name) tag() (s string) {
tl := n.tagLen()
if tl == 0 {
return ""
@@ -400,7 +410,7 @@ func (n *name) tag() (s string) {
return s
}
-func (n *name) pkgPath() string {
+func (n name) pkgPath() string {
if n.bytes == nil || *n.data(0)&(1<<2) == 0 {
return ""
}
@@ -545,13 +555,15 @@ func typesEqual(t, v *_type) bool {
for i := range it.mhdr {
tm := &it.mhdr[i]
vm := &iv.mhdr[i]
- if tm.name.name() != vm.name.name() {
+ tname := it.typ.nameOff(tm.name)
+ vname := iv.typ.nameOff(vm.name)
+ if tname.name() != vname.name() {
return false
}
- if tm.name.pkgPath() != vm.name.pkgPath() {
+ if tname.pkgPath() != vname.pkgPath() {
return false
}
- if !typesEqual(tm._type, vm._type) {
+ if !typesEqual(it.typ.typeOff(tm.ityp), iv.typ.typeOff(vm.ityp)) {
return false
}
}