diff options
author | Bryan C. Mills <bcmills@google.com> | 2017-05-13 00:01:50 -0400 |
---|---|---|
committer | Bryan Mills <bcmills@google.com> | 2017-08-17 18:14:16 +0000 |
commit | d5b0ec858b3760e93722c13958dea767ab8da34b (patch) | |
tree | 65f54ece8b1df00ed5d299f47ef1e7839a40ee34 /src/plugin | |
parent | 6711fa70cecce261662c20613cc63eec0c21a16a (diff) | |
download | go-d5b0ec858b3760e93722c13958dea767ab8da34b.tar.gz go-d5b0ec858b3760e93722c13958dea767ab8da34b.zip |
{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 <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/plugin')
-rw-r--r-- | src/plugin/plugin_dlopen.go | 33 |
1 files changed, 19 insertions, 14 deletions
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)) } |