1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:20:22 -07:00

reflect: expose reflect.call argument slice to the garbage collector

The argument slice was kept hidden from the garbage collector
by destroying its referent in an unsafe.Pointer to uintptr
conversion.  This change preserves the unsafe.Pointer referent
and only performs an unsafe.Pointer to uintptr conversions
within expressions that construct new unsafe.Pointer values.

R=golang-dev, khr, rsc
CC=golang-dev
https://golang.org/cl/14008043
This commit is contained in:
Carl Shapiro 2013-09-26 21:59:13 -07:00
parent d6eada282e
commit 0ab8f2d287

View File

@ -446,11 +446,11 @@ func (v Value) call(op string, in []Value) []Value {
// For now make everything look like a pointer by allocating
// a []unsafe.Pointer.
args := make([]unsafe.Pointer, size/ptrSize)
ptr := uintptr(unsafe.Pointer(&args[0]))
ptr := unsafe.Pointer(&args[0])
off := uintptr(0)
if v.flag&flagMethod != 0 {
// Hard-wired first argument.
*(*iword)(unsafe.Pointer(ptr)) = rcvr
*(*iword)(ptr) = rcvr
off = ptrSize
}
for i, v := range in {
@ -459,7 +459,7 @@ func (v Value) call(op string, in []Value) []Value {
a := uintptr(targ.align)
off = (off + a - 1) &^ (a - 1)
n := targ.size
addr := unsafe.Pointer(ptr + off)
addr := unsafe.Pointer(uintptr(ptr) + off)
v = v.assignTo("reflect.Value.Call", targ, (*interface{})(addr))
if v.flag&flagIndir == 0 {
storeIword(addr, iword(v.val), n)
@ -471,7 +471,7 @@ func (v Value) call(op string, in []Value) []Value {
off = (off + ptrSize - 1) &^ (ptrSize - 1)
// Call.
call(fn, unsafe.Pointer(ptr), uint32(size))
call(fn, ptr, uint32(size))
// Copy return values out of args.
//
@ -482,7 +482,7 @@ func (v Value) call(op string, in []Value) []Value {
a := uintptr(tv.Align())
off = (off + a - 1) &^ (a - 1)
fl := flagIndir | flag(tv.Kind())<<flagKindShift
ret[i] = Value{tv.common(), unsafe.Pointer(ptr + off), fl}
ret[i] = Value{tv.common(), unsafe.Pointer(uintptr(ptr) + off), fl}
off += tv.Size()
}