diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2015-01-30 09:14:13 +0300 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2015-02-12 08:29:53 +0000 |
| commit | 9568126f350b10163155045445cb149323a2b5c8 (patch) | |
| tree | c827fd80cdf26992d360ebb87a231338f9d529f2 /src/runtime/string.go | |
| parent | cdc2b0568feac1867377dddccf6eafa45cd27352 (diff) | |
| download | go-9568126f350b10163155045445cb149323a2b5c8.tar.xz | |
cmd/gc: allocate buffers for non-escaping string conversions on stack
Support the following conversions in escape analysis:
[]rune("foo")
[]byte("foo")
string([]rune{})
If the result does not escape, allocate temp buffer on stack
and pass it to runtime functions.
Change-Id: I1d075907eab8b0109ad7ad1878104b02b3d5c690
Reviewed-on: https://go-review.googlesource.com/3590
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime/string.go')
| -rw-r--r-- | src/runtime/string.go | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/runtime/string.go b/src/runtime/string.go index 46c3502f77..0ba309cf02 100644 --- a/src/runtime/string.go +++ b/src/runtime/string.go @@ -129,8 +129,13 @@ func slicebytetostringtmp(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } -func stringtoslicebyte(s string) []byte { - b := rawbyteslice(len(s)) +func stringtoslicebyte(buf *tmpBuf, s string) []byte { + var b []byte + if buf != nil && len(s) <= len(buf) { + b = buf[:len(s)] + } else { + b = rawbyteslice(len(s)) + } copy(b, s) return b } @@ -147,7 +152,7 @@ func stringtoslicebytetmp(s string) []byte { return *(*[]byte)(unsafe.Pointer(&ret)) } -func stringtoslicerune(s string) []rune { +func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune { // two passes. // unlike slicerunetostring, no race because strings are immutable. n := 0 @@ -157,7 +162,12 @@ func stringtoslicerune(s string) []rune { s = s[k:] n++ } - a := rawruneslice(n) + var a []rune + if buf != nil && n <= len(buf) { + a = buf[:n] + } else { + a = rawruneslice(n) + } n = 0 for len(t) > 0 { r, k := charntorune(t) @@ -168,7 +178,7 @@ func stringtoslicerune(s string) []rune { return a } -func slicerunetostring(a []rune) string { +func slicerunetostring(buf *tmpBuf, a []rune) string { if raceenabled && len(a) > 0 { racereadrangepc(unsafe.Pointer(&a[0]), uintptr(len(a))*unsafe.Sizeof(a[0]), @@ -180,7 +190,7 @@ func slicerunetostring(a []rune) string { for _, r := range a { size1 += runetochar(dum[:], r) } - s, b := rawstring(size1 + 3) + s, b := rawstringtmp(buf, size1+3) size2 := 0 for _, r := range a { // check for race @@ -309,11 +319,6 @@ func gobytes(p *byte, n int) []byte { return x } -func gostringsize(n int) string { - s, _ := rawstring(n) - return s -} - func gostring(p *byte) string { l := findnull(p) if l == 0 { |
