aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/bytes
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-09-24 21:46:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-09-24 21:46:21 +0000
commitdd931d9b48647e898dc80927c532ae93cc09e192 (patch)
tree71be2295cd79b8a182f6130611658db8628772d5 /libgo/go/bytes
parent779d8a5ad09b01428726ea5a0e6c87bd9ac3c0e4 (diff)
downloadgcc-dd931d9b48647e898dc80927c532ae93cc09e192.zip
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.gz
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.bz2
libgo: update to Go 1.11
Reviewed-on: https://go-review.googlesource.com/136435 gotools/: * Makefile.am (mostlyclean-local): Run chmod on check-go-dir to make sure it is writable. (check-go-tools): Likewise. (check-vet): Copy internal/objabi to check-vet-dir. * Makefile.in: Rebuild. From-SVN: r264546
Diffstat (limited to 'libgo/go/bytes')
-rw-r--r--libgo/go/bytes/buffer.go1
-rw-r--r--libgo/go/bytes/buffer_test.go33
-rw-r--r--libgo/go/bytes/bytes.go101
-rw-r--r--libgo/go/bytes/bytes_amd64.go90
-rw-r--r--libgo/go/bytes/bytes_arm64.go70
-rw-r--r--libgo/go/bytes/bytes_decl.go8
-rw-r--r--libgo/go/bytes/bytes_generic.go65
-rw-r--r--libgo/go/bytes/bytes_s390x.go88
-rw-r--r--libgo/go/bytes/bytes_test.go8
-rw-r--r--libgo/go/bytes/compare_test.go15
-rw-r--r--libgo/go/bytes/export_test.go1
11 files changed, 147 insertions, 333 deletions
diff --git a/libgo/go/bytes/buffer.go b/libgo/go/bytes/buffer.go
index dc9d5e9..a2eca2e 100644
--- a/libgo/go/bytes/buffer.go
+++ b/libgo/go/bytes/buffer.go
@@ -202,6 +202,7 @@ func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
b.lastRead = opInvalid
for {
i := b.grow(MinRead)
+ b.buf = b.buf[:i]
m, e := r.Read(b.buf[i:cap(b.buf)])
if m < 0 {
panic(errNegativeRead)
diff --git a/libgo/go/bytes/buffer_test.go b/libgo/go/bytes/buffer_test.go
index e4bbc12..acbe5ca 100644
--- a/libgo/go/bytes/buffer_test.go
+++ b/libgo/go/bytes/buffer_test.go
@@ -269,6 +269,39 @@ func TestReadFrom(t *testing.T) {
}
}
+type panicReader struct{ panic bool }
+
+func (r panicReader) Read(p []byte) (int, error) {
+ if r.panic {
+ panic(nil)
+ }
+ return 0, io.EOF
+}
+
+// Make sure that an empty Buffer remains empty when
+// it is "grown" before a Read that panics
+func TestReadFromPanicReader(t *testing.T) {
+
+ // First verify non-panic behaviour
+ var buf Buffer
+ i, err := buf.ReadFrom(panicReader{})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if i != 0 {
+ t.Fatalf("unexpected return from bytes.ReadFrom (1): got: %d, want %d", i, 0)
+ }
+ check(t, "TestReadFromPanicReader (1)", &buf, "")
+
+ // Confirm that when Reader panics, the emtpy buffer remains empty
+ var buf2 Buffer
+ defer func() {
+ recover()
+ check(t, "TestReadFromPanicReader (2)", &buf2, "")
+ }()
+ buf2.ReadFrom(panicReader{panic: true})
+}
+
func TestReadFromNegativeReader(t *testing.T) {
var b Buffer
defer func() {
diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go
index 9af177f..437a6e1 100644
--- a/libgo/go/bytes/bytes.go
+++ b/libgo/go/bytes/bytes.go
@@ -7,6 +7,7 @@
package bytes
import (
+ "internal/bytealg"
"unicode"
"unicode/utf8"
)
@@ -46,12 +47,16 @@ func explode(s []byte, n int) [][]byte {
return a[0:na]
}
-// countGeneric actually implements Count
-func countGeneric(s, sep []byte) int {
+// Count counts the number of non-overlapping instances of sep in s.
+// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
+func Count(s, sep []byte) int {
// special case
if len(sep) == 0 {
return utf8.RuneCount(s) + 1
}
+ if len(sep) == 1 {
+ return bytealg.Count(s, sep[0])
+ }
n := 0
for {
i := Index(s, sep)
@@ -800,9 +805,9 @@ func EqualFold(s, t []byte) bool {
tr, sr = sr, tr
}
// Fast check for ASCII.
- if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
- // ASCII, and sr is upper case. tr must be lower case.
- if tr == sr+'a'-'A' {
+ if tr < utf8.RuneSelf {
+ // ASCII only, sr/tr must be upper/lower case
+ if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
continue
}
return false
@@ -824,6 +829,92 @@ func EqualFold(s, t []byte) bool {
return len(s) == len(t)
}
+// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
+func Index(s, sep []byte) int {
+ n := len(sep)
+ switch {
+ case n == 0:
+ return 0
+ case n == 1:
+ return IndexByte(s, sep[0])
+ case n == len(s):
+ if Equal(sep, s) {
+ return 0
+ }
+ return -1
+ case n > len(s):
+ return -1
+ case n <= bytealg.MaxLen:
+ // Use brute force when s and sep both are small
+ if len(s) <= bytealg.MaxBruteForce {
+ return bytealg.Index(s, sep)
+ }
+ c := sep[0]
+ i := 0
+ t := s[:len(s)-n+1]
+ fails := 0
+ for i < len(t) {
+ if t[i] != c {
+ // IndexByte is faster than bytealg.Index, so use it as long as
+ // we're not getting lots of false positives.
+ o := IndexByte(t[i:], c)
+ if o < 0 {
+ return -1
+ }
+ i += o
+ }
+ if Equal(s[i:i+n], sep) {
+ return i
+ }
+ fails++
+ i++
+ // Switch to bytealg.Index when IndexByte produces too many false positives.
+ if fails > bytealg.Cutover(i) {
+ r := bytealg.Index(s[i:], sep)
+ if r >= 0 {
+ return r + i
+ }
+ return -1
+ }
+ }
+ return -1
+ }
+ c := sep[0]
+ i := 0
+ fails := 0
+ t := s[:len(s)-n+1]
+ for i < len(t) {
+ if t[i] != c {
+ o := IndexByte(t[i:], c)
+ if o < 0 {
+ break
+ }
+ i += o
+ }
+ if Equal(s[i:i+n], sep) {
+ return i
+ }
+ i++
+ fails++
+ if fails >= 4+i>>4 && i < len(t) {
+ // Give up on IndexByte, it isn't skipping ahead
+ // far enough to be better than Rabin-Karp.
+ // Experiments (using IndexPeriodic) suggest
+ // the cutover is about 16 byte skips.
+ // TODO: if large prefixes of sep are matching
+ // we should cutover at even larger average skips,
+ // because Equal becomes that much more expensive.
+ // This code does not take that effect into account.
+ j := indexRabinKarp(s[i:], sep)
+ if j < 0 {
+ return -1
+ }
+ return i + j
+ }
+ }
+ return -1
+}
+
func indexRabinKarp(s, sep []byte) int {
// Rabin-Karp search
hashsep, pow := hashStr(sep)
diff --git a/libgo/go/bytes/bytes_amd64.go b/libgo/go/bytes/bytes_amd64.go
deleted file mode 100644
index 2fbbbb0..0000000
--- a/libgo/go/bytes/bytes_amd64.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package bytes
-
-import "internal/cpu"
-
-//go:noescape
-
-// indexShortStr returns the index of the first instance of c in s, or -1 if c is not present in s.
-// indexShortStr requires 2 <= len(c) <= shortStringLen
-func indexShortStr(s, c []byte) int // ../runtime/asm_amd64.s
-func countByte(s []byte, c byte) int // ../runtime/asm_amd64.s
-
-var shortStringLen int
-
-func init() {
- if cpu.X86.HasAVX2 {
- shortStringLen = 63
- } else {
- shortStringLen = 31
- }
-}
-
-// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
-func Index(s, sep []byte) int {
- n := len(sep)
- switch {
- case n == 0:
- return 0
- case n == 1:
- return IndexByte(s, sep[0])
- case n == len(s):
- if Equal(sep, s) {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- case n <= shortStringLen:
- // Use brute force when s and sep both are small
- if len(s) <= 64 {
- return indexShortStr(s, sep)
- }
- c := sep[0]
- i := 0
- t := s[:len(s)-n+1]
- fails := 0
- for i < len(t) {
- if t[i] != c {
- // IndexByte skips 16/32 bytes per iteration,
- // so it's faster than indexShortStr.
- o := IndexByte(t[i:], c)
- if o < 0 {
- return -1
- }
- i += o
- }
- if Equal(s[i:i+n], sep) {
- return i
- }
- fails++
- i++
- // Switch to indexShortStr when IndexByte produces too many false positives.
- // Too many means more that 1 error per 8 characters.
- // Allow some errors in the beginning.
- if fails > (i+16)/8 {
- r := indexShortStr(s[i:], sep)
- if r >= 0 {
- return r + i
- }
- return -1
- }
- }
- return -1
- }
- return indexRabinKarp(s, sep)
-}
-
-// Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
-func Count(s, sep []byte) int {
- if len(sep) == 1 && cpu.X86.HasPOPCNT {
- return countByte(s, sep[0])
- }
- return countGeneric(s, sep)
-}
diff --git a/libgo/go/bytes/bytes_arm64.go b/libgo/go/bytes/bytes_arm64.go
deleted file mode 100644
index 1213b06..0000000
--- a/libgo/go/bytes/bytes_arm64.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package bytes
-
-func countByte(s []byte, c byte) int // bytes_arm64.s
-
-// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
-func Index(s, sep []byte) int {
- n := len(sep)
- switch {
- case n == 0:
- return 0
- case n == 1:
- return IndexByte(s, sep[0])
- case n == len(s):
- if Equal(sep, s) {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- }
- c := sep[0]
- i := 0
- fails := 0
- t := s[:len(s)-n+1]
- for i < len(t) {
- if t[i] != c {
- o := IndexByte(t[i:], c)
- if o < 0 {
- break
- }
- i += o
- }
- if Equal(s[i:i+n], sep) {
- return i
- }
- i++
- fails++
- if fails >= 4+i>>4 && i < len(t) {
- // Give up on IndexByte, it isn't skipping ahead
- // far enough to be better than Rabin-Karp.
- // Experiments (using IndexPeriodic) suggest
- // the cutover is about 16 byte skips.
- // TODO: if large prefixes of sep are matching
- // we should cutover at even larger average skips,
- // because Equal becomes that much more expensive.
- // This code does not take that effect into account.
- j := indexRabinKarp(s[i:], sep)
- if j < 0 {
- return -1
- }
- return i + j
- }
- }
- return -1
-}
-
-// Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
-func Count(s, sep []byte) int {
- if len(sep) == 1 {
- return countByte(s, sep[0])
- }
- return countGeneric(s, sep)
-}
diff --git a/libgo/go/bytes/bytes_decl.go b/libgo/go/bytes/bytes_decl.go
index df0614f..af0f8b1 100644
--- a/libgo/go/bytes/bytes_decl.go
+++ b/libgo/go/bytes/bytes_decl.go
@@ -6,19 +6,19 @@ package bytes
//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 []byte, c byte) int // ../runtime/asm_$GOARCH.s
+// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
+func IndexByte(b []byte, c byte) int // in internal/bytealg
//go:noescape
// Equal returns a boolean reporting whether a and b
// are the same length and contain the same bytes.
// A nil argument is equivalent to an empty slice.
-func Equal(a, b []byte) bool // ../runtime/asm_$GOARCH.s
+func Equal(a, b []byte) bool // in internal/bytealg
//go:noescape
// Compare returns an integer comparing two byte slices lexicographically.
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
// A nil argument is equivalent to an empty slice.
-func Compare(a, b []byte) int // ../runtime/noasm.go or ../runtime/asm_{386,amd64}.s
+func Compare(a, b []byte) int // in internal/bytealg
diff --git a/libgo/go/bytes/bytes_generic.go b/libgo/go/bytes/bytes_generic.go
deleted file mode 100644
index b52d939..0000000
--- a/libgo/go/bytes/bytes_generic.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// -build !amd64,!s390x,!arm64
-
-package bytes
-
-// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
-func Index(s, sep []byte) int {
- n := len(sep)
- switch {
- case n == 0:
- return 0
- case n == 1:
- return IndexByte(s, sep[0])
- case n == len(s):
- if Equal(sep, s) {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- }
- c := sep[0]
- i := 0
- fails := 0
- t := s[:len(s)-n+1]
- for i < len(t) {
- if t[i] != c {
- o := IndexByte(t[i:], c)
- if o < 0 {
- break
- }
- i += o
- }
- if Equal(s[i:i+n], sep) {
- return i
- }
- i++
- fails++
- if fails >= 4+i>>4 && i < len(t) {
- // Give up on IndexByte, it isn't skipping ahead
- // far enough to be better than Rabin-Karp.
- // Experiments (using IndexPeriodic) suggest
- // the cutover is about 16 byte skips.
- // TODO: if large prefixes of sep are matching
- // we should cutover at even larger average skips,
- // because Equal becomes that much more expensive.
- // This code does not take that effect into account.
- j := indexRabinKarp(s[i:], sep)
- if j < 0 {
- return -1
- }
- return i + j
- }
- }
- return -1
-}
-
-// Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
-func Count(s, sep []byte) int {
- return countGeneric(s, sep)
-}
diff --git a/libgo/go/bytes/bytes_s390x.go b/libgo/go/bytes/bytes_s390x.go
deleted file mode 100644
index 0c22848..0000000
--- a/libgo/go/bytes/bytes_s390x.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package bytes
-
-//go:noescape
-
-// indexShortStr returns the index of the first instance of sep in s,
-// or -1 if sep is not present in s.
-// indexShortStr requires 2 <= len(sep) <= shortStringLen
-func indexShortStr(s, c []byte) int // ../runtime/asm_s390x.s
-
-// supportsVX reports whether the vector facility is available.
-// indexShortStr must not be called if the vector facility is not
-// available.
-func supportsVX() bool // ../runtime/asm_s390x.s
-
-var shortStringLen = -1
-
-func init() {
- if supportsVX() {
- shortStringLen = 64
- }
-}
-
-// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
-func Index(s, sep []byte) int {
- n := len(sep)
- switch {
- case n == 0:
- return 0
- case n == 1:
- return IndexByte(s, sep[0])
- case n == len(s):
- if Equal(sep, s) {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- case n <= shortStringLen:
- // Use brute force when s and sep both are small
- if len(s) <= 64 {
- return indexShortStr(s, sep)
- }
- c := sep[0]
- i := 0
- t := s[:len(s)-n+1]
- fails := 0
- for i < len(t) {
- if t[i] != c {
- // IndexByte skips 16/32 bytes per iteration,
- // so it's faster than indexShortStr.
- o := IndexByte(t[i:], c)
- if o < 0 {
- return -1
- }
- i += o
- }
- if Equal(s[i:i+n], sep) {
- return i
- }
- fails++
- i++
- // Switch to indexShortStr when IndexByte produces too many false positives.
- // Too many means more that 1 error per 8 characters.
- // Allow some errors in the beginning.
- if fails > (i+16)/8 {
- r := indexShortStr(s[i:], sep)
- if r >= 0 {
- return r + i
- }
- return -1
- }
- }
- return -1
- }
- return indexRabinKarp(s, sep)
-}
-
-// Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
-func Count(s, sep []byte) int {
- return countGeneric(s, sep)
-}
diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go
index 23fce29..11c5ef9 100644
--- a/libgo/go/bytes/bytes_test.go
+++ b/libgo/go/bytes/bytes_test.go
@@ -415,10 +415,6 @@ func TestCountByte(t *testing.T) {
if p != j+1 {
t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p)
}
- pGeneric := CountGeneric(b[i:i+window], []byte{100})
- if pGeneric != j+1 {
- t.Errorf("TestCountByte.CountGeneric(%q, 100) = %d", b[i:i+window], p)
- }
}
}
@@ -466,10 +462,6 @@ func TestCountByteNoMatch(t *testing.T) {
if p != 0 {
t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p)
}
- pGeneric := CountGeneric(b[i:i+window], []byte{0})
- if pGeneric != 0 {
- t.Errorf("TestCountByteNoMatch.CountGeneric(%q, 100) = %d", b[i:i+window], p)
- }
for j := 0; j < window; j++ {
b[i+j] = byte(0)
}
diff --git a/libgo/go/bytes/compare_test.go b/libgo/go/bytes/compare_test.go
index 35088a1..3e33c27 100644
--- a/libgo/go/bytes/compare_test.go
+++ b/libgo/go/bytes/compare_test.go
@@ -6,6 +6,7 @@ package bytes_test
import (
. "bytes"
+ "internal/testenv"
"testing"
)
@@ -58,10 +59,20 @@ func TestCompareIdenticalSlice(t *testing.T) {
}
func TestCompareBytes(t *testing.T) {
- n := 128
+ lengths := make([]int, 0) // lengths to test in ascending order
+ for i := 0; i <= 128; i++ {
+ lengths = append(lengths, i)
+ }
+ lengths = append(lengths, 256, 512, 1024, 1333, 4095, 4096, 4097)
+
+ if !testing.Short() || testenv.Builder() != "" {
+ lengths = append(lengths, 65535, 65536, 65537, 99999)
+ }
+
+ n := lengths[len(lengths)-1]
a := make([]byte, n+1)
b := make([]byte, n+1)
- for len := 0; len < 128; len++ {
+ for _, len := range lengths {
// randomish but deterministic data. No 0 or 255.
for i := 0; i < len; i++ {
a[i] = byte(1 + 31*i%254)
diff --git a/libgo/go/bytes/export_test.go b/libgo/go/bytes/export_test.go
index 823c8b0..f61523e 100644
--- a/libgo/go/bytes/export_test.go
+++ b/libgo/go/bytes/export_test.go
@@ -7,4 +7,3 @@ package bytes
// Export func for testing
var IndexBytePortable = indexBytePortable
var EqualPortable = equalPortable
-var CountGeneric = countGeneric