From d5b0ec858b3760e93722c13958dea767ab8da34b Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Sat, 13 May 2017 00:01:50 -0400 Subject: {net,os/user,plugin}: eliminate unnecessary C round-trips We're making two extra round-trips to C to malloc and free strings that originate in Go and don't escape. Skip those round-trips by allocating null-terminated slices in Go memory instead. Change-Id: I9e4c5ad999a7924ba50b82293c52073ec75518be Reviewed-on: https://go-review.googlesource.com/56530 Run-TryBot: Bryan Mills TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/plugin/plugin_dlopen.go | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'src/plugin/plugin_dlopen.go') diff --git a/src/plugin/plugin_dlopen.go b/src/plugin/plugin_dlopen.go index 3237598f06..ce66c036c9 100644 --- a/src/plugin/plugin_dlopen.go +++ b/src/plugin/plugin_dlopen.go @@ -81,16 +81,16 @@ func pathToPrefix(s string) string { } func open(name string) (*Plugin, error) { - cPath := (*C.char)(C.malloc(C.PATH_MAX + 1)) - defer C.free(unsafe.Pointer(cPath)) - - cRelName := C.CString(name) - defer C.free(unsafe.Pointer(cRelName)) - if C.realpath(cRelName, cPath) == nil { + cPath := make([]byte, C.PATH_MAX+1) + cRelName := make([]byte, len(name)+1) + copy(cRelName, name) + if C.realpath( + (*C.char)(unsafe.Pointer(&cRelName[0])), + (*C.char)(unsafe.Pointer(&cPath[0]))) == nil { return nil, errors.New("plugin.Open(" + name + "): realpath failed") } - filepath := C.GoString(cPath) + filepath := C.GoString((*C.char)(unsafe.Pointer(&cPath[0]))) pluginsMu.Lock() if p := plugins[filepath]; p != nil { @@ -99,7 +99,7 @@ func open(name string) (*Plugin, error) { return p, nil } var cErr *C.char - h := C.pluginOpen(cPath, &cErr) + h := C.pluginOpen((*C.char)(unsafe.Pointer(&cPath[0])), &cErr) if h == 0 { pluginsMu.Unlock() return nil, errors.New("plugin.Open: " + C.GoString(cErr)) @@ -127,9 +127,11 @@ func open(name string) (*Plugin, error) { plugins[filepath] = p pluginsMu.Unlock() - initStr := C.CString(pluginpath + ".init") - initFuncPC := C.pluginLookup(h, initStr, &cErr) - C.free(unsafe.Pointer(initStr)) + initStr := make([]byte, len(pluginpath)+6) + copy(initStr, pluginpath) + copy(initStr[len(pluginpath):], ".init") + + initFuncPC := C.pluginLookup(h, (*C.char)(unsafe.Pointer(&initStr[0])), &cErr) if initFuncPC != nil { initFuncP := &initFuncPC initFunc := *(*func())(unsafe.Pointer(&initFuncP)) @@ -144,9 +146,12 @@ func open(name string) (*Plugin, error) { delete(syms, symName) symName = symName[1:] } - cname := C.CString(pathToPrefix(pluginpath) + "." + symName) - p := C.pluginLookup(h, cname, &cErr) - C.free(unsafe.Pointer(cname)) + + fullName := pathToPrefix(pluginpath) + "." + symName + cname := make([]byte, len(fullName)+1) + copy(cname, fullName) + + p := C.pluginLookup(h, (*C.char)(unsafe.Pointer(&cname[0])), &cErr) if p == nil { return nil, errors.New("plugin.Open: could not find symbol " + symName + ": " + C.GoString(cErr)) } -- cgit v1.3