mirror of
https://github.com/golang/go.git
synced 2025-05-13 03:14:40 +00:00
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)
|
|
}
|
|
}
|