Pardon the wide distribution, the obvious hacks, and the failure to properly split up the largest of the libffi patches.
The background here is my thread from last week[1], and Ian's reply[2], wherein he rightly points out that not needing to play games with mmap in order to implement closures for Go is a strong reason to continue using custom code within libgo. While that thread did have a go at implementing that custom code for aarch64, I still think that replicating libffi's calling convention knowledge for every interesting target is a mistake. So instead I thought about how I'd add some support for Go directly into libffi. After all, we've got some custom code in libffi for Java, why couldn't Go have the same treatment? The stickler, as far as I could see, is __go_set_context. I didn't like the idea of libffi needing a callback into libgo in order to accomplish the goal. But the comment immediately before __go_set_closure itself says that it would be better to use the static chain register. So I set about to see how easy that would be to accomplish. (And not for nothing such a change would make gccgo compiled programs faster by avoiding the library calls.) The following patch set enables this for x86_64, i386, and aarch64[3]. The first two patches enable a static chain to be set by the front end on CALL_EXPRs, and to be used with indirect function calls. The third patch is a horrible hack to expose this feature to the C front end. The 4th patch changes gccgo to use the static chain. I don't bother with checking to see that the target has one. All targets currently supported by libgo have one, so I don't really see this as a stumbling block. The 5th patch changes libgo to use the static chain. I admit that I haven't tested this patch solo; I simply split it out of a larger patch for clarity. The 6th patch adds interfaces to libffi for Go; these interfaces are used within libgo in the 8th patch. Patches 7, 10, 11, 12, 13 are all enabling the new libffi interface on the aforementioned targets. There's lots of cleanup in here, and I owe the libffi list smaller reviewable changes. I ask that libffi ignore patches 10 and 12 for now and comment on the meat instead. Before I go too much farther down this road, I wanted to get some feedback. FWIW, a complete tree can be found at [4]. Thanks, r~ [1] https://gcc.gnu.org/ml/gcc-patches/2014-10/msg00098.html [2] https://gcc.gnu.org/ml/gcc-patches/2014-10/msg00102.html [3] Except that after rebasing the tree on yesterday's trunk, I discovered that i386 and aarch64 both have bootstrap problems on trunk. Ouch. [4] git://github.com/rth7680/gcc.git rth/go-closure Richard Henderson (13): Make TARGET_STATIC_CHAIN allow a function type Allow the front-end to create calls with a static chain HACK! Allow the static chain to be set from C Use the static chain as the closure parameter from Go libgo: Use the static chain for the closure libffi: Add entry points for interacting with Go libffi: Support go closures on x86_64 libgo: Use the new libffi interfaces for Go libgo: Remove __go_get/set_closure libffi: Rewrite aarch64 libffi: Support go closures on aarch64 libffi: Rewrite i386 sysv libffi: Support go closures on i386 gcc/c-family/c-common.c | 1 + gcc/c-family/c-common.h | 2 +- gcc/c/c-parser.c | 29 + gcc/calls.c | 14 +- gcc/config/i386/i386.c | 19 +- gcc/config/moxie/moxie.c | 5 +- gcc/config/xtensa/xtensa.c | 2 +- gcc/doc/tm.texi | 2 +- gcc/gimple-fold.c | 21 + gcc/gimplify.c | 17 +- gcc/go/go-gcc.cc | 44 +- gcc/go/gofrontend/backend.h | 7 +- gcc/go/gofrontend/expressions.cc | 21 +- gcc/go/gofrontend/gogo.cc | 29 +- gcc/go/gofrontend/gogo.h | 14 + gcc/go/gofrontend/runtime.def | 6 - gcc/target.def | 6 +- gcc/targhooks.c | 5 +- gcc/testsuite/gcc.dg/static-chain.c | 31 + gcc/tree-cfg.c | 22 +- libffi/include/ffi.h.in | 16 + libffi/src/aarch64/ffi.c | 1380 ++++++++++++++--------------------- libffi/src/aarch64/ffitarget.h | 18 +- libffi/src/aarch64/internal.h | 43 ++ libffi/src/aarch64/sysv.S | 557 +++++++------- libffi/src/x86/ffi.c | 1161 ++++++++++++----------------- libffi/src/x86/ffi64.c | 103 ++- libffi/src/x86/ffitarget.h | 112 ++- libffi/src/x86/internal.h | 48 ++ libffi/src/x86/sysv.S | 1003 +++++++++++++++---------- libffi/src/x86/unix64.S | 319 ++++---- libgo/go/reflect/makefunc.go | 49 +- libgo/go/reflect/makefunc_386.S | 22 +- libgo/go/reflect/makefunc_amd64.S | 13 +- libgo/go/reflect/makefunc_ffi.go | 67 +- libgo/go/reflect/makefunc_ffi_c.c | 68 +- libgo/go/reflect/value.go | 3 + libgo/runtime/go-reflect-call.c | 10 +- libgo/runtime/malloc.goc | 8 - libgo/runtime/mgc0.c | 3 +- libgo/runtime/proc.c | 20 - libgo/runtime/runtime.h | 4 - libgo/runtime/time.goc | 3 +- 43 files changed, 2624 insertions(+), 2703 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/static-chain.c create mode 100644 libffi/src/aarch64/internal.h create mode 100644 libffi/src/x86/internal.h -- 1.9.3