Open aclements opened 4 years ago
Change https://golang.org/cl/305330 mentions this issue: runtime: add GC testing helpers for regabi signature fuzzer
Change https://golang.org/cl/305669 mentions this issue: runtime: use ABIInternal for closure calls from assembly
Change https://golang.org/cl/305671 mentions this issue: cmd/compile: emit writebarriers in specified ABI
One example is to interface with the Core Audio APIs. In this specific case, the support for callbacks with floating point argument is needed.
@emarj, are you saying that there's already Go code that calls these, or just giving a theoretical example? Unless I'm completely misunderstanding the Windows calling convention, it has never worked for a Go callback to accept floating-point arguments. As of Go 1.16 NewCallback
will actually panic, but before that it would simply do the wrong thing. If it's a theoretical example, it would great if you could open a new issue about adding support for floating-point Windows callback arguments so we can track that separately.
Change https://golang.org/cl/305672 mentions this issue: cmd/compile: make expandCalls preserve types of pointer stores
Change https://golang.org/cl/305550 mentions this issue: cmd/compile: wrap defer/go call with results
Change https://golang.org/cl/304771 mentions this issue: cmd/compile: be sure to wrap defer/go calls with arguments
Change https://golang.org/cl/305549 mentions this issue: cmd/compile: check deferred nil interface call before wrapping it
@emarj, are you saying that there's already Go code that calls these, or just giving a theoretical example? Unless I'm completely misunderstanding the Windows calling convention, it has never worked for a Go callback to accept floating-point arguments. As of Go 1.16
NewCallback
will actually panic, but before that it would simply do the wrong thing. If it's a theoretical example, it would great if you could open a new issue about adding support for floating-point Windows callback arguments so we can track that separately.
@aclements I'm sorry for the confusion. There are pure Go libraries that implements these Windows APIs, but they are incomplete for this reason (i.e. they cannot implement callbacks). There is no (afaik) actual code that does that, because, as you said, it is not possible at the moment. I discover that myself trying to improve one of those libraries (https://github.com/moutend/go-wca for reference).
I commented here since I saw there is work being done in the "calling conventions area" and maybe this could be addressed. But now I understand it is better to open a new issue, since this is a feature request.
Change https://golang.org/cl/305829 mentions this issue: cmd/compile: make amd64 version of zerorange regabi-friendly
Change https://golang.org/cl/305849 mentions this issue: dashboard: add windows- and darwin- amd64-regabi builders
@emarj , thanks for opening the issue! You're right that they're related issues. We're in a much better place to support floating-point arguments to callbacks now. Previously NewCallback could sort of pretend that the Windows calling convention and Go calling convention were close enough that it didn't need to do any complicated translation, and adding floating-point to that would have been really hard. With Go switching to a register-based calling convention, it has to really understand both calling conventions and translate between them, so adding floating-point support now is actually much easier.
Change https://golang.org/cl/306009 mentions this issue: runtime: check that defer/go frames are empty
Change https://golang.org/cl/306010 mentions this issue: runtime: replace reflectcall of defers with direct call
Change https://golang.org/cl/306109 mentions this issue: reflect: undo register count increments on register assignment failure
Change https://golang.org/cl/306409 mentions this issue: cmd/compile: fix incoming ABI with GOEXPERIMENT=regabiargs
Change https://golang.org/cl/306410 mentions this issue: cmd/compile: fix outgoing calls with GOEXPERIMENT=regabiargs
As of tip:
$ cat hello.go
package main
func main() {
println("hello with registers")
}
$ GOEXPERIMENT=regabi,regabiargs go run hello.go
hello with registers
This means the full register ABI is running well enough to bring up the whole runtime (including the scheduler, GC, starting lots of threads and goroutines, allocating a bunch, etc) and get to main.main.
Change https://golang.org/cl/306469 mentions this issue: cmd/compile: fix register/offset calculation for trailing empty field case.
Change https://golang.org/cl/306571 mentions this issue: reflect,runtime: assume register ABI with GOEXPERIMENT=regabiargs
Change https://golang.org/cl/306869 mentions this issue: cmd/compile: mark unused values as invalid to prevent problems in expandCalls
Change https://golang.org/cl/306929 mentions this issue: reflect: remove short-circuits for zero-sized types in ABI algorithm
Change https://golang.org/cl/306910 mentions this issue: runtime: make concatstring{2,3,4,5} consistent w/ compiler's use
Change https://golang.org/cl/306931 mentions this issue: runtime: make reflectcall ABI0 on amd64
Change https://golang.org/cl/307009 mentions this issue: cmd/internal/obj: use REGENTRYTMP* in a few more places
Change https://golang.org/cl/304470 mentions this issue: cmd/compile, runtime: add metadata for argument printing in traceback
Change https://golang.org/cl/307309 mentions this issue: cmd/compile: add "surprised by IData of Arg" case for register args
Change https://golang.org/cl/307229 mentions this issue: cmd/link: mangle function name with ABI on Mach-O
Change https://golang.org/cl/307232 mentions this issue: cmd/compile, runtime: use ABI-aware function converting float to interface
Change https://golang.org/cl/307231 mentions this issue: cmd/compile: load results into registers on open defer return path
Change https://golang.org/cl/307235 mentions this issue: cmd/compile: untangle Wrapper and ABIWrapper flags
Change https://golang.org/cl/307234 mentions this issue: cmd/compile: disable tail call for method wrappers when RegabiArgs is enabled
Change https://golang.org/cl/307233 mentions this issue: cmd/compile: reference ABIInternal memequal_varlen
Change https://golang.org/cl/307390 mentions this issue: runtime: mark abort as ABIInternal on amd64
Change https://golang.org/cl/307391 mentions this issue: runtime: use funcID to identify abort in isAbortPC
Change https://golang.org/cl/307236 mentions this issue: cmd/compile: enable panic+recover adjustment for some ABI wrappers
Change https://golang.org/cl/307237 mentions this issue: reflect: call ABI0 callReflect/callMethod
Change https://golang.org/cl/307529 mentions this issue: cmd/compile: check for unused OpArg* and mark invalid (again)
Change https://golang.org/cl/307829 mentions this issue: cmd/compile/internal/amd64: follow-on regabi fix for amd64 zerorange
Change https://golang.org/cl/307869 mentions this issue: reflect: refactor funcLayout tests
Change https://golang.org/cl/307909 mentions this issue: cmd/compile: pre-spill pointers in aggregate-typed register args
Change https://golang.org/cl/307872 mentions this issue: runtime: set up read-only dummy TLS space for needm on Windows
Change https://golang.org/cl/308189 mentions this issue: reflect: fix typo in result-in-registers case
Change https://golang.org/cl/308309 mentions this issue: cmd/compile: sanitize before/after expansion OpSelectN references
Change https://golang.org/cl/308510 mentions this issue: cmd/compile: ensure spills of int/float reg args land in abi slots
Change https://golang.org/cl/308069 mentions this issue: cmd/compile: fix buglet in walk convert phase relating to convT64
Change https://golang.org/cl/308589 mentions this issue: cmd/compile: add recursive-invalidate Value method, use in expand_calls
Change https://golang.org/cl/308590 mentions this issue: test/abi: clean up test to fix builders
Change https://golang.org/cl/308689 mentions this issue: cmd/compile: fix buglet in walk convert phase relating to convF32/64
Change https://golang.org/cl/308889 mentions this issue: test/abi: disable test on windows for now
I propose that we switch the Go internal ABI (used between Go functions) from stack-based to register-based argument and result passing for Go ~1.16~ 1.17.
I lay out the details of our proposal and the work required in this document.
The ABI specification can be found here.
This was previously proposed in #18597, where @dr2chase did some excellent prototyping work that our new proposal builds on. With multiple ABI support, we’re now in a much better position to execute on this without breaking compatibility with the existing body of Go assembly code. I’ve opened this new issue to focus on discussion of our new proposal.
/cc @dr2chase @danscales @thanm @cherrymui @mknyszek @prattmic @randall77
An incomplete and evolving list of tasks:
defer recover()
(@cherrymui, CL)RegEntryTmp
registers in prologue (@mknyszek, CL)WriteFuncMap
) (@dr2chase, CL)cgo_unsafe_args
generate an ABI0 function (or an ABIInternal-with-no-registers function) (@cherrymui, CL)High-priority non-critical path
funcPC
always return the "native" PC of a function (maybe also introduceABIOther
) (@cherrymui, CL)funcPC
is inargs_stackmap
in ABIInternal functions (because it's for ABI0) (CL)reflect.ValueOf(fn).Pointer()
to get the PC of an assembly function will now return the PC of the ABI wrapperEnabling steps
Testing
reflect.{ValueOf(target),MakeFunc(x, target),Method(x)}.{Call,Interface}
, called fromdefer
, called fromgo
, called as a finalizerdefer
in a test function (check arguments, modify results)MoveStackOnNextCall
, assertions for pointer-to-stack/pointer-to-heap, assertions for live/dead (@aclements, CL)Post-MVP
Cleanup (can be done later)
go
in runtime (context)ir.Func
to functionir.Name
s (context)firstpos
inssa.go
– sometimes it's late.