cmd/gc, runtime: refactor interface inlining decision into compiler
We need to change the interface value representation for
concurrent garbage collection, so that there is no ambiguity
about whether the data word holds a pointer or scalar.
This CL does NOT make any representation changes.
Instead, it removes representation assumptions from
various pieces of code throughout the tree.
The isdirectiface function in cmd/gc/subr.c is now
the only place that decides that policy.
The policy propagates out from there in the reflect
metadata, as a new flag in the internal kind value.
A follow-up CL will change the representation by
changing the isdirectiface function. If that CL causes
problems, it will be easy to roll back.
Update #8405.
LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews, r
https://golang.org/cl/129090043
diff --git a/src/pkg/runtime/iface.go b/src/pkg/runtime/iface.go
index 9bd6fc7..60dfb49 100644
--- a/src/pkg/runtime/iface.go
+++ b/src/pkg/runtime/iface.go
@@ -135,7 +135,7 @@
func convT2E(t *_type, elem unsafe.Pointer) (e interface{}) {
size := uintptr(t.size)
ep := (*eface)(unsafe.Pointer(&e))
- if size <= ptrSize {
+ if isDirectIface(t) {
ep._type = t
memmove(unsafe.Pointer(&ep.data), elem, size)
} else {
@@ -157,7 +157,7 @@
}
size := uintptr(t.size)
pi := (*iface)(unsafe.Pointer(&i))
- if size <= ptrSize {
+ if isDirectIface(t) {
pi.tab = tab
memmove(unsafe.Pointer(&pi.data), elem, size)
} else {
@@ -182,7 +182,7 @@
panic(&TypeAssertionError{*tab.inter.typ._string, *tab._type._string, *t._string, ""})
}
size := uintptr(t.size)
- if size <= ptrSize {
+ if isDirectIface(t) {
memmove(unsafe.Pointer(&r), unsafe.Pointer(&ip.data), size)
} else {
memmove(unsafe.Pointer(&r), ip.data, size)
@@ -202,7 +202,7 @@
return
}
*ok = true
- if size <= ptrSize {
+ if isDirectIface(t) {
memmove(unsafe.Pointer(&r), unsafe.Pointer(&ip.data), size)
} else {
memmove(unsafe.Pointer(&r), ip.data, size)
@@ -226,7 +226,7 @@
panic(&TypeAssertionError{"", *ep._type._string, *t._string, ""})
}
size := uintptr(t.size)
- if size <= ptrSize {
+ if isDirectIface(t) {
memmove(unsafe.Pointer(&r), unsafe.Pointer(&ep.data), size)
} else {
memmove(unsafe.Pointer(&r), ep.data, size)
@@ -245,7 +245,7 @@
return
}
*ok = true
- if size <= ptrSize {
+ if isDirectIface(t) {
memmove(unsafe.Pointer(&r), unsafe.Pointer(&ep.data), size)
} else {
memmove(unsafe.Pointer(&r), ep.data, size)