Commit c8e7b34b authored by Ian Lance Taylor's avatar Ian Lance Taylor

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: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 277024bd
......@@ -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)
......
......@@ -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)
}
}
......@@ -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]))
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment