]> Cypherpunks repositories - gostls13.git/commitdiff
bytes, internal/bytealg: simplify Equal
authorJosh Bleecher Snyder <josharian@gmail.com>
Mon, 22 Apr 2019 21:39:55 +0000 (14:39 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 24 Apr 2019 00:56:36 +0000 (00:56 +0000)
The compiler has advanced enough that it is cheaper
to convert to strings than to go through the assembly
trampolines to call runtime.memequal.

Simplify Equal accordingly, and cull dead code from bytealg.

While we're here, simplify Equal's documentation.

Fixes #31587

Change-Id: Ie721d33f9a6cbd86b1d873398b20e7882c2c63e9
Reviewed-on: https://go-review.googlesource.com/c/go/+/173323
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
16 files changed:
src/bytes/bytes.go
src/bytes/bytes_test.go
src/bytes/export_test.go
src/cmd/vet/all/whitelist/arm.txt
src/internal/bytealg/equal_386.s
src/internal/bytealg/equal_amd64.s
src/internal/bytealg/equal_amd64p32.s
src/internal/bytealg/equal_arm.s
src/internal/bytealg/equal_arm64.s
src/internal/bytealg/equal_generic.go [new file with mode: 0644]
src/internal/bytealg/equal_mips64x.s
src/internal/bytealg/equal_mipsx.s
src/internal/bytealg/equal_native.go
src/internal/bytealg/equal_ppc64x.s
src/internal/bytealg/equal_s390x.s
src/internal/bytealg/equal_wasm.s

index 22aeded5e134a0af2c5091a0b33fd75a86e223fd..9d586581f5cc55daa3899adee62512cb089d8794 100644 (file)
@@ -12,23 +12,12 @@ import (
        "unicode/utf8"
 )
 
-// Equal returns a boolean reporting whether a and b
+// Equal reports 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 {
-       return bytealg.Equal(a, b)
-}
-
-func equalPortable(a, b []byte) bool {
-       if len(a) != len(b) {
-               return false
-       }
-       for i, c := range a {
-               if c != b[i] {
-                       return false
-               }
-       }
-       return true
+       // Neither cmd/compile nor gccgo allocates for these string conversions.
+       return string(a) == string(b)
 }
 
 // Compare returns an integer comparing two byte slices lexicographically.
index 340810facf4056b38385d2eb380df83af0c30523..4c50755e7c264d5c9f975e7d84433d2eb5cca7bb 100644 (file)
@@ -51,15 +51,17 @@ type BinOpTest struct {
 }
 
 func TestEqual(t *testing.T) {
-       for _, tt := range compareTests {
-               eql := Equal(tt.a, tt.b)
-               if eql != (tt.i == 0) {
-                       t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql)
-               }
-               eql = EqualPortable(tt.a, tt.b)
-               if eql != (tt.i == 0) {
-                       t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql)
+       // Run the tests and check for allocation at the same time.
+       allocs := testing.AllocsPerRun(10, func() {
+               for _, tt := range compareTests {
+                       eql := Equal(tt.a, tt.b)
+                       if eql != (tt.i == 0) {
+                               t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql)
+                       }
                }
+       })
+       if allocs > 0 {
+               t.Errorf("Equal allocated %v times", allocs)
        }
 }
 
@@ -572,11 +574,6 @@ func BenchmarkEqual(b *testing.B) {
        benchBytes(b, sizes, bmEqual(Equal))
 }
 
