]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: allow copying of onM frame
authorDmitriy Vyukov <dvyukov@google.com>
Tue, 19 Aug 2014 10:24:03 +0000 (14:24 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Tue, 19 Aug 2014 10:24:03 +0000 (14:24 +0400)
Currently goroutines in onM can't be copied/shrunk
(including the very goroutine that triggers GC).
Special case onM to allow copying.

LGTM=daniel.morsing, khr
R=golang-codereviews, daniel.morsing, khr, rsc
CC=golang-codereviews, rlh
https://golang.org/cl/124550043

src/pkg/runtime/stack.c

index f7d41f44d41a9ca24ece5794fd272b41263fa338..f21d544f334dd73b8f7f40738dd50a21817e7325 100644 (file)
@@ -399,6 +399,7 @@ struct CopyableInfo {
 };
 
 void runtime·main(void);
+void runtime·switchtoM(void(*)(void));
 
 static bool
 checkframecopy(Stkframe *frame, void *arg)
@@ -424,6 +425,13 @@ checkframecopy(Stkframe *frame, void *arg)
                cinfo->frames++;
                return false; // stop traceback
        }
+       if(f->entry == (uintptr)runtime·switchtoM) {
+               // A special routine at the bottom of stack of a goroutine that does onM call.
+               // We will allow it to be copied even though we don't
+               // have full GC info for it (because it is written in asm).
+               cinfo->frames++;
+               return true;
+       }
        if(frame->varp != (byte*)frame->sp) { // not in prologue (and has at least one local or outarg)
                stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
                if(stackmap == nil) {
@@ -648,7 +656,8 @@ adjustframe(Stkframe *frame, void *arg)
        f = frame->fn;
        if(StackDebug >= 2)
                runtime·printf("    adjusting %s frame=[%p,%p] pc=%p continpc=%p\n", runtime·funcname(f), frame->sp, frame->fp, frame->pc, frame->continpc);
-       if(f->entry == (uintptr)runtime·main)
+       if(f->entry == (uintptr)runtime·main ||
+               f->entry == (uintptr)runtime·switchtoM)
                return true;
        targetpc = frame->continpc;
        if(targetpc == 0) {