aboutsummaryrefslogtreecommitdiff
path: root/src/reflect/value.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect/value.go')
-rw-r--r--src/reflect/value.go19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 6f878eba5b..520dc69137 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -352,7 +352,7 @@ func (v Value) CallSlice(in []Value) []Value {
return v.call("CallSlice", in)
}
-var callGC bool // for testing; see TestCallMethodJump
+var callGC bool // for testing; see TestCallMethodJump and TestCallArgLive
const debugReflectCall = false
@@ -509,12 +509,16 @@ func (v Value) call(op string, in []Value) []Value {
// Copy values to "integer registers."
if v.flag&flagIndir != 0 {
offset := add(v.ptr, st.offset, "precomputed value offset")
- memmove(unsafe.Pointer(&regArgs.Ints[st.ireg]), offset, st.size)
- } else {
if st.kind == abiStepPointer {
// Duplicate this pointer in the pointer area of the
// register space. Otherwise, there's the potential for
// this to be the last reference to v.ptr.
+ regArgs.Ptrs[st.ireg] = *(*unsafe.Pointer)(offset)
+ }
+ memmove(unsafe.Pointer(&regArgs.Ints[st.ireg]), offset, st.size)
+ } else {
+ if st.kind == abiStepPointer {
+ // See the comment in abiStepPointer case above.
regArgs.Ptrs[st.ireg] = v.ptr
}
regArgs.Ints[st.ireg] = uintptr(v.ptr)
@@ -539,6 +543,15 @@ func (v Value) call(op string, in []Value) []Value {
// Mark pointers in registers for the return path.
regArgs.ReturnIsPtr = abi.outRegPtrs
+ if debugReflectCall {
+ regArgs.Dump()
+ }
+
+ // For testing; see TestCallArgLive.
+ if callGC {
+ runtime.GC()
+ }
+
// Call.
call(frametype, fn, stackArgs, uint32(frametype.size), uint32(abi.retOffset), uint32(frameSize), &regArgs)