Commit 108dbd0d authored by Keith Randall's avatar Keith Randall

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/2090Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 0d4ea0c7
...@@ -4075,9 +4075,10 @@ func TestCallGC(t *testing.T) { ...@@ -4075,9 +4075,10 @@ func TestCallGC(t *testing.T) {
} }
type funcLayoutTest struct { type funcLayoutTest struct {
rcvr, t Type rcvr, t Type
argsize, retOffset uintptr size, argsize, retOffset uintptr
stack []byte stack []byte
gc []byte
} }
var funcLayoutTests []funcLayoutTest var funcLayoutTests []funcLayoutTest
...@@ -4095,24 +4096,30 @@ func init() { ...@@ -4095,24 +4096,30 @@ func init() {
funcLayoutTest{ funcLayoutTest{
nil, nil,
ValueOf(func(a, b string) string { return "" }).Type(), ValueOf(func(a, b string) string { return "" }).Type(),
6 * PtrSize,
4 * PtrSize, 4 * PtrSize,
4 * PtrSize, 4 * PtrSize,
[]byte{BitsPointer, BitsScalar, BitsPointer}, []byte{BitsPointer, BitsScalar, BitsPointer},
[]byte{BitsPointer, BitsScalar, BitsPointer, BitsScalar, BitsPointer, BitsScalar},
}) })
var r []byte var r, s []byte
if PtrSize == 4 { if PtrSize == 4 {
r = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer} r = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer}
s = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer, BitsScalar}
} else { } else {
r = []byte{BitsScalar, BitsScalar, BitsPointer} r = []byte{BitsScalar, BitsScalar, BitsPointer}
s = []byte{BitsScalar, BitsScalar, BitsPointer, BitsScalar}
} }
funcLayoutTests = append(funcLayoutTests, funcLayoutTests = append(funcLayoutTests,
funcLayoutTest{ funcLayoutTest{
nil, nil,
ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(), 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(3*4, PtrSize) + PtrSize + 2,
roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign), roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
r, r,
s,
}) })
funcLayoutTests = append(funcLayoutTests, funcLayoutTests = append(funcLayoutTests,
...@@ -4121,6 +4128,8 @@ func init() { ...@@ -4121,6 +4128,8 @@ func init() {
ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(), ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
4 * PtrSize, 4 * PtrSize,
4 * PtrSize, 4 * PtrSize,
4 * PtrSize,
[]byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer},
[]byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer}, []byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer},
}) })
...@@ -4134,6 +4143,8 @@ func init() { ...@@ -4134,6 +4143,8 @@ func init() {
ValueOf(func(a S) {}).Type(), ValueOf(func(a S) {}).Type(),
4 * PtrSize, 4 * PtrSize,
4 * PtrSize, 4 * PtrSize,
4 * PtrSize,
[]byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer},
[]byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer}, []byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer},
}) })
...@@ -4141,15 +4152,56 @@ func init() { ...@@ -4141,15 +4152,56 @@ func init() {
funcLayoutTest{ funcLayoutTest{
ValueOf((*byte)(nil)).Type(), ValueOf((*byte)(nil)).Type(),
ValueOf(func(a uintptr, b *int) {}).Type(), ValueOf(func(a uintptr, b *int) {}).Type(),
roundup(3*PtrSize, argAlign),
3 * PtrSize, 3 * PtrSize,
roundup(3*PtrSize, argAlign), roundup(3*PtrSize, argAlign),
[]byte{BitsPointer, BitsScalar, BitsPointer}, []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) { func TestFuncLayout(t *testing.T) {
for _, lt := range funcLayoutTests { 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 { if argsize != lt.argsize {
t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, 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) { ...@@ -4159,5 +4211,11 @@ func TestFuncLayout(t *testing.T) {
if !bytes.Equal(stack, lt.stack) { if !bytes.Equal(stack, lt.stack) {
t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, 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)
}
} }
} }
...@@ -22,7 +22,7 @@ const PtrSize = ptrSize ...@@ -22,7 +22,7 @@ const PtrSize = ptrSize
const BitsPointer = bitsPointer const BitsPointer = bitsPointer
const BitsScalar = bitsScalar 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 ft *rtype
var s *bitVector var s *bitVector
if rcvr != nil { if rcvr != nil {
...@@ -34,5 +34,13 @@ func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, ...@@ -34,5 +34,13 @@ func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr,
for i := uint32(0); i < s.n; i += 2 { for i := uint32(0); i < s.n; i += 2 {
stack = append(stack, s.data[i/8]>>(i%8)&3) 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 return
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment