Skip to content

Commit

Permalink
runtime: skip cgo check for non-pointer slice elements
Browse files Browse the repository at this point in the history
Fixes #14387.

Change-Id: Icc98be80f549c5e1f55c5e693bfea97b456a6c41
Reviewed-on: https://go-review.googlesource.com/19621
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/22036
Reviewed-by: Ian Lance Taylor <iant@golang.org>
  • Loading branch information
ianlancetaylor authored and adg committed Apr 14, 2016
1 parent 406752b commit 512261e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/runtime/cgocall.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,9 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if !top {
panic(errorString(msg))
}
if st.elem.kind&kindNoPointers != 0 {
return
}
for i := 0; i < s.cap; i++ {
cgoCheckArg(st.elem, p, true, false, msg)
p = add(p, st.elem.size)
Expand Down
31 changes: 31 additions & 0 deletions src/runtime/crash_cgo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
package runtime_test

import (
"internal/testenv"
"os/exec"
"runtime"
"strings"
"testing"
"time"
)

func TestCgoCrashHandler(t *testing.T) {
Expand Down Expand Up @@ -147,3 +149,32 @@ func TestEnsureDropM(t *testing.T) {
t.Errorf("expected %q, got %v", want, got)
}
}

// Test for issue 14387.
// Test that the program that doesn't need any cgo pointer checking
// takes about the same amount of time with it as without it.
func TestCgoCheckBytes(t *testing.T) {
// Make sure we don't count the build time as part of the run time.
testenv.MustHaveGoBuild(t)
exe, err := buildTestProg(t, "testprogcgo")
if err != nil {
t.Fatal(err)
}

cmd := testEnv(exec.Command(exe, "CgoCheckBytes"))

start := time.Now()
cmd.Run()
d1 := time.Since(start)

cmd = testEnv(exec.Command(exe, "CgoCheckBytes"))
cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0")

start = time.Now()
cmd.Run()
d2 := time.Since(start)

if d2*10 < d1 {
t.Errorf("cgo check too slow: got %v, expected at most %v", d1, d2*10)
}
}
10 changes: 10 additions & 0 deletions src/runtime/testdata/testprogcgo/cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ package main

/*
void foo1(void) {}
void foo2(void* p) {}
*/
import "C"
import (
"fmt"
"runtime"
"time"
"unsafe"
)

func init() {
register("CgoSignalDeadlock", CgoSignalDeadlock)
register("CgoTraceback", CgoTraceback)
register("CgoCheckBytes", CgoCheckBytes)
}

func CgoSignalDeadlock() {
Expand Down Expand Up @@ -78,3 +81,10 @@ func CgoTraceback() {
runtime.Stack(buf, true)
fmt.Printf("OK\n")
}

func CgoCheckBytes() {
b := make([]byte, 1e6)
for i := 0; i < 1e3; i++ {
C.foo2(unsafe.Pointer(&b[0]))
}
}

0 comments on commit 512261e

Please sign in to comment.