aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/string.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-01-30 09:14:13 +0300
committerDmitry Vyukov <dvyukov@google.com>2015-02-12 08:29:53 +0000
commit9568126f350b10163155045445cb149323a2b5c8 (patch)
treec827fd80cdf26992d360ebb87a231338f9d529f2 /src/runtime/string.go
parentcdc2b0568feac1867377dddccf6eafa45cd27352 (diff)
downloadgo-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.go27
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 {