@@ -661,6 +661,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
661
661
// come in on the m->g0 stack already.
662
662
get_tls(CX)
663
663
MOVQ g(CX), R8
664
+ CMPQ R8, $0
665
+ JEQ nosave
664
666
MOVQ g_m(R8), R8
665
667
MOVQ m_g0(R8), SI
666
668
MOVQ g(CX), DI
@@ -670,11 +672,11 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
670
672
CMPQ SI, DI
671
673
JEQ nosave
672
674
675
+ // Switch to system stack.
673
676
MOVQ m_g0(R8), SI
674
677
CALL gosave<>(SB)
675
678
MOVQ SI, g(CX)
676
679
MOVQ (g_sched+gobuf_sp)(SI), SP
677
- nosave:
678
680
679
681
// Now on a scheduling stack (a pthread-created stack).
680
682
// Make sure we have enough room for 4 stack-backed fast-call
@@ -700,6 +702,29 @@ nosave:
700
702
MOVL AX, ret +16 (FP)
701
703
RET
702
704
705
+ nosave:
706
+ // Running on a system stack, perhaps even without a g.
707
+ // Having no g can happen during thread creation or thread teardown
708
+ // (see needm/dropm on Solaris, for example).
709
+ // This code is like the above sequence but without saving/restoring g
710
+ // and without worrying about the stack moving out from under us
711
+ // (because we're on a system stack, not a goroutine stack).
712
+ // The above code could be used directly if already on a system stack,
713
+ // but then the only path through this code would be a rare case on Solaris.
714
+ // Using this code for all "already on system stack" calls exercises it more,
715
+ // which should help keep it correct.
716
+ SUBQ $64 , SP
717
+ ANDQ $~15 , SP
718
+ MOVQ $0 , 48 (SP) // where above code stores g, in case someone looks during debugging
719
+ MOVQ DX, 40 (SP) // save original stack pointer
720
+ MOVQ BX, DI // DI = first argument in AMD64 ABI
721
+ MOVQ BX, CX // CX = first argument in Win64
722
+ CALL AX
723
+ MOVQ 40 (SP), SI // restore original stack pointer
724
+ MOVQ SI, SP
725
+ MOVL AX, ret +16 (FP)
726
+ RET
727
+
703
728
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
704
729
// Turn the fn into a Go func (by taking its address) and call
705
730
// cgocallback_gofunc.
0 commit comments