diff --git a/sum64string_unsafe.go b/sum64string_unsafe.go new file mode 100644 index 0000000..ab683a6 --- /dev/null +++ b/sum64string_unsafe.go @@ -0,0 +1,11 @@ +// +build !amd64 !appengine,purego + +package xxhash + +// Forward to the version in xxhash_unsafe.go. This should be inlineable. + +// Sum64String computes the 64-bit xxHash digest of s. +// It may be faster than Sum64([]byte(s)) by avoiding a copy. +func Sum64String(s string) uint64 { + return sum64String(s) +} diff --git a/xxhash_amd64.go b/xxhash_amd64.go index ad14b80..4aa371b 100644 --- a/xxhash_amd64.go +++ b/xxhash_amd64.go @@ -9,5 +9,11 @@ package xxhash //go:noescape func Sum64(b []byte) uint64 +// Sum64String computes the 64-bit xxHash digest of s. +// It may be faster than Sum64([]byte(s)) by avoiding a copy. +// +//go:noescape +func Sum64String(s string) uint64 + //go:noescape func writeBlocks(d *Digest, b []byte) int diff --git a/xxhash_amd64.s b/xxhash_amd64.s index d580e32..15c6346 100644 --- a/xxhash_amd64.s +++ b/xxhash_amd64.s @@ -9,6 +9,7 @@ // CX pointer to advance through b // DX n // BX loop end +// DI pointer for string return value // R8 v1, k1 // R9 v2 // R10 v3 @@ -40,14 +41,26 @@ // func Sum64(b []byte) uint64 TEXT ·Sum64(SB), NOSPLIT, $0-32 + MOVQ b_base+0(FP), CX + MOVQ b_len+8(FP), DX + LEAQ ret+24(FP), DI + JMP sum64<>(SB) + +// func Sum64String(s string) uint64 +TEXT ·Sum64String(SB), NOSPLIT, $0-24 + MOVQ s_base+0(FP), CX + MOVQ s_len+8(FP), DX + LEAQ ret+16(FP), DI + JMP sum64<>(SB) + +// Takes arguments in CX, DX. Stores its return value through DI. +// All three must be set by the caller. +TEXT sum64<>(SB), NOFRAME+NOSPLIT, $0 // Load fixed primes. MOVQ ·prime1v(SB), R13 MOVQ ·prime2v(SB), R14 MOVQ ·prime4v(SB), R15 - // Load slice. - MOVQ b_base+0(FP), CX - MOVQ b_len+8(FP), DX LEAQ (CX)(DX*1), BX // The first loop limit will be len(b)-32. @@ -166,7 +179,7 @@ finalize: SHRQ $32, R12 XORQ R12, AX - MOVQ AX, ret+24(FP) + MOVQ AX, (DI) RET // writeBlocks uses the same registers as above except that it uses AX to store diff --git a/xxhash_unsafe.go b/xxhash_unsafe.go index 53bf76e..8a59c14 100644 --- a/xxhash_unsafe.go +++ b/xxhash_unsafe.go @@ -23,9 +23,7 @@ import ( // for strings to squeeze out a bit more speed. Mid-stack inlining should // eventually fix this. -// Sum64String computes the 64-bit xxHash digest of s. -// It may be faster than Sum64([]byte(s)) by avoiding a copy. -func Sum64String(s string) uint64 { +func sum64String(s string) uint64 { var b []byte bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data