mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile, runtime: new static name encoding
Create a byte encoding designed for static Go names. It is intended to be a compact representation of a name and optional tag data that can be turned into a Go string without allocating, and describes whether or not it is exported without unicode table. The encoding is described in reflect/type.go: // The first byte is a bit field containing: // // 1<<0 the name is exported // 1<<1 tag data follows the name // 1<<2 pkgPath *string follow the name and tag // // The next two bytes are the data length: // // l := uint16(data[1])<<8 | uint16(data[2]) // // Bytes [3:3+l] are the string data. // // If tag data follows then bytes 3+l and 3+l+1 are the tag length, // with the data following. // // If the import path follows, then ptrSize bytes at the end of // the data form a *string. The import path is only set for concrete // methods that are defined in a different package than their type. Shrinks binary sizes: cmd/go: 164KB (1.6%) jujud: 1.0MB (1.5%) For #6853. Change-Id: I46b6591015b17936a443c9efb5009de8dfe8b609 Reviewed-on: https://go-review.googlesource.com/20968 Run-TryBot: David Crawshaw <crawshaw@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
0a82ed5d7c
commit
24ce64d1a9
6 changed files with 387 additions and 138 deletions
|
|
@ -6,7 +6,10 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"runtime/internal/sys"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// tflag is documented in ../reflect/type.go.
|
||||
type tflag uint8
|
||||
|
|
@ -152,11 +155,10 @@ func (t *functype) dotdotdot() bool {
|
|||
}
|
||||
|
||||
type method struct {
|
||||
name *string
|
||||
pkgpath *string
|
||||
mtyp *_type
|
||||
ifn unsafe.Pointer
|
||||
tfn unsafe.Pointer
|
||||
name name
|
||||
mtyp *_type
|
||||
ifn unsafe.Pointer
|
||||
tfn unsafe.Pointer
|
||||
}
|
||||
|
||||
type uncommontype struct {
|
||||
|
|
@ -165,14 +167,14 @@ type uncommontype struct {
|
|||
}
|
||||
|
||||
type imethod struct {
|
||||
name *string
|
||||
pkgpath *string
|
||||
_type *_type
|
||||
name name
|
||||
_type *_type
|
||||
}
|
||||
|
||||
type interfacetype struct {
|
||||
typ _type
|
||||
mhdr []imethod
|
||||
typ _type
|
||||
pkgpath *string
|
||||
mhdr []imethod
|
||||
}
|
||||
|
||||
type maptype struct {
|
||||
|
|
@ -220,14 +222,62 @@ type ptrtype struct {
|
|||
}
|
||||
|
||||
type structfield struct {
|
||||
name *string
|
||||
pkgpath *string
|
||||
typ *_type
|
||||
tag *string
|
||||
offset uintptr
|
||||
name name
|
||||
typ *_type
|
||||
offset uintptr
|
||||
}
|
||||
|
||||
type structtype struct {
|
||||
typ _type
|
||||
fields []structfield
|
||||
typ _type
|
||||
pkgPath *string
|
||||
fields []structfield
|
||||
}
|
||||
|
||||
// name is an encoded type name with optional extra data.
|
||||
// See reflect/type.go for details.
|
||||
type name struct {
|
||||
bytes *byte
|
||||
}
|
||||
|
||||
func (n *name) data(off int) *byte {
|
||||
return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off)))
|
||||
}
|
||||
|
||||
func (n *name) isExported() bool {
|
||||
return (*n.bytes)&(1<<0) != 0
|
||||
}
|
||||
|
||||
func (n *name) nameLen() int {
|
||||
return int(uint16(*n.data(1))<<8 | uint16(*n.data(2)))
|
||||
}
|
||||
|
||||
func (n *name) tagLen() int {
|
||||
if *n.data(0)&(1<<1) == 0 {
|
||||
return 0
|
||||
}
|
||||
off := 3 + n.nameLen()
|
||||
return int(uint16(*n.data(off))<<8 | uint16(*n.data(off + 1)))
|
||||
}
|
||||
|
||||
func (n *name) name() (s string) {
|
||||
nl := n.nameLen()
|
||||
if nl == 0 {
|
||||
return ""
|
||||
}
|
||||
hdr := (*stringStruct)(unsafe.Pointer(&s))
|
||||
hdr.str = unsafe.Pointer(n.data(3))
|
||||
hdr.len = nl
|
||||
return s
|
||||
}
|
||||
|
||||
func (n *name) pkgPath() *string {
|
||||
if *n.data(0)&(1<<2) == 0 {
|
||||
return nil
|
||||
}
|
||||
off := 3 + n.nameLen()
|
||||
if tl := n.tagLen(); tl > 0 {
|
||||
off += 2 + tl
|
||||
}
|
||||
off = int(round(uintptr(off), sys.PtrSize))
|
||||
return *(**string)(unsafe.Pointer(n.data(off)))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue