Skip to content

cmd/compile: pointer update without write barrier in reslice operation #14855

Closed
@rsc

Description

@rsc

The ssa back end does not eliminate as many write barriers as the non-ssa back end. This should be fixed. I thought there were tests of this. Were they disabled?

In particular, reslicing an addressable slice with low index 0 should not rewrite the pointer (or the cap, usually), and not rewriting the pointer will avoid the expense of a write barrier.

Test program:

package p

func f(x *[]byte) []byte {
    *x = (*x)[:8]
    g()
    return *x
}

func g()

Without ssa:

0x0020 00032 (/tmp/x.go:4)  MOVQ    "".x+8(FP), BX
0x0025 00037 (/tmp/x.go:4)  NOP
0x0025 00037 (/tmp/x.go:4)  MOVQ    16(BX), BP
0x0029 00041 (/tmp/x.go:4)  CMPQ    BP, $8
0x002d 00045 (/tmp/x.go:4)  JCS $0, 102
0x002f 00047 (/tmp/x.go:4)  MOVQ    $8, 8(BX)

With ssa:

0x0013 00019 (/tmp/x.go:4)  MOVQ    "".x+24(FP), CX
0x0018 00024 (/tmp/x.go:4)  MOVQ    (CX), DX
0x001b 00027 (/tmp/x.go:4)  MOVQ    16(CX), BX
0x001f 00031 (/tmp/x.go:4)  CMPQ    BX, $8
0x0023 00035 (/tmp/x.go:4)  JCS $0, 130
0x0025 00037 (/tmp/x.go:4)  CMPQ    BX, $0
0x0029 00041 (/tmp/x.go:4)  JEQ $0, 43
0x002b 00043 (/tmp/x.go:4)  MOVQ    $8, 8(CX)
0x0033 00051 (/tmp/x.go:4)  MOVQ    BX, 16(CX) << rewritine slice cap
0x0037 00055 (/tmp/x.go:4)  MOVL    runtime.writeBarrier(SB), AX
0x003d 00061 (/tmp/x.go:4)  TESTB   AL, AL
0x003f 00063 (/tmp/x.go:4)  JNE $0, 109
0x0041 00065 (/tmp/x.go:4)  MOVQ    DX, (CX) << rewriting slice base ptr

If I remember correctly, the optimization in the non-ssa back end applies to any expression of the form thing = thing[:n], where thing can be arbitrarily long, provided its the same on both sides, has no idempotency problems (like function calls), and is addressable.

/cc @randall77 @dr2chase

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions