From 108dbd0dc759181ac31513a855d1e77c5df37d9d Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 23 Dec 2014 10:57:37 -0800 Subject: [PATCH] reflect: more function layout tests Test more stuff: 1) flagNoPointers, an incorrect value was the cause of #9425 2) Total function layout size 3) gc program Change-Id: I73f65fe740215938fa930d2f096febd9db0a0021 Reviewed-on: https://go-review.googlesource.com/2090 Reviewed-by: Ian Lance Taylor --- src/reflect/all_test.go | 68 +++++++++++++++++++++++++++++++++++--- src/reflect/export_test.go | 10 +++++- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 9d092d9acf..69be8c6b40 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -4075,9 +4075,10 @@ func TestCallGC(t *testing.T) { } type funcLayoutTest struct { - rcvr, t Type - argsize, retOffset uintptr - stack []byte + rcvr, t Type + size, argsize, retOffset uintptr + stack []byte + gc []byte } var funcLayoutTests []funcLayoutTest @@ -4095,24 +4096,30 @@ func init() { funcLayoutTest{ nil, ValueOf(func(a, b string) string { return "" }).Type(), + 6 * PtrSize, 4 * PtrSize, 4 * PtrSize, []byte{BitsPointer, BitsScalar, BitsPointer}, + []byte{BitsPointer, BitsScalar, BitsPointer, BitsScalar, BitsPointer, BitsScalar}, }) - var r []byte + var r, s []byte if PtrSize == 4 { r = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer} + s = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer, BitsScalar} } else { r = []byte{BitsScalar, BitsScalar, BitsPointer} + s = []byte{BitsScalar, BitsScalar, BitsPointer, BitsScalar} } 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, + s, }) funcLayoutTests = append(funcLayoutTests, @@ -4121,6 +4128,8 @@ func init() { ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(), 4 * PtrSize, 4 * PtrSize, + 4 * PtrSize, + []byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer}, []byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer}, }) @@ -4134,6 +4143,8 @@ func init() { ValueOf(func(a S) {}).Type(), 4 * PtrSize, 4 * PtrSize, + 4 * PtrSize, + []byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer}, []byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer}, }) @@ -4141,15 +4152,56 @@ func init() { funcLayoutTest{ ValueOf((*byte)(nil)).Type(), ValueOf(func(a uintptr, b *int) {}).Type(), + roundup(3*PtrSize, argAlign), 3 * PtrSize, roundup(3*PtrSize, argAlign), []byte{BitsPointer, BitsScalar, BitsPointer}, + []byte{BitsPointer, BitsScalar, BitsPointer}, + }) + + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + nil, + ValueOf(func(a uintptr){}).Type(), + PtrSize, + PtrSize, + PtrSize, + []byte{}, + []byte{BitsScalar}, + }) + + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + nil, + ValueOf(func() uintptr{return 0}).Type(), + PtrSize, + 0, + 0, + []byte{}, + []byte{BitsScalar}, + }) + + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + ValueOf(uintptr(0)).Type(), + ValueOf(func(a uintptr){}).Type(), + 2*PtrSize, + 2*PtrSize, + 2*PtrSize, + []byte{BitsPointer}, + []byte{BitsPointer, BitsScalar}, + // 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 { - _, argsize, retOffset, stack := FuncLayout(lt.t, lt.rcvr) + 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) } @@ -4159,5 +4211,11 @@ func TestFuncLayout(t *testing.T) { 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) + } } } diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go index caaf51a50f..1ef63b034f 100644 --- a/src/reflect/export_test.go +++ b/src/reflect/export_test.go @@ -22,7 +22,7 @@ const PtrSize = ptrSize const BitsPointer = bitsPointer const BitsScalar = bitsScalar -func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack []byte) { +func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack []byte, gc []byte, ptrs bool) { var ft *rtype var s *bitVector if rcvr != nil { @@ -34,5 +34,13 @@ func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, for i := uint32(0); i < s.n; i += 2 { stack = append(stack, s.data[i/8]>>(i%8)&3) } + if ft.kind & kindGCProg != 0 { + panic("can't handle gc programs") + } + gcdata := (*[1000]byte)(ft.gc[0]) + for i := uintptr(0); i < ft.size/ptrSize; i++ { + gc = append(gc, gcdata[i/2] >> (i%2*4+2) & 3) + } + ptrs = ft.kind & kindNoPointers == 0 return } -- 2.50.0