]> Cypherpunks repositories - gostls13.git/commitdiff
strings: declare IndexByte as noescape
authorKeith Randall <khr@google.com>
Tue, 30 Oct 2018 17:56:02 +0000 (10:56 -0700)
committerKeith Randall <khr@golang.org>
Tue, 30 Oct 2018 20:03:54 +0000 (20:03 +0000)
This lets []byte->string conversions which are used as arguments to
strings.IndexByte and friends have their backing store allocated on
the stack.

It only prevents allocation when the string is small enough (32
bytes), so it isn't perfect. But reusing the []byte backing store
directly requires a bunch more compiler analysis (see #2205 and
related issues).

Fixes #25864.

Change-Id: Ie52430422196e3c91e5529d6e56a8435ced1fc4c
Reviewed-on: https://go-review.googlesource.com/c/146018
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/runtime/string_test.go
src/strings/strings_decl.go

index 678ff003636f987c01001d5e806635c0394ac05b..a1716fa32f2ec56a5af6ffc1497d375696b1e76f 100644 (file)
@@ -240,6 +240,34 @@ func TestCompareTempString(t *testing.T) {
        }
 }
 
+func TestStringIndexHaystack(t *testing.T) {
+       // See issue 25864.
+       haystack := []byte("hello")
+       needle := "ll"
+       n := testing.AllocsPerRun(1000, func() {
+               if strings.Index(string(haystack), needle) != 2 {
+                       t.Fatalf("needle not found")
+               }
+       })
+       if n != 0 {
+               t.Fatalf("want 0 allocs, got %v", n)
+       }
+}
+
+func TestStringIndexNeedle(t *testing.T) {
+       // See issue 25864.
+       haystack := "hello"
+       needle := []byte("ll")
+       n := testing.AllocsPerRun(1000, func() {
+               if strings.Index(haystack, string(needle)) != 2 {
+                       t.Fatalf("needle not found")
+               }
+       })
+       if n != 0 {
+               t.Fatalf("want 0 allocs, got %v", n)
+       }
+}
+
 func TestStringOnStack(t *testing.T) {
        s := ""
        for i := 0; i < 3; i++ {
index 98194445e1cfc3347b5010b9945e638a984db08c..6718c3ace4ef1fa5ca0e0223c196667db37bd831 100644 (file)
@@ -4,5 +4,7 @@
 
 package strings
 
+//go:noescape
+
 // IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s.
 func IndexByte(s string, c byte) int // in internal/bytealg