1
0
mirror of https://github.com/golang/go synced 2024-11-18 20:44:45 -07:00
go/misc/cgo/test
Austin Clements 30c1887873 runtime,cmd/cgo: simplify C -> Go call path
This redesigns the way calls work from C to exported Go functions. It
removes several steps from the call path, makes cmd/cgo no longer
sensitive to the Go calling convention, and eliminates the use of
reflectcall from cgo.

In order to avoid generating a large amount of FFI glue between the C
and Go ABIs, the cgo tool has long depended on generating a C function
that marshals the arguments into a struct, and then the actual ABI
switch happens in functions with fixed signatures that simply take a
pointer to this struct. In a way, this CL simply pushes this idea
further.

Currently, the cgo tool generates this argument struct in the exact
layout of the Go stack frame and depends on reflectcall to unpack it
into the appropriate Go call (even though it's actually
reflectcall'ing a function generated by cgo).

In this CL, we decouple this struct from the Go stack layout. Instead,
cgo generates a Go function that takes the struct, unpacks it, and
calls the exported function. Since this generated function has a
generic signature (like the rest of the call path), we don't need
reflectcall and can instead depend on the Go compiler itself to
implement the call to the exported Go function.

One complication is that syscall.NewCallback on Windows, which
converts a Go function into a C function pointer, depends on
cgocallback's current dynamic calling approach since the signatures of
the callbacks aren't known statically. For this specific case, we
continue to depend on reflectcall. Really, the current approach makes
some overly simplistic assumptions about translating the C ABI to the
Go ABI. Now we're at least in a much better position to do a proper
ABI translation.

For comparison, the current cgo call path looks like:

    GoF (generated C function) ->
    crosscall2 (in cgo/asm_*.s) ->
    _cgoexp_GoF (generated Go function) ->
    cgocallback (in asm_*.s) ->
    cgocallback_gofunc (in asm_*.s) ->
    cgocallbackg (in cgocall.go) ->
    cgocallbackg1 (in cgocall.go) ->
    reflectcall (in asm_*.s) ->
    _cgoexpwrap_GoF (generated Go function) ->
    p.GoF

Now the call path looks like:

    GoF (generated C function) ->
    crosscall2 (in cgo/asm_*.s) ->
    cgocallback (in asm_*.s) ->
    cgocallbackg (in cgocall.go) ->
    cgocallbackg1 (in cgocall.go) ->
    _cgoexp_GoF (generated Go function) ->
    p.GoF

Notably:

1. We combine _cgoexp_GoF and _cgoexpwrap_GoF and move the combined
operation to the end of the sequence. This combined function also
handles reflectcall's previous role.

2. We combined cgocallback and cgocallback_gofunc since the only
purpose of having both was to convert a raw PC into a Go function
value. We instead construct the Go function value in cgocallbackg1.

3. cgocallbackg1 no longer reaches backwards through the stack to get
the arguments to cgocallback_gofunc. Instead, we just pass the
arguments down.

4. Currently, we need an explicit msanwrite to mark the results struct
as written because reflectcall doesn't do this. Now, the results are
written by regular Go assignments, so the Go compiler generates the
necessary MSAN annotations. This also means we no longer need to track
the size of the arguments frame.

Updates #40724, since now we don't need to teach cgo about the
register ABI or change how it uses reflectcall.

Change-Id: I7840489a2597962aeb670e0c1798a16a7359c94f
Reviewed-on: https://go-review.googlesource.com/c/go/+/258938
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
2020-10-26 14:50:32 +00:00
..
testdata cmd/compile: export notinheap annotation to object file 2020-10-05 18:52:43 +00:00
backdoor.go
buildid_linux.go misc/cgo/test: avoid endless loop when we can't parse notes 2018-01-11 19:55:49 +00:00
callback_c_gc.c
callback_c_gccgo.c
callback_c.c
callback.go runtime,cmd/cgo: simplify C -> Go call path 2020-10-26 14:50:32 +00:00
cgo_linux_test.go syscall: support POSIX semantics for Linux syscalls 2020-10-23 20:53:14 +00:00
cgo_stubs_android_test.go misc/cgo/test: consolidate tests into fewer cgo source files 2019-05-22 12:52:33 +00:00
cgo_test.go cmd/cgo: build unique C type cache keys from parent names 2019-10-05 00:16:04 +00:00
cgo_thread_lock.go
cgo_unix_test.go
cthread_unix.c cmd/dist, misc/cgo: enable tests for aix/ppc64 2019-03-20 14:38:44 +00:00
cthread_windows.c
issue1435.go syscall: support POSIX semantics for Linux syscalls 2020-10-23 20:53:14 +00:00
issue4029.c cmd/link: support cgo internal/linking on darwin/arm64 2020-10-20 02:25:52 +00:00
issue4029.go cmd/link: support cgo internal/linking on darwin/arm64 2020-10-20 02:25:52 +00:00
issue4029w.go cmd/link: support cgo internal/linking on darwin/arm64 2020-10-20 02:25:52 +00:00
issue4273.c
issue4273b.c
issue4339.c
issue4339.h
issue5548_c.c
issue5740a.c
issue5740b.c
issue6833_c.c
issue6907export_c.c cmd/cgo: permit passing string values directly between Go and C 2017-11-15 03:36:54 +00:00
issue6997_linux.c
issue6997_linux.go
issue7234_test.go
issue8148.go
issue8331.h
issue8517_windows.c
issue8517_windows.go
issue8517.go
issue8694.go
issue8811.c
issue18146.go all: add GOOS=ios 2020-09-23 18:12:59 +00:00
issue20910.c cmd/cgo: unify cgo output for gc and gccgo 2017-08-16 21:57:56 +00:00
issue21897.go misc/cgo/test: re-enable darwin cgo tests in race mode 2020-01-10 10:04:49 +00:00
issue21897b.go misc/cgo/test: re-enable darwin cgo tests in race mode 2020-01-10 10:04:49 +00:00
issue31891.c cmd/cgo: build unique C type cache keys from parent names 2019-10-05 00:16:04 +00:00
overlaydir_test.go misc: remove use of relative directories in overlayDir functions 2019-11-25 16:26:15 +00:00
pkg_test.go all: add GOOS=ios 2020-09-23 18:12:59 +00:00
setgid_linux.go
sigaltstack.go runtime: use sigaltstack on macOS/ARM64 2020-10-06 21:25:42 +00:00
sigprocmask.c misc/cgo/test: add retry loop around pthread_create in TestSigprocmask 2018-06-27 04:33:10 +00:00
sigprocmask.go misc/cgo/test: log error value in testSigprocmask 2018-04-25 20:26:39 +00:00
test_unix.go misc/cgo/test: consolidate tests into fewer cgo source files 2019-05-22 12:52:33 +00:00
test_windows.go misc/cgo/test: consolidate tests into fewer cgo source files 2019-05-22 12:52:33 +00:00
test.go all: add GOOS=ios 2020-09-23 18:12:59 +00:00
testx.go all: add GOOS=ios 2020-09-23 18:12:59 +00:00