diff options
author | Ian Lance Taylor <iant@golang.org> | 2018-09-24 21:46:21 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-09-24 21:46:21 +0000 |
commit | dd931d9b48647e898dc80927c532ae93cc09e192 (patch) | |
tree | 71be2295cd79b8a182f6130611658db8628772d5 /libgo/go/runtime/string.go | |
parent | 779d8a5ad09b01428726ea5a0e6c87bd9ac3c0e4 (diff) | |
download | gcc-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/runtime/string.go')
-rw-r--r-- | libgo/go/runtime/string.go | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/libgo/go/runtime/string.go b/libgo/go/runtime/string.go index e8df9a6..5296ebd 100644 --- a/libgo/go/runtime/string.go +++ b/libgo/go/runtime/string.go @@ -4,7 +4,10 @@ package runtime -import "unsafe" +import ( + "internal/bytealg" + "unsafe" +) // For gccgo, use go:linkname to rename compiler-called functions to // themselves, so that the compiler will export them. @@ -105,6 +108,11 @@ func slicebytetostring(buf *tmpBuf, b []byte) (str string) { if msanenabled { msanread(unsafe.Pointer(&b[0]), uintptr(l)) } + if l == 1 { + stringStructOf(&str).str = unsafe.Pointer(&staticbytes[b[0]]) + stringStructOf(&str).len = 1 + return + } var p unsafe.Pointer if buf != nil && len(b) <= len(buf) { @@ -232,8 +240,13 @@ func stringStructOf(sp *string) *stringStruct { return (*stringStruct)(unsafe.Pointer(sp)) } -func intstring(buf *[4]byte, v int64) string { - var s string +func intstring(buf *[4]byte, v int64) (s string) { + if v >= 0 && v < runeSelf { + stringStructOf(&s).str = unsafe.Pointer(&staticbytes[v]) + stringStructOf(&s).len = 1 + return + } + var b []byte if buf != nil { b = buf[:] @@ -277,7 +290,7 @@ func rawbyteslice(size int) (b []byte) { // rawruneslice allocates a new rune slice. The rune slice is not zeroed. func rawruneslice(size int) (b []rune) { - if uintptr(size) > _MaxMem/4 { + if uintptr(size) > maxAlloc/4 { throw("out of memory") } mem := roundupsize(uintptr(size) * 4) @@ -291,13 +304,20 @@ func rawruneslice(size int) (b []rune) { } // used by cmd/cgo -func gobytes(p *byte, n int) []byte { +func gobytes(p *byte, n int) (b []byte) { if n == 0 { return make([]byte, 0) } - x := make([]byte, n) - memmove(unsafe.Pointer(&x[0]), unsafe.Pointer(p), uintptr(n)) - return x + + if n < 0 || uintptr(n) > maxAlloc { + panic(errorString("gobytes: length out of range")) + } + + bp := mallocgc(uintptr(n), nil, false) + memmove(bp, unsafe.Pointer(p), uintptr(n)) + + *(*slice)(unsafe.Pointer(&b)) = slice{bp, n, n} + return } func gostring(p *byte) string { @@ -406,19 +426,50 @@ func findnull(s *byte) int { if s == nil { return 0 } - p := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s)) - l := 0 - for p[l] != 0 { - l++ + + // Avoid IndexByteString on Plan 9 because it uses SSE instructions + // on x86 machines, and those are classified as floating point instructions, + // which are illegal in a note handler. + if GOOS == "plan9" { + p := (*[maxAlloc/2 - 1]byte)(unsafe.Pointer(s)) + l := 0 + for p[l] != 0 { + l++ + } + return l + } + + // pageSize is the unit we scan at a time looking for NULL. + // It must be the minimum page size for any architecture Go + // runs on. It's okay (just a minor performance loss) if the + // actual system page size is larger than this value. + const pageSize = 4096 + + offset := 0 + ptr := unsafe.Pointer(s) + // IndexByteString uses wide reads, so we need to be careful + // with page boundaries. Call IndexByteString on + // [ptr, endOfPage) interval. + safeLen := int(pageSize - uintptr(ptr)%pageSize) + + for { + t := *(*string)(unsafe.Pointer(&stringStruct{ptr, safeLen})) + // Check one page at a time. + if i := bytealg.IndexByteString(t, 0); i != -1 { + return offset + i + } + // Move to next page + ptr = unsafe.Pointer(uintptr(ptr) + uintptr(safeLen)) + offset += safeLen + safeLen = pageSize } - return l } func findnullw(s *uint16) int { if s == nil { return 0 } - p := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(s)) + p := (*[maxAlloc/2/2 - 1]uint16)(unsafe.Pointer(s)) l := 0 for p[l] != 0 { l++ @@ -435,7 +486,7 @@ func gostringnocopy(str *byte) string { func gostringw(strw *uint16) string { var buf [8]byte - str := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(strw)) + str := (*[maxAlloc/2/2 - 1]uint16)(unsafe.Pointer(strw)) n1 := 0 for i := 0; str[i] != 0; i++ { n1 += encoderune(buf[:], rune(str[i])) |