aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/iface.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/iface.go')
-rw-r--r--src/runtime/iface.go108
1 files changed, 36 insertions, 72 deletions
diff --git a/src/runtime/iface.go b/src/runtime/iface.go
index cd5fead999..3d1d9d6ba1 100644
--- a/src/runtime/iface.go
+++ b/src/runtime/iface.go
@@ -5,8 +5,9 @@
package runtime
import (
+ "internal/abi"
+ "internal/goarch"
"runtime/internal/atomic"
- "runtime/internal/sys"
"unsafe"
)
@@ -63,7 +64,7 @@ func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
}
// Entry doesn't exist yet. Make a new entry & add it.
- m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*sys.PtrSize, 0, &memstats.other_sys))
+ m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*goarch.PtrSize, 0, &memstats.other_sys))
m.inter = inter
m._type = typ
// The hash is used in type switches. However, compiler statically generates itab's
@@ -100,7 +101,7 @@ func (t *itabTableType) find(inter *interfacetype, typ *_type) *itab {
mask := t.size - 1
h := itabHashFunc(inter, typ) & mask
for i := uintptr(1); ; i++ {
- p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
+ p := (**itab)(add(unsafe.Pointer(&t.entries), h*goarch.PtrSize))
// Use atomic read here so if we see m != nil, we also see
// the initializations of the fields of m.
// m := *p
@@ -133,7 +134,7 @@ func itabAdd(m *itab) {
// t2 = new(itabTableType) + some additional entries
// We lie and tell malloc we want pointer-free memory because
// all the pointed-to values are not in the heap.
- t2 := (*itabTableType)(mallocgc((2+2*t.size)*sys.PtrSize, nil, true))
+ t2 := (*itabTableType)(mallocgc((2+2*t.size)*goarch.PtrSize, nil, true))
t2.size = t.size * 2
// Copy over entries.
@@ -161,7 +162,7 @@ func (t *itabTableType) add(m *itab) {
mask := t.size - 1
h := itabHashFunc(m.inter, m._type) & mask
for i := uintptr(1); ; i++ {
- p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
+ p := (**itab)(add(unsafe.Pointer(&t.entries), h*goarch.PtrSize))
m2 := *p
if m2 == m {
// A given itab may be used in more than one module
@@ -315,26 +316,36 @@ var (
// The convXXX functions succeed on a nil input, whereas the assertXXX
// functions fail on a nil input.
-func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
+// convT converts a value of type t, which is pointed to by v, to a pointer that can
+// be used as the second word of an interface value.
+func convT(t *_type, v unsafe.Pointer) unsafe.Pointer {
if raceenabled {
- raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E))
+ raceReadObjectPC(t, v, getcallerpc(), abi.FuncPCABIInternal(convT))
}
if msanenabled {
- msanread(elem, t.size)
+ msanread(v, t.size)
}
x := mallocgc(t.size, t, true)
- // TODO: We allocate a zeroed object only to overwrite it with actual data.
- // Figure out how to avoid zeroing. Also below in convT2Eslice, convT2I, convT2Islice.
- typedmemmove(t, x, elem)
- e._type = t
- e.data = x
- return
+ typedmemmove(t, x, v)
+ return x
+}
+func convTnoptr(t *_type, v unsafe.Pointer) unsafe.Pointer {
+ // TODO: maybe take size instead of type?
+ if raceenabled {
+ raceReadObjectPC(t, v, getcallerpc(), abi.FuncPCABIInternal(convTnoptr))
+ }
+ if msanenabled {
+ msanread(v, t.size)
+ }
+ x := mallocgc(t.size, t, false)
+ memmove(x, v, t.size)
+ return x
}
func convT16(val uint16) (x unsafe.Pointer) {
if val < uint16(len(staticuint64s)) {
x = unsafe.Pointer(&staticuint64s[val])
- if sys.BigEndian {
+ if goarch.BigEndian {
x = add(x, 6)
}
} else {
@@ -347,7 +358,7 @@ func convT16(val uint16) (x unsafe.Pointer) {
func convT32(val uint32) (x unsafe.Pointer) {
if val < uint32(len(staticuint64s)) {
x = unsafe.Pointer(&staticuint64s[val])
- if sys.BigEndian {
+ if goarch.BigEndian {
x = add(x, 4)
}
} else {
@@ -388,63 +399,16 @@ func convTslice(val []byte) (x unsafe.Pointer) {
return
}
-func convT2Enoptr(t *_type, elem unsafe.Pointer) (e eface) {
- if raceenabled {
- raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Enoptr))
- }
- if msanenabled {
- msanread(elem, t.size)
- }
- x := mallocgc(t.size, t, false)
- memmove(x, elem, t.size)
- e._type = t
- e.data = x
- return
-}
-
-func convT2I(tab *itab, elem unsafe.Pointer) (i iface) {
- t := tab._type
- if raceenabled {
- raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I))
- }
- if msanenabled {
- msanread(elem, t.size)
- }
- x := mallocgc(t.size, t, true)
- typedmemmove(t, x, elem)
- i.tab = tab
- i.data = x
- return
-}
-
-func convT2Inoptr(tab *itab, elem unsafe.Pointer) (i iface) {
- t := tab._type
- if raceenabled {
- raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Inoptr))
- }
- if msanenabled {
- msanread(elem, t.size)
- }
- x := mallocgc(t.size, t, false)
- memmove(x, elem, t.size)
- i.tab = tab
- i.data = x
- return
-}
-
-func convI2I(inter *interfacetype, i iface) (r iface) {
- tab := i.tab
- if tab == nil {
- return
+// convI2I returns the new itab to be used for the destination value
+// when converting a value with itab src to the dst interface.
+func convI2I(dst *interfacetype, src *itab) *itab {
+ if src == nil {
+ return nil
}
- if tab.inter == inter {
- r.tab = tab
- r.data = i.data
- return
+ if src.inter == dst {
+ return src
}
- r.tab = getitab(inter, tab._type, false)
- r.data = i.data
- return
+ return getitab(dst, src._type, false)
}
func assertI2I(inter *interfacetype, tab *itab) *itab {
@@ -511,7 +475,7 @@ func iterate_itabs(fn func(*itab)) {
// so no other locks/atomics needed.
t := itabTable
for i := uintptr(0); i < t.size; i++ {
- m := *(**itab)(add(unsafe.Pointer(&t.entries), i*sys.PtrSize))
+ m := *(**itab)(add(unsafe.Pointer(&t.entries), i*goarch.PtrSize))
if m != nil {
fn(m)
}