diff options
| author | Russ Cox <rsc@golang.org> | 2014-09-12 07:29:19 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2014-09-12 07:29:19 -0400 |
| commit | f0d44dbeaf28d157f8eba85ec9f9bffdc84ce3e0 (patch) | |
| tree | 60896b9b1303b7ad3eb305568cb63d5e26cac032 /src/reflect/makefunc.go | |
| parent | 70f928698b8416efa544029cfa0f0f7178cdd51b (diff) | |
| download | go-f0d44dbeaf28d157f8eba85ec9f9bffdc84ce3e0.tar.xz | |
runtime: look up arg stackmap for makeFuncStub/methodValueStub during traceback
makeFuncStub and methodValueStub are used by reflect as
generic function implementations. Each call might have
different arguments. Extract those arguments from the
closure data instead of assuming it is the same each time.
Because the argument map is now being extracted from the
function itself, we don't need the special cases in reflect.Call
anymore, so delete those.
Fixes an occasional crash seen when stack copying does
not update makeFuncStub's arguments correctly.
Will also help make it safe to require stack maps in the
garbage collector.
Derived from CL 142000044 by khr.
LGTM=khr
R=khr
CC=golang-codereviews
https://golang.org/cl/143890044
Diffstat (limited to 'src/reflect/makefunc.go')
| -rw-r--r-- | src/reflect/makefunc.go | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/reflect/makefunc.go b/src/reflect/makefunc.go index 0e61fdea7a..bdb8c21d76 100644 --- a/src/reflect/makefunc.go +++ b/src/reflect/makefunc.go @@ -13,9 +13,10 @@ import ( // makeFuncImpl is the closure value implementing the function // returned by MakeFunc. type makeFuncImpl struct { - code uintptr - typ *funcType - fn func([]Value) []Value + code uintptr + stack *bitVector // stack bitmap for args - offset known to runtime + typ *funcType + fn func([]Value) []Value } // MakeFunc returns a new function of the given Type @@ -54,7 +55,10 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { dummy := makeFuncStub code := **(**uintptr)(unsafe.Pointer(&dummy)) - impl := &makeFuncImpl{code: code, typ: ftyp, fn: fn} + // makeFuncImpl contains a stack map for use by the runtime + _, _, _, stack := funcLayout(t, nil) + + impl := &makeFuncImpl{code: code, stack: stack, typ: ftyp, fn: fn} return Value{t, unsafe.Pointer(impl), 0, flag(Func) << flagKindShift} } @@ -68,6 +72,7 @@ func makeFuncStub() type methodValue struct { fn uintptr + stack *bitVector // stack bitmap for args - offset known to runtime method int rcvr Value } @@ -98,8 +103,12 @@ func makeMethodValue(op string, v Value) Value { dummy := methodValueCall code := **(**uintptr)(unsafe.Pointer(&dummy)) + // methodValue contains a stack map for use by the runtime + _, _, _, stack := funcLayout(funcType, nil) + fv := &methodValue{ fn: code, + stack: stack, method: int(v.flag) >> flagMethodShift, rcvr: rcvr, } |