-func BenchmarkEqualPort(b *testing.B) {
-       sizes := []int{1, 6, 32, 4 << 10, 4 << 20, 64 << 20}
-       benchBytes(b, sizes, bmEqual(EqualPortable))
-}
-
 func bmEqual(equal func([]byte, []byte) bool) func(b *testing.B, n int) {
        return func(b *testing.B, n int) {
                if len(bmbuf) < 2*n {
index f61523e60bbb3fd209594912ebcaa76cde9acd20..b65428d9ce84894e05ecd063fa2a53b803a2c9f8 100644 (file)
@@ -6,4 +6,3 @@ package bytes
 
 // Export func for testing
 var IndexBytePortable = indexBytePortable
-var EqualPortable = equalPortable
index abcb38b003b6ebe707d8ccf8809868142129dd74..81a1f1831ea8f3f37a592da3e8a8a57ef3b0c52d 100644 (file)
@@ -12,4 +12,3 @@ runtime/tls_arm.s: [arm] load_g: function load_g missing Go declaration
 runtime/tls_arm.s: [arm] _initcgo: function _initcgo missing Go declaration
 
 runtime/internal/atomic/asm_arm.s: [arm] cas: function cas missing Go declaration
-internal/bytealg/equal_arm.s: [arm] Equal: invalid MOVW of ret+24(FP); bool is 1-byte value
index ad7da0ea8b3a6e1806f2f0268b0dccb69c403094..87233635a927d35cd6018fa692f3081317575eca 100644 (file)
@@ -5,24 +5,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB),NOSPLIT,$0-25
-       MOVL    a_len+4(FP), BX
-       MOVL    b_len+16(FP), CX
-       CMPL    BX, CX
-       JNE     neq
-       MOVL    a_base+0(FP), SI
-       MOVL    b_base+12(FP), DI
-       CMPL    SI, DI
-       JEQ     eq
-       LEAL    ret+24(FP), AX
-       JMP     memeqbody<>(SB)
-neq:
-       MOVB    $0, ret+24(FP)
-       RET
-eq:
-       MOVB    $1, ret+24(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT,$0-13
        MOVL    a+0(FP), SI
index fa82589644512a8f106b381af24fd5f6abbe80e1..c8164095450ee0296c944f17435715f599450198 100644 (file)
@@ -5,24 +5,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB),NOSPLIT,$0-49
-       MOVQ    a_len+8(FP), BX
-       MOVQ    b_len+32(FP), CX
-       CMPQ    BX, CX
-       JNE     neq
-       MOVQ    a_base+0(FP), SI
-       MOVQ    b_base+24(FP), DI
-       CMPQ    SI, DI
-       JEQ     eq
-       LEAQ    ret+48(FP), AX
-       JMP     memeqbody<>(SB)
-neq:
-       MOVB    $0, ret+48(FP)
-       RET
-eq:
-       MOVB    $1, ret+48(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT,$0-25
        MOVQ    a+0(FP), SI
index 00d5c0afcc6a1486cb259214431c4a958606cbf2..cd369c673128e78df27cce818bd653eb2e172384 100644 (file)
@@ -5,25 +5,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB),NOSPLIT,$0-25
-       MOVL    a_len+4(FP), BX
-       MOVL    b_len+16(FP), CX
-       CMPL    BX, CX
-       JNE     neq
-       MOVL    a_base+0(FP), SI
-       MOVL    b_base+12(FP), DI
-       CMPL    SI, DI
-       JEQ     eq
-       CALL    memeqbody<>(SB)
-       MOVB    AX, ret+24(FP)
-       RET
-neq:
-       MOVB    $0, ret+24(FP)
-       RET
-eq:
-       MOVB    $1, ret+24(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT,$0-17
        MOVL    a+0(FP), SI
index b8f2b69bbe5b686eea850cb40439d9f3d7926b29..a6c4369603484539402cc692ab0e8635f02165ee 100644 (file)
@@ -5,27 +5,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB),NOSPLIT,$0-25
-       MOVW    a_len+4(FP), R1
-       MOVW    b_len+16(FP), R3
-       CMP     R1, R3          // unequal lengths are not equal
-       B.NE    notequal
-       CMP     $0, R1          // short path to handle 0-byte case
-       B.EQ    equal
-
-       MOVW    a_base+0(FP), R0
-       MOVW    b_base+12(FP), R2
-       MOVW    $ret+24(FP), R7
-       B       memeqbody<>(SB)
-equal:
-       MOVW    $1, R0
-       MOVB    R0, ret+24(FP)
-       RET
-notequal:
-       MOVW    $0, R0
-       MOVBU   R0, ret+24(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-13
        MOVW    a+0(FP), R0
index 2c6af01e0ae2f53fd6d96bae84a57332d7382415..01aa7b7b7aa8adbc0f1945a072e6c2a576c082fc 100644 (file)
@@ -5,26 +5,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB),NOSPLIT,$0-49
-       MOVD    a_len+8(FP), R1
-       MOVD    b_len+32(FP), R3
-       CMP     R1, R3
-       // unequal lengths are not equal
-       BNE     not_equal
-       // short path to handle 0-byte case
-       CBZ     R1, equal
-       MOVD    a_base+0(FP), R0
-       MOVD    b_base+24(FP), R2
-       MOVD    $ret+48(FP), R8
-       B       memeqbody<>(SB)
-equal:
-       MOVD    $1, R0
-       MOVB    R0, ret+48(FP)
-       RET
-not_equal:
-       MOVB    ZR, ret+48(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
        MOVD    size+16(FP), R1
diff --git a/src/internal/bytealg/equal_generic.go b/src/internal/bytealg/equal_generic.go
new file mode 100644 (file)
index 0000000..59bdf8f
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2019 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.
+
+package bytealg
+
+// Equal reports whether a and b
+// are the same length and contain the same bytes.
+// A nil argument is equivalent to an empty slice.
+//
+// Equal is equivalent to bytes.Equal.
+// It is provided here for convenience,
+// because some packages cannot depend on bytes.
+func Equal(a, b []byte) bool {
+       // Neither cmd/compile nor gccgo allocates for these string conversions.
+       // There is a test for this in package bytes.
+       return string(a) == string(b)
+}
index a75b957e8b50ee2747544415ada82e219673ae86..58dc4303b4844641ac85a8edb44b6d51c927592f 100644 (file)
@@ -9,32 +9,6 @@
 
 #define        REGCTXT R22
 
-TEXT ·Equal(SB),NOSPLIT,$0-49
-       MOVV    a_len+8(FP), R3
-       MOVV    b_len+32(FP), R4
-       BNE     R3, R4, noteq           // unequal lengths are not equal
-
-       MOVV    a_base+0(FP), R1
-       MOVV    b_base+24(FP), R2
-       ADDV    R1, R3          // end
-
-loop:
-       BEQ     R1, R3, equal           // reached the end
-       MOVBU   (R1), R6
-       ADDV    $1, R1
-       MOVBU   (R2), R7
-       ADDV    $1, R2
-       BEQ     R6, R7, loop
-
-noteq:
-       MOVB    R0, ret+48(FP)
-       RET
-
-equal:
-       MOVV    $1, R1
-       MOVB    R1, ret+48(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
        MOVV    a+0(FP), R1
index 70d579d5d434eadb178576ac688eb730f232eea4..1cabc70178be09fb30fe8cf842bc802bc9dbc23e 100644 (file)
@@ -9,32 +9,6 @@
 
 #define        REGCTXT R22
 
-TEXT ·Equal(SB),NOSPLIT,$0-25
-       MOVW    a_len+4(FP), R3
-       MOVW    b_len+16(FP), R4
-       BNE     R3, R4, noteq   // unequal lengths are not equal
-
-       MOVW    a_base+0(FP), R1
-       MOVW    b_base+12(FP), R2
-       ADDU    R1, R3  // end
-
-loop:
-       BEQ     R1, R3, equal   // reached the end
-       MOVBU   (R1), R6
-       ADDU    $1, R1
-       MOVBU   (R2), R7
-       ADDU    $1, R2
-       BEQ     R6, R7, loop
-
-noteq:
-       MOVB    R0, ret+24(FP)
-       RET
-
-equal:
-       MOVW    $1, R1
-       MOVB    R1, ret+24(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT,$0-13
        MOVW    a+0(FP), R1
index 995f0749d441992b479331250b5babddd975eda2..cf3a245bc053b185574405c9eb40e3091d9f70f8 100644 (file)
@@ -6,11 +6,6 @@ package bytealg
 
 import "unsafe"
 
-// Note: there's no equal_generic.go because every platform must implement at least memequal_varlen in assembly.
-
-//go:noescape
-func Equal(a, b []byte) bool
-
 // The declarations below generate ABI wrappers for functions
 // implemented in assembly in this package but declared in another
 // package.
index 74ea34834dc4e7f1608a3eef3c66faec8962ed6a..18171eaedc9474fa5d59f211a5876022b8a08151 100644 (file)
@@ -7,25 +7,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB),NOSPLIT|NOFRAME,$0-49
-       MOVD    a_len+8(FP), R4
-       MOVD    b_len+32(FP), R5
-       CMP     R5, R4          // unequal lengths are not equal
-       BNE     noteq
-       MOVD    a_base+0(FP), R3
-       MOVD    b_base+24(FP), R4
-       MOVD    $ret+48(FP), R10
-       BR      memeqbody<>(SB)
-
-noteq:
-       MOVBZ   $0,ret+48(FP)
-       RET
-
-equal:
-       MOVD    $1,R3
-       MOVBZ   R3,ret+48(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
        MOVD    a+0(FP), R3
index d7724747d4b765dcea5e722732f451b9f4a19741..67f814dfc1c674ce7d222b93fdd8ce252eea08ae 100644 (file)
@@ -5,18 +5,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB),NOSPLIT|NOFRAME,$0-49
-       MOVD    a_len+8(FP), R2
-       MOVD    b_len+32(FP), R6
-       MOVD    a_base+0(FP), R3
-       MOVD    b_base+24(FP), R5
-       LA      ret+48(FP), R7
-       CMPBNE  R2, R6, notequal
-       BR      memeqbody<>(SB)
-notequal:
-       MOVB    $0, ret+48(FP)
-       RET
-
 // memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
        MOVD    a+0(FP), R3
index cac3fb2d13702c0de18c5eb2c5d16a19bf18eeed..a2b76c13681589708b4aae7a94aaf8956f323c82 100644 (file)
@@ -5,26 +5,6 @@
 #include "go_asm.h"
 #include "textflag.h"
 
-TEXT ·Equal(SB), NOSPLIT, $0-49
-       MOVD a_len+8(FP), R0
-       MOVD b_len+32(FP), R1
-       Get R0
-       Get R1
-       I64Eq
-       If
-               Get SP
-               I64Load a+0(FP)
-               I64Load b+24(FP)
-               Get R0
-               Call memeqbody<>(SB)
-               I64Store8 ret+48(FP)
-       Else
-               Get SP
-               I64Const $0
-               I64Store8 ret+48(FP)
-       End
-       RET
-
 // memequal(p, q unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal(SB), NOSPLIT, $0-25
        Get SP