diff options
author | Michael Anthony Knyszek <mknyszek@google.com> | 2021-04-06 21:55:19 +0000 |
---|---|---|
committer | Michael Knyszek <mknyszek@google.com> | 2021-04-06 22:55:58 +0000 |
commit | b084073b53bfc4236d95819a3cc34dcbb4f15392 (patch) | |
tree | a73c1b9b940f5362cf5b57755fa6f0531c0380f8 /src/reflect/all_test.go | |
parent | 0a510478b0294744894385c6c6f5ded6829b6524 (diff) | |
download | go-b084073b53bfc4236d95819a3cc34dcbb4f15392.tar.gz go-b084073b53bfc4236d95819a3cc34dcbb4f15392.zip |
reflect: refactor funcLayout tests
This change refactors the existing funcLayout tests and sets them up to
support the new register ABI by explicitly setting the register counts
to zero. This allows the test to pass if GOEXPERIMENT=regabiargs is set.
A follow-up change will add tests for a non-zero register count.
For #40724.
Change-Id: Ibbe061b4ed4fd70566eb38b9e6182dca32b81127
Reviewed-on: https://go-review.googlesource.com/c/go/+/307869
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/reflect/all_test.go')
-rw-r--r-- | src/reflect/all_test.go | 235 |
1 files changed, 113 insertions, 122 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index e4b74f72d9..241f6b0b5a 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -6396,144 +6396,135 @@ func clobber() { runtime.GC() } -type funcLayoutTest struct { - rcvr, t Type - size, argsize, retOffset uintptr - stack []byte // pointer bitmap: 1 is pointer, 0 is scalar - gc []byte -} - -var funcLayoutTests []funcLayoutTest - -func init() { - var argAlign uintptr = PtrSize - roundup := func(x uintptr, a uintptr) uintptr { - return (x + a - 1) / a * a - } - - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - nil, - ValueOf(func(a, b string) string { return "" }).Type(), - 6 * PtrSize, - 4 * PtrSize, - 4 * PtrSize, - []byte{1, 0, 1, 0, 1}, - []byte{1, 0, 1, 0, 1}, - }) - +func TestFuncLayout(t *testing.T) { + align := func(x uintptr) uintptr { + return (x + PtrSize - 1) &^ (PtrSize - 1) + } var r []byte if PtrSize == 4 { r = []byte{0, 0, 0, 1} } else { r = []byte{0, 0, 1} } - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - nil, - ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(), - roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign), - roundup(3*4, PtrSize) + PtrSize + 2, - roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign), - r, - r, - }) - - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - nil, - ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(), - 4 * PtrSize, - 4 * PtrSize, - 4 * PtrSize, - []byte{1, 0, 1, 1}, - []byte{1, 0, 1, 1}, - }) type S struct { a, b uintptr c, d *byte } - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - nil, - ValueOf(func(a S) {}).Type(), - 4 * PtrSize, - 4 * PtrSize, - 4 * PtrSize, - []byte{0, 0, 1, 1}, - []byte{0, 0, 1, 1}, - }) - - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - ValueOf((*byte)(nil)).Type(), - ValueOf(func(a uintptr, b *int) {}).Type(), - roundup(3*PtrSize, argAlign), - 3 * PtrSize, - roundup(3*PtrSize, argAlign), - []byte{1, 0, 1}, - []byte{1, 0, 1}, - }) - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - nil, - ValueOf(func(a uintptr) {}).Type(), - roundup(PtrSize, argAlign), - PtrSize, - roundup(PtrSize, argAlign), - []byte{}, - []byte{}, - }) - - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - nil, - ValueOf(func() uintptr { return 0 }).Type(), - PtrSize, - 0, - 0, - []byte{}, - []byte{}, - }) - - funcLayoutTests = append(funcLayoutTests, - funcLayoutTest{ - ValueOf(uintptr(0)).Type(), - ValueOf(func(a uintptr) {}).Type(), - 2 * PtrSize, - 2 * PtrSize, - 2 * PtrSize, - []byte{1}, - []byte{1}, + type test struct { + rcvr, typ Type + size, argsize, retOffset uintptr + stack, gc, inRegs, outRegs []byte // pointer bitmap: 1 is pointer, 0 is scalar + intRegs, floatRegs int + floatRegSize uintptr + } + tests := []test{ + { + typ: ValueOf(func(a, b string) string { return "" }).Type(), + size: 6 * PtrSize, + argsize: 4 * PtrSize, + retOffset: 4 * PtrSize, + stack: []byte{1, 0, 1, 0, 1}, + gc: []byte{1, 0, 1, 0, 1}, + }, + { + typ: ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(), + size: align(align(3*4) + PtrSize + 2), + argsize: align(3*4) + PtrSize + 2, + retOffset: align(align(3*4) + PtrSize + 2), + stack: r, + gc: r, + }, + { + typ: ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(), + size: 4 * PtrSize, + argsize: 4 * PtrSize, + retOffset: 4 * PtrSize, + stack: []byte{1, 0, 1, 1}, + gc: []byte{1, 0, 1, 1}, + }, + { + typ: ValueOf(func(a S) {}).Type(), + size: 4 * PtrSize, + argsize: 4 * PtrSize, + retOffset: 4 * PtrSize, + stack: []byte{0, 0, 1, 1}, + gc: []byte{0, 0, 1, 1}, + }, + { + rcvr: ValueOf((*byte)(nil)).Type(), + typ: ValueOf(func(a uintptr, b *int) {}).Type(), + size: 3 * PtrSize, + argsize: 3 * PtrSize, + retOffset: 3 * PtrSize, + stack: []byte{1, 0, 1}, + gc: []byte{1, 0, 1}, + }, + { + typ: ValueOf(func(a uintptr) {}).Type(), + size: PtrSize, + argsize: PtrSize, + retOffset: PtrSize, + stack: []byte{}, + gc: []byte{}, + }, + { + typ: ValueOf(func() uintptr { return 0 }).Type(), + size: PtrSize, + argsize: 0, + retOffset: 0, + stack: []byte{}, + gc: []byte{}, + }, + { + rcvr: ValueOf(uintptr(0)).Type(), + typ: ValueOf(func(a uintptr) {}).Type(), + size: 2 * PtrSize, + argsize: 2 * PtrSize, + retOffset: 2 * PtrSize, + stack: []byte{1}, + gc: []byte{1}, // Note: this one is tricky, as the receiver is not a pointer. But we // pass the receiver by reference to the autogenerated pointer-receiver // version of the function. - }) -} - -func TestFuncLayout(t *testing.T) { - for _, lt := range funcLayoutTests { - typ, argsize, retOffset, stack, gc, ptrs := FuncLayout(lt.t, lt.rcvr) - if typ.Size() != lt.size { - t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.t, lt.rcvr, typ.Size(), lt.size) - } - if argsize != lt.argsize { - t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize) - } - if retOffset != lt.retOffset { - t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.t, lt.rcvr, retOffset, lt.retOffset) - } - if !bytes.Equal(stack, lt.stack) { - t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack) - } - if !bytes.Equal(gc, lt.gc) { - t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.t, lt.rcvr, gc, lt.gc) - } - if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 { - t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.t, lt.rcvr, ptrs, !ptrs) + }, + // TODO(mknyszek): Add tests for non-zero register count. + } + for _, lt := range tests { + name := lt.typ.String() + if lt.rcvr != nil { + name = lt.rcvr.String() + "." + name } + t.Run(name, func(t *testing.T) { + defer SetArgRegs(SetArgRegs(lt.intRegs, lt.floatRegs, lt.floatRegSize)) + + typ, argsize, retOffset, stack, gc, inRegs, outRegs, ptrs := FuncLayout(lt.typ, lt.rcvr) + if typ.Size() != lt.size { + t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.typ, lt.rcvr, typ.Size(), lt.size) + } + if argsize != lt.argsize { + t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.typ, lt.rcvr, argsize, lt.argsize) + } + if retOffset != lt.retOffset { + t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.typ, lt.rcvr, retOffset, lt.retOffset) + } + if !bytes.Equal(stack, lt.stack) { + t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.typ, lt.rcvr, stack, lt.stack) + } + if !bytes.Equal(gc, lt.gc) { + t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.typ, lt.rcvr, gc, lt.gc) + } + if !bytes.Equal(inRegs, lt.inRegs) { + t.Errorf("funcLayout(%v, %v).inRegs=%v, want %v", lt.typ, lt.rcvr, inRegs, lt.inRegs) + } + if !bytes.Equal(outRegs, lt.outRegs) { + t.Errorf("funcLayout(%v, %v).outRegs=%v, want %v", lt.typ, lt.rcvr, outRegs, lt.outRegs) + } + if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 { + t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.typ, lt.rcvr, ptrs, !ptrs) + } + }) } } |