aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/cgocall.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2020-10-01 10:58:47 -0400
committerAustin Clements <austin@google.com>2020-10-02 20:42:56 +0000
commitf89d05eb7ba1885474d03bb62f0a36a2d3cf56ea (patch)
tree2cd5ebda15bcf622122bc8ba1699c36e46179070 /src/runtime/cgocall.go
parent21eb3dcf93fc3698c9b8cd3ba83c9ddbef31e880 (diff)
downloadgo-f89d05eb7ba1885474d03bb62f0a36a2d3cf56ea.tar.gz
go-f89d05eb7ba1885474d03bb62f0a36a2d3cf56ea.zip
runtime: update and tidy cgo callback description
The documentation on how cgo callbacks (C -> Go calls) works internally has gotten somewhat stale. This CL refreshes it. Change-Id: I1ab66225c9da52d698d97ebeb4f3c7b9b5ee97db Reviewed-on: https://go-review.googlesource.com/c/go/+/258937 Trust: Austin Clements <austin@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime/cgocall.go')
-rw-r--r--src/runtime/cgocall.go42
1 files changed, 23 insertions, 19 deletions
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 427ed0ffb9..0b69ff3233 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -35,44 +35,48 @@
// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
// know about packages). The gcc-compiled C function f calls GoF.
//
-// GoF calls crosscall2(_cgoexp_GoF, frame, framesize). Crosscall2
-// (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument
-// adapter from the gcc function call ABI to the 6c function call ABI.
-// It is called from gcc to call 6c functions. In this case it calls
-// _cgoexp_GoF(frame, framesize), still running on m->g0's stack
+// GoF calls crosscall2(_cgoexp_GoF, frame, framesize, ctxt).
+// Crosscall2 (in cgo/asm_$GOARCH.s) is a four-argument adapter from
+// the gcc function call ABI to the gc function call ABI.
+// It is called from gcc to call gc functions. In this case it calls
+// _cgoexp_GoF(frame, framesize), still running on m.g0's stack
// and outside the $GOMAXPROCS limit. Thus, this code cannot yet
// call arbitrary Go code directly and must be careful not to allocate
-// memory or use up m->g0's stack.
+// memory or use up m.g0's stack.
//
-// _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize, ctxt).
+// _cgoexp_GoF (generated by cmd/cgo) calls
+// runtime.cgocallback(funcPC(p.GoF), frame, framesize, ctxt).
// (The reason for having _cgoexp_GoF instead of writing a crosscall3
// to make this call directly is that _cgoexp_GoF, because it is compiled
-// with 6c instead of gcc, can refer to dotted names like
+// with gc instead of gcc, can refer to dotted names like
// runtime.cgocallback and p.GoF.)
//
-// runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's
-// stack to the original g (m->curg)'s stack, on which it calls
+// runtime.cgocallback (in asm_$GOARCH.s) turns the raw PC of p.GoF
+// into a Go function value and calls runtime.cgocallback_gofunc.
+//
+// runtime.cgocallback_gofunc (in asm_$GOARCH.s) switches from m.g0's
+// stack to the original g (m.curg)'s stack, on which it calls
// runtime.cgocallbackg(p.GoF, frame, framesize).
// As part of the stack switch, runtime.cgocallback saves the current
-// SP as m->g0->sched.sp, so that any use of m->g0's stack during the
+// SP as m.g0.sched.sp, so that any use of m.g0's stack during the
// execution of the callback will be done below the existing stack frames.
-// Before overwriting m->g0->sched.sp, it pushes the old value on the
-// m->g0 stack, so that it can be restored later.
+// Before overwriting m.g0.sched.sp, it pushes the old value on the
+// m.g0 stack, so that it can be restored later.
//
// runtime.cgocallbackg (below) is now running on a real goroutine
-// stack (not an m->g0 stack). First it calls runtime.exitsyscall, which will
+// stack (not an m.g0 stack). First it calls runtime.exitsyscall, which will
// block until the $GOMAXPROCS limit allows running this goroutine.
// Once exitsyscall has returned, it is safe to do things like call the memory
// allocator or invoke the Go callback function p.GoF. runtime.cgocallbackg
-// first defers a function to unwind m->g0.sched.sp, so that if p.GoF
-// panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack
-// and the m->curg stack will be unwound in lock step.
+// first defers a function to unwind m.g0.sched.sp, so that if p.GoF
+// panics, m.g0.sched.sp will be restored to its old value: the m.g0 stack
+// and the m.curg stack will be unwound in lock step.
// Then it calls p.GoF. Finally it pops but does not execute the deferred
// function, calls runtime.entersyscall, and returns to runtime.cgocallback.
//
// After it regains control, runtime.cgocallback switches back to
-// m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old
-// m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
+// m.g0's stack (the pointer is still in m.g0.sched.sp), restores the old
+// m.g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
//
// _cgoexp_GoF immediately returns to crosscall2, which restores the
// callee-save registers for gcc and returns to GoF, which returns to f.