aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/string.go
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/runtime/string.go
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/runtime/string.go')
-rw-r--r--libgo/go/runtime/string.go81
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]))