]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: skip cgo check for non-pointer slice elements
authorIan Lance Taylor <iant@golang.org>
Thu, 18 Feb 2016 19:04:05 +0000 (11:04 -0800)
committerIan Lance Taylor <iant@golang.org>
Fri, 19 Feb 2016 16:07:27 +0000 (16:07 +0000)
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>
src/runtime/cgocall.go
src/runtime/crash_cgo_test.go
src/runtime/testdata/testprogcgo/cgo.go

index 66115fd8b49bd01ad915a891040427e5a4cc1b95..fef8add46feb1b3c60b4de3da94db33006d38188 100644 (file)
@@ -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)
index d7b367f941f4a35e89a8d77828e105e2757dd97a..7685582aa8ad9485f527cf07ac71aed807ce72a0 100644 (file)
@@ -7,10 +7,12 @@
 package runtime_test
 
 import (
+       "internal/testenv"
        "os/exec"
        "runtime"
        "strings"
        "testing"
+       "time"
 )
 
 func TestCgoCrashHandler(t *testing.T) {
@@ -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)
+       }
+}
index cf1af8268caec36f029856a0cb47fa157587562a..5d2550dbb0343542bac5f3ee5ee64edd41d353c3 100644 (file)
@@ -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() {
@@ -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]))
+       }
+}