mirror of
https://github.com/golang/go
synced 2024-11-17 04:04:46 -07:00
91102bf723
bytes.IndexByte is heavily optimized. Use it in findnull. This is second attempt, similar to CL97523. In this version we never call IndexByte on region of memory, that crosses page boundary. A bit slower than CL97523, but still fast: name old time/op new time/op delta GoString-6 164ns ± 2% 118ns ± 0% -28.00% (p=0.000 n=10+6) findnull is also used in gostringnocopy, which is used in many hot spots in the runtime. Fixes #23830 Change-Id: Id843dd4f65a34309d92bdd8df229e484d26b0cb2 Reviewed-on: https://go-review.googlesource.com/98015 Run-TryBot: Ilya Tocar <ilya.tocar@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
55 lines
1.4 KiB
Go
55 lines
1.4 KiB
Go
// +build amd64,linux
|
|
|
|
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package cgotest
|
|
|
|
// Test that C.GoString uses IndexByte in safe manner.
|
|
|
|
/*
|
|
#include <sys/mman.h>
|
|
|
|
// Returns string with null byte at the last valid address
|
|
char* dangerousString1() {
|
|
int pageSize = 4096;
|
|
char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
|
|
mprotect(data + pageSize,pageSize,PROT_NONE);
|
|
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
|
|
int i = start;
|
|
for (; i < pageSize; i++) {
|
|
data[i] = 'x';
|
|
}
|
|
data[pageSize -1 ] = 0;
|
|
return data+start;
|
|
}
|
|
|
|
char* dangerousString2() {
|
|
int pageSize = 4096;
|
|
char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
|
|
mprotect(data + 2 * pageSize,pageSize,PROT_NONE);
|
|
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
|
|
int i = start;
|
|
for (; i < 2 * pageSize; i++) {
|
|
data[i] = 'x';
|
|
}
|
|
data[2*pageSize -1 ] = 0;
|
|
return data+start;
|
|
}
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func test24206(t *testing.T) {
|
|
if l := len(C.GoString(C.dangerousString1())); l != 123 {
|
|
t.Errorf("Incorrect string length - got %d, want 123", l)
|
|
}
|
|
if l := len(C.GoString(C.dangerousString2())); l != 4096+123 {
|
|
t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123)
|
|
}
|
|
}
|