aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-02-18 11:04:05 -0800
committerAndrew Gerrand <adg@golang.org>2016-04-14 05:20:32 +0000
commit512261e50e90c7fb064b825c7fab67e95a3142ab (patch)
tree01916b5b9b2e83aa03b9cb1ffde6f8291b3246b5
parent406752b640fcc56a9287b8454564cffe2f0021c1 (diff)
downloadgo-512261e50e90c7fb064b825c7fab67e95a3142ab.tar.gz
go-512261e50e90c7fb064b825c7fab67e95a3142ab.zip
runtime: skip cgo check for non-pointer slice elements
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>
-rw-r--r--src/runtime/cgocall.go3
-rw-r--r--src/runtime/crash_cgo_test.go31
-rw-r--r--src/runtime/testdata/testprogcgo/cgo.go10
3 files changed, 44 insertions, 0 deletions
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 66115fd8b4..fef8add46f 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -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)
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index d7b367f941..7685582aa8 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -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)
+ }
+}
diff --git a/src/runtime/testdata/testprogcgo/cgo.go b/src/runtime/testdata/testprogcgo/cgo.go
index cf1af8268c..5d2550dbb0 100644
--- a/src/runtime/testdata/testprogcgo/cgo.go
+++ b/src/runtime/testdata/testprogcgo/cgo.go
@@ -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]))
+ }
+}