Commit d4a7ea1b authored by Matthew Dempsky's avatar Matthew Dempsky

runtime: add stringStructOf helper function

Instead of open-coding conversions from *string to unsafe.Pointer then
to *stringStruct, add a helper function to add some type safety.
Bonus: This caught two **string values being converted to
*stringStruct in heapdump.go.

While here, get rid of the redundant _string type, but add in a
stringStructDWARF type used for generating DWARF debug info.

Change-Id: I8882f8cca66ac45190270f82019a5d85db023bd2
Reviewed-on: https://go-review.googlesource.com/16131
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent ef986fa3
......@@ -1187,7 +1187,7 @@ func substitutetype(structdie *DWDie, field string, dwtype *DWDie) {
}
func synthesizestringtypes(die *DWDie) {
prototype := walktypedef(defgotype(lookup_or_diag("type.runtime._string")))
prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.stringStructDWARF")))
if prototype == nil {
return
}
......
......@@ -40,8 +40,8 @@ func gogetenv(key string) string {
}
var s string
sp := (*_string)(unsafe.Pointer(&s))
sp.str = &p[0]
sp := stringStructOf(&s)
sp.str = unsafe.Pointer(&p[0])
sp.len = int(r)
return s
}
......
......@@ -48,7 +48,6 @@ func syscall_unsetenv_c(k string) {
func cstring(s string) unsafe.Pointer {
p := make([]byte, len(s)+1)
sp := (*_string)(unsafe.Pointer(&s))
memmove(unsafe.Pointer(&p[0]), unsafe.Pointer(sp.str), uintptr(len(s)))
copy(p, s)
return unsafe.Pointer(&p[0])
}
......@@ -184,7 +184,7 @@ func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
if h == nil || h.count == 0 {
return atomicloadp(unsafe.Pointer(&zeroptr))
}
key := (*stringStruct)(unsafe.Pointer(&ky))
key := stringStructOf(&ky)
if h.B == 0 {
// One-bucket table.
b := (*bmap)(h.buckets)
......@@ -286,7 +286,7 @@ func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) {
if h == nil || h.count == 0 {
return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
key := (*stringStruct)(unsafe.Pointer(&ky))
key := stringStructOf(&ky)
if h.B == 0 {
// One-bucket table.
b := (*bmap)(h.buckets)
......
......@@ -142,7 +142,7 @@ func dumpslice(b []byte) {
}
func dumpstr(s string) {
sp := (*stringStruct)(unsafe.Pointer(&s))
sp := stringStructOf(&s)
dumpmemrange(sp.str, uintptr(sp.len))
}
......@@ -183,8 +183,8 @@ func dumptype(t *_type) {
if t.x == nil || t.x.pkgpath == nil || t.x.name == nil {
dumpstr(*t._string)
} else {
pkgpath := (*stringStruct)(unsafe.Pointer(&t.x.pkgpath))
name := (*stringStruct)(unsafe.Pointer(&t.x.name))
pkgpath := stringStructOf(t.x.pkgpath)
name := stringStructOf(t.x.name)
dumpint(uint64(uintptr(pkgpath.len) + 1 + uintptr(name.len)))
dwrite(pkgpath.str, uintptr(pkgpath.len))
dwritebyte('.')
......
......@@ -12,8 +12,8 @@ type hex uint64
func bytes(s string) (ret []byte) {
rp := (*slice)(unsafe.Pointer(&ret))
sp := (*_string)(noescape(unsafe.Pointer(&s)))
rp.array = unsafe.Pointer(sp.str)
sp := stringStructOf(&s)
rp.array = sp.str
rp.len = sp.len
rp.cap = sp.len
return
......
......@@ -67,11 +67,6 @@ type note struct {
key uintptr
}
type _string struct {
str *byte
len int
}
type funcval struct {
fn uintptr
// variable-size, fn-specific data here
......
......@@ -154,6 +154,6 @@ func slicestringcopy(to []byte, fm string) int {
racewriterangepc(unsafe.Pointer(&to[0]), uintptr(n), callerpc, pc)
}
memmove(unsafe.Pointer(&to[0]), unsafe.Pointer((*stringStruct)(unsafe.Pointer(&fm)).str), uintptr(n))
memmove(unsafe.Pointer(&to[0]), unsafe.Pointer(stringStructOf(&fm).str), uintptr(n))
return n
}
......@@ -94,7 +94,7 @@ func slicebytetostring(buf *tmpBuf, b []byte) string {
// stringDataOnStack reports whether the string's data is
// stored on the current goroutine's stack.
func stringDataOnStack(s string) bool {
ptr := uintptr((*stringStruct)(unsafe.Pointer(&s)).str)
ptr := uintptr(stringStructOf(&s).str)
stk := getg().stack
return stk.lo <= ptr && ptr < stk.hi
}
......@@ -147,7 +147,7 @@ func stringtoslicebytetmp(s string) []byte {
// The only such case today is:
// for i, c := range []byte(str)
str := (*stringStruct)(unsafe.Pointer(&s))
str := stringStructOf(&s)
ret := slice{array: unsafe.Pointer(str.str), len: str.len, cap: str.len}
return *(*[]byte)(unsafe.Pointer(&ret))
}
......@@ -207,6 +207,16 @@ type stringStruct struct {
len int
}
// Variant with *byte pointer type for DWARF debugging.
type stringStructDWARF struct {
str *byte
len int
}
func stringStructOf(sp *string) *stringStruct {
return (*stringStruct)(unsafe.Pointer(sp))
}
func intstring(buf *[4]byte, v int64) string {
var s string
var b []byte
......@@ -263,8 +273,8 @@ func stringiter2(s string, k int) (int, rune) {
func rawstring(size int) (s string, b []byte) {
p := mallocgc(uintptr(size), nil, flagNoScan|flagNoZero)
(*stringStruct)(unsafe.Pointer(&s)).str = p
(*stringStruct)(unsafe.Pointer(&s)).len = size
stringStructOf(&s).str = p
stringStructOf(&s).len = size
*(*slice)(unsafe.Pointer(&b)) = slice{p, size, size}
......
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