diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/malloc.h | 1 | ||||
| -rw-r--r-- | src/runtime/mgc0.c | 6 | ||||
| -rw-r--r-- | src/runtime/runtime.h | 2 | ||||
| -rw-r--r-- | src/runtime/stack.c | 14 | ||||
| -rw-r--r-- | src/runtime/traceback.go | 16 |
5 files changed, 31 insertions, 8 deletions
diff --git a/src/runtime/malloc.h b/src/runtime/malloc.h index 5441691940..b6856768db 100644 --- a/src/runtime/malloc.h +++ b/src/runtime/malloc.h @@ -586,7 +586,6 @@ void runtime·queuefinalizer(byte *p, FuncVal *fn, uintptr nret, Type *fint, Ptr bool runtime·freespecial(Special *s, void *p, uintptr size, bool freed); // Information from the compiler about the layout of stack frames. -typedef struct BitVector BitVector; struct BitVector { int32 n; // # of bits diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c index da0455d923..af0b6285a3 100644 --- a/src/runtime/mgc0.c +++ b/src/runtime/mgc0.c @@ -673,8 +673,10 @@ scanframe(Stkframe *frame, void *unused) // Scan arguments. // Use pointer information if known. - stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps); - if(stackmap != nil) { + if(frame->argmap != nil) { + bv = *frame->argmap; + scanblock((byte*)frame->argp, bv.n/BitsPerPointer*PtrSize, (byte*)bv.data); + } else if((stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps)) != nil) { bv = runtime·stackmapdata(stackmap, pcdata); scanblock((byte*)frame->argp, bv.n/BitsPerPointer*PtrSize, (byte*)bv.data); } else { diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 01923c61e0..6300b83c97 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -666,6 +666,7 @@ struct Panic * stack traces */ typedef struct Stkframe Stkframe; +typedef struct BitVector BitVector; struct Stkframe { Func* fn; // function being run @@ -677,6 +678,7 @@ struct Stkframe uintptr varp; // top of local variables uintptr argp; // pointer to function arguments uintptr arglen; // number of bytes at argp + BitVector* argmap; // force use of this argmap }; intgo runtime·gentraceback(uintptr, uintptr, uintptr, G*, intgo, uintptr*, intgo, bool(**)(Stkframe*, void*), void*, bool); diff --git a/src/runtime/stack.c b/src/runtime/stack.c index cc2857ac81..53ad90a5de 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -481,12 +481,16 @@ adjustframe(Stkframe *frame, void *arg) } // adjust inargs and outargs if(frame->arglen != 0) { - stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps); - if(stackmap == nil) { - runtime·printf("size %d\n", (int32)frame->arglen); - runtime·throw("no arg info"); + if(frame->argmap != nil) { + bv = *frame->argmap; + } else { + stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps); + if(stackmap == nil) { + runtime·printf("size %d\n", (int32)frame->arglen); + runtime·throw("no arg info"); + } + bv = runtime·stackmapdata(stackmap, pcdata); } - bv = runtime·stackmapdata(stackmap, pcdata); if(StackDebug >= 3) runtime·printf(" args\n"); adjustpointers((byte**)frame->argp, &bv, adjinfo, nil); diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index ca3b862102..84cb08c9e1 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -189,6 +189,21 @@ func gentraceback(pc0 uintptr, sp0 uintptr, lr0 uintptr, gp *g, skip int, pcbuf } if f.args != _ArgsSizeUnknown { frame.arglen = uintptr(f.args) + } else if callback != nil && (gofuncname(f) == "reflect.makeFuncStub" || gofuncname(f) == "reflect.methodValueCall") { + // NOTE: Two calls to gofuncname on line above will be + // collapsed to one when we pull out all the imprecise fallback code. + arg0 := frame.sp + if usesLR { + arg0 += ptrSize + } + fn := *(**[2]uintptr)(unsafe.Pointer(arg0)) + if fn[0] != f.entry { + print("runtime: confused by ", gofuncname(f), "\n") + gothrow("reflect mismatch") + } + bv := (*bitvector)(unsafe.Pointer(fn[1])) + frame.arglen = uintptr(bv.n / 2 * ptrSize) + frame.argmap = bv } else if flr == nil { frame.arglen = 0 } else { @@ -332,6 +347,7 @@ func gentraceback(pc0 uintptr, sp0 uintptr, lr0 uintptr, gp *g, skip int, pcbuf frame.lr = 0 frame.sp = frame.fp frame.fp = 0 + frame.argmap = nil // On link register architectures, sighandler saves the LR on stack // before faking a call to sigpanic. |
