cmd/cgo: optimize cgoCheckPointer call

Currently cgoCheckPointer is only used with one optional argument.
Using a slice for the optional arguments is quite expensive, hence
replace it with a single interface{}. This results in ~30% improvement.

When checking struct fields, they quite often end up being without
pointers. Check this before calling cgoCheckPointer, which results in
additional ~20% improvement.

Inline some p == nil checks from cgoIsGoPointer which gives
additional ~15% improvement.

All of this translates to:

name                             old time/op  new time/op  delta
CgoCall/add-int-32               46.9ns ± 1%  46.6ns ± 1%   -0.75%  (p=0.000 n=18+20)
CgoCall/one-pointer-32            143ns ± 1%    87ns ± 1%  -38.96%  (p=0.000 n=20+20)
CgoCall/eight-pointers-32         767ns ± 0%   327ns ± 1%  -57.30%  (p=0.000 n=18+16)
CgoCall/eight-pointers-nil-32     110ns ± 1%    89ns ± 2%  -19.10%  (p=0.000 n=19+19)
CgoCall/eight-pointers-array-32  5.09µs ± 1%  3.56µs ± 2%  -30.09%  (p=0.000 n=19+19)
CgoCall/eight-pointers-slice-32  3.92µs ± 0%  2.57µs ± 2%  -34.48%  (p=0.000 n=20+20)

Change-Id: I2aa9f5ae8962a9a41a7fb1db0c300893109d0d75
Reviewed-on: https://go-review.googlesource.com/c/go/+/198081
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Egon Elbre 2019-10-01 18:12:55 +03:00 committed by Ian Lance Taylor
parent 30d7b64008
commit e85ffec784
4 changed files with 98 additions and 20 deletions

View file

@ -1631,14 +1631,14 @@ func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr)
//go:linkname _cgoCheckPointer runtime.cgoCheckPointer
func _cgoCheckPointer(interface{}, ...interface{})
func _cgoCheckPointer(interface{}, interface{})
//go:linkname _cgoCheckResult runtime.cgoCheckResult
func _cgoCheckResult(interface{})
`
const gccgoGoProlog = `
func _cgoCheckPointer(interface{}, ...interface{})
func _cgoCheckPointer(interface{}, interface{})
func _cgoCheckResult(interface{})
`
@ -1825,16 +1825,16 @@ typedef struct __go_empty_interface {
void *__object;
} Eface;
extern void runtimeCgoCheckPointer(Eface, Slice)
extern void runtimeCgoCheckPointer(Eface, Eface)
__asm__("runtime.cgoCheckPointer")
__attribute__((weak));
extern void localCgoCheckPointer(Eface, Slice)
extern void localCgoCheckPointer(Eface, Eface)
__asm__("GCCGOSYMBOLPREF._cgoCheckPointer");
void localCgoCheckPointer(Eface ptr, Slice args) {
void localCgoCheckPointer(Eface ptr, Eface arg) {
if(runtimeCgoCheckPointer) {
runtimeCgoCheckPointer(ptr, args);
runtimeCgoCheckPointer(ptr, arg);
}
}