aboutsummaryrefslogtreecommitdiff
path: root/libgo/go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go')
-rw-r--r--libgo/go/reflect/all_test.go5
-rw-r--r--libgo/go/reflect/type.go17
-rw-r--r--libgo/go/runtime/iface.go19
-rw-r--r--libgo/go/runtime/pprof/proto.go2
-rw-r--r--libgo/go/runtime/proc.go2
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