diff options
Diffstat (limited to 'libgo/go/runtime/string.go')
-rw-r--r-- | libgo/go/runtime/string.go | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/libgo/go/runtime/string.go b/libgo/go/runtime/string.go index df4cae7..c0058be 100644 --- a/libgo/go/runtime/string.go +++ b/libgo/go/runtime/string.go @@ -6,6 +6,7 @@ package runtime import ( "internal/bytealg" + "runtime/internal/sys" "unsafe" ) @@ -70,47 +71,54 @@ func concatstrings(buf *tmpBuf, p *string, n int) string { return s } +// slicebytetostring converts a byte slice to a string. +// It is inserted by the compiler into generated code. +// ptr is a pointer to the first element of the slice; +// n is the length of the slice. // Buf is a fixed-size buffer for the result, // it is not nil if the result does not escape. -func slicebytetostring(buf *tmpBuf, b []byte) (str string) { - l := len(b) - if l == 0 { +func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) { + if n == 0 { // Turns out to be a relatively common case. // Consider that you want to parse out data between parens in "foo()bar", // you find the indices and convert the subslice to string. return "" } if raceenabled { - racereadrangepc(unsafe.Pointer(&b[0]), - uintptr(l), + racereadrangepc(unsafe.Pointer(ptr), + uintptr(n), getcallerpc(), funcPC(slicebytetostring)) } if msanenabled { - msanread(unsafe.Pointer(&b[0]), uintptr(l)) + msanread(unsafe.Pointer(ptr), uintptr(n)) } - if l == 1 { - stringStructOf(&str).str = unsafe.Pointer(&staticbytes[b[0]]) + if n == 1 { + p := unsafe.Pointer(&staticuint64s[*ptr]) + if sys.BigEndian { + p = add(p, 7) + } + stringStructOf(&str).str = p stringStructOf(&str).len = 1 return } var p unsafe.Pointer - if buf != nil && len(b) <= len(buf) { + if buf != nil && n <= len(buf) { p = unsafe.Pointer(buf) } else { - p = mallocgc(uintptr(len(b)), nil, false) + p = mallocgc(uintptr(n), nil, false) } stringStructOf(&str).str = p - stringStructOf(&str).len = len(b) - memmove(p, (*(*slice)(unsafe.Pointer(&b))).array, uintptr(len(b))) + stringStructOf(&str).len = n + memmove(p, unsafe.Pointer(ptr), uintptr(n)) return } func rawstringtmp(buf *tmpBuf, l int) (s string, b []byte) { if buf != nil && l <= len(buf) { b = buf[:l] - s = slicebytetostringtmp(b) + s = slicebytetostringtmp(&b[0], len(b)) } else { s, b = rawstring(l) } @@ -131,17 +139,19 @@ func rawstringtmp(buf *tmpBuf, l int) (s string, b []byte) { // where k is []byte, T1 to Tn is a nesting of struct and array literals. // - Used for "<"+string(b)+">" concatenation where b is []byte. // - Used for string(b)=="foo" comparison where b is []byte. -func slicebytetostringtmp(b []byte) string { - if raceenabled && len(b) > 0 { - racereadrangepc(unsafe.Pointer(&b[0]), - uintptr(len(b)), +func slicebytetostringtmp(ptr *byte, n int) (str string) { + if raceenabled && n > 0 { + racereadrangepc(unsafe.Pointer(ptr), + uintptr(n), getcallerpc(), funcPC(slicebytetostringtmp)) } - if msanenabled && len(b) > 0 { - msanread(unsafe.Pointer(&b[0]), uintptr(len(b))) + if msanenabled && n > 0 { + msanread(unsafe.Pointer(ptr), uintptr(n)) } - return *(*string)(unsafe.Pointer(&b)) + stringStructOf(&str).str = unsafe.Pointer(ptr) + stringStructOf(&str).len = n + return } func stringtoslicebyte(buf *tmpBuf, s string) []byte { @@ -223,16 +233,10 @@ func stringStructOf(sp *string) *stringStruct { } 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[:] - s = slicebytetostringtmp(b) + s = slicebytetostringtmp(&b[0], len(b)) } else { s, b = rawstring(4) } |