diff options
Diffstat (limited to 'libgo/go')
-rw-r--r-- | libgo/go/reflect/all_test.go | 5 | ||||
-rw-r--r-- | libgo/go/reflect/type.go | 17 | ||||
-rw-r--r-- | libgo/go/runtime/iface.go | 19 | ||||
-rw-r--r-- | libgo/go/runtime/pprof/proto.go | 2 | ||||
-rw-r--r-- | libgo/go/runtime/proc.go | 2 |
5 files changed, 30 insertions, 15 deletions
diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index 599ab27..9452255 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -4136,7 +4136,6 @@ func TestArrayOfGenericAlg(t *testing.T) { } func TestArrayOfDirectIface(t *testing.T) { - t.Skip("skipping test because gccgo uses a different directiface value") { type T [1]*byte i1 := Zero(TypeOf(T{})).Interface() @@ -4775,9 +4774,6 @@ func TestStructOfGenericAlg(t *testing.T) { } } -/* -gccgo does not use the same directiface settings as gc. - func TestStructOfDirectIface(t *testing.T) { { type T struct{ X [1]*byte } @@ -4826,7 +4822,6 @@ func TestStructOfDirectIface(t *testing.T) { } } } -*/ type StructI int diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index ea97b7d..fb2e5d4 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -2204,7 +2204,14 @@ func StructOf(fields []StructField) Type { typ.equalfn = nil } - typ.kind &^= kindDirectIface + switch { + case len(fs) == 1 && !ifaceIndir(fs[0].typ): + // structs of 1 direct iface type can be direct + typ.kind |= kindDirectIface + default: + typ.kind &^= kindDirectIface + } + typ.uncommonType = nil typ.ptrToThis = nil @@ -2405,7 +2412,13 @@ func ArrayOf(count int, elem Type) Type { array.ptrdata = array.size // overestimate but ok; must match program } - array.kind &^= kindDirectIface + switch { + case count == 1 && !ifaceIndir(typ): + // array of 1 direct iface type can be direct + array.kind |= kindDirectIface + default: + array.kind &^= kindDirectIface + } esize := typ.size diff --git a/libgo/go/runtime/iface.go b/libgo/go/runtime/iface.go index dc92476..1c3a5f3 100644 --- a/libgo/go/runtime/iface.go +++ b/libgo/go/runtime/iface.go @@ -68,10 +68,9 @@ import ( // pointer to memory that holds the value. It follows from this that // kindDirectIface can only be set for a type whose representation is // simply a pointer. In the current gccgo implementation, this is set -// only for pointer types (including unsafe.Pointer). In the future it -// could also be set for other types: channels, maps, functions, -// single-field structs and single-element arrays whose single field -// is simply a pointer. +// for types that are pointer-shaped, including unsafe.Pointer, channels, +// maps, functions, single-field structs and single-element arrays whose +// single field is simply a pointer-shaped type. // For a nil interface value both fields in the interface struct are nil. @@ -458,7 +457,11 @@ func ifaceE2T2(t *_type, e eface, ret unsafe.Pointer) bool { typedmemclr(t, ret) return false } else { - typedmemmove(t, ret, e.data) + if isDirectIface(t) { + *(*unsafe.Pointer)(ret) = e.data + } else { + typedmemmove(t, ret, e.data) + } return true } } @@ -469,7 +472,11 @@ func ifaceI2T2(t *_type, i iface, ret unsafe.Pointer) bool { typedmemclr(t, ret) return false } else { - typedmemmove(t, ret, i.data) + if isDirectIface(t) { + *(*unsafe.Pointer)(ret) = i.data + } else { + typedmemmove(t, ret, i.data) + } return true } } diff --git a/libgo/go/runtime/pprof/proto.go b/libgo/go/runtime/pprof/proto.go index 27cd09e..ef3eeb1 100644 --- a/libgo/go/runtime/pprof/proto.go +++ b/libgo/go/runtime/pprof/proto.go @@ -29,7 +29,7 @@ func funcPC(f interface{}) uintptr { data unsafe.Pointer } i := (*iface)(unsafe.Pointer(&f)) - r := **(**uintptr)(i.data) + r := *(*uintptr)(i.data) if internalcpu.FunctionDescriptors { // With PPC64 ELF ABI v1 function descriptors the // function address is a pointer to a struct whose diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index 0e6c9e1..8146c1d 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -446,7 +446,7 @@ func releaseSudog(s *sudog) { //go:nosplit func funcPC(f interface{}) uintptr { i := (*iface)(unsafe.Pointer(&f)) - r := **(**uintptr)(i.data) + r := *(*uintptr)(i.data) if cpu.FunctionDescriptors { // With PPC64 ELF ABI v1 function descriptors the // function address is a pointer to a struct whose |