aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/go-patches
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-10-11 21:50:32 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2021-10-11 21:50:32 -0600
commite5cfd498576dc7bda771fa7987765bb1dbe9f4f8 (patch)
tree2e9cb14d36571d92808540c8513fc1b18f483896 /go-patches
parentglobal: use unsafe.Slice instead of unsafeSlice (diff)
downloadwireguard-windows-e5cfd498576dc7bda771fa7987765bb1dbe9f4f8.tar.xz
wireguard-windows-e5cfd498576dc7bda771fa7987765bb1dbe9f4f8.zip
go-patches: make unsafe.Slice fast
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'go-patches')
-rw-r--r--go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch2
-rw-r--r--go-patches/0002-release-branch.go1.17-cmd-compile-speed-up-unsafe.Sl.patch331
2 files changed, 332 insertions, 1 deletions
diff --git a/go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch b/go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch
index c2a5dd52..b72675bd 100644
--- a/go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch
+++ b/go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch
@@ -55,5 +55,5 @@ index 5a4ceaf43d..68c01805a5 100644
return write1(fd, p, n)
}
--
-2.32.0
+2.33.0
diff --git a/go-patches/0002-release-branch.go1.17-cmd-compile-speed-up-unsafe.Sl.patch b/go-patches/0002-release-branch.go1.17-cmd-compile-speed-up-unsafe.Sl.patch
new file mode 100644
index 00000000..42a71f88
--- /dev/null
+++ b/go-patches/0002-release-branch.go1.17-cmd-compile-speed-up-unsafe.Sl.patch
@@ -0,0 +1,331 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Mon, 11 Oct 2021 21:31:47 -0600
+Subject: [PATCH] [release-branch.go1.17] cmd/compile: speed up unsafe.Slice by
+ omitting checks
+
+unsafe.Slice is already an unsafe operation, like unsafe.Pointer casts.
+So, assume the user knows what they're doing, unless checkptr is used,
+in which case, we can then emit the checker code, just like
+unsafe.Pointer casts do.
+
+Fixes #48798.
+
+Change-Id: Ice1f615b49fe13556f71495f303d4ff0eb794bd9
+---
+ src/cmd/compile/internal/typecheck/builtin.go | 179 +++++++++---------
+ .../internal/typecheck/builtin/runtime.go | 2 -
+ src/cmd/compile/internal/walk/builtin.go | 19 +-
+ test/unsafebuiltins.go | 30 +--
+ 4 files changed, 92 insertions(+), 138 deletions(-)
+
+diff --git a/src/cmd/compile/internal/typecheck/builtin.go b/src/cmd/compile/internal/typecheck/builtin.go
+index 833b17b414..add59020a7 100644
+--- a/src/cmd/compile/internal/typecheck/builtin.go
++++ b/src/cmd/compile/internal/typecheck/builtin.go
+@@ -136,72 +136,70 @@ var runtimeDecls = [...]struct {
+ {"makeslice64", funcTag, 113},
+ {"makeslicecopy", funcTag, 114},
+ {"growslice", funcTag, 116},
+- {"unsafeslice", funcTag, 117},
+- {"unsafeslice64", funcTag, 118},
+- {"unsafeslicecheckptr", funcTag, 118},
+- {"memmove", funcTag, 119},
+- {"memclrNoHeapPointers", funcTag, 120},
+- {"memclrHasPointers", funcTag, 120},
+- {"memequal", funcTag, 121},
+- {"memequal0", funcTag, 122},
+- {"memequal8", funcTag, 122},
+- {"memequal16", funcTag, 122},
+- {"memequal32", funcTag, 122},
+- {"memequal64", funcTag, 122},
+- {"memequal128", funcTag, 122},
+- {"f32equal", funcTag, 123},
+- {"f64equal", funcTag, 123},
+- {"c64equal", funcTag, 123},
+- {"c128equal", funcTag, 123},
+- {"strequal", funcTag, 123},
+- {"interequal", funcTag, 123},
+- {"nilinterequal", funcTag, 123},
+- {"memhash", funcTag, 124},
+- {"memhash0", funcTag, 125},
+- {"memhash8", funcTag, 125},
+- {"memhash16", funcTag, 125},
+- {"memhash32", funcTag, 125},
+- {"memhash64", funcTag, 125},
+- {"memhash128", funcTag, 125},
+- {"f32hash", funcTag, 125},
+- {"f64hash", funcTag, 125},
+- {"c64hash", funcTag, 125},
+- {"c128hash", funcTag, 125},
+- {"strhash", funcTag, 125},
+- {"interhash", funcTag, 125},
+- {"nilinterhash", funcTag, 125},
+- {"int64div", funcTag, 126},
+- {"uint64div", funcTag, 127},
+- {"int64mod", funcTag, 126},
+- {"uint64mod", funcTag, 127},
+- {"float64toint64", funcTag, 128},
+- {"float64touint64", funcTag, 129},
+- {"float64touint32", funcTag, 130},
+- {"int64tofloat64", funcTag, 131},
+- {"uint64tofloat64", funcTag, 132},
+- {"uint32tofloat64", funcTag, 133},
+- {"complex128div", funcTag, 134},
+- {"getcallerpc", funcTag, 135},
+- {"getcallersp", funcTag, 135},
++ {"unsafeslicecheckptr", funcTag, 117},
++ {"memmove", funcTag, 118},
++ {"memclrNoHeapPointers", funcTag, 119},
++ {"memclrHasPointers", funcTag, 119},
++ {"memequal", funcTag, 120},
++ {"memequal0", funcTag, 121},
++ {"memequal8", funcTag, 121},
++ {"memequal16", funcTag, 121},
++ {"memequal32", funcTag, 121},
++ {"memequal64", funcTag, 121},
++ {"memequal128", funcTag, 121},
++ {"f32equal", funcTag, 122},
++ {"f64equal", funcTag, 122},
++ {"c64equal", funcTag, 122},
++ {"c128equal", funcTag, 122},
++ {"strequal", funcTag, 122},
++ {"interequal", funcTag, 122},
++ {"nilinterequal", funcTag, 122},
++ {"memhash", funcTag, 123},
++ {"memhash0", funcTag, 124},
++ {"memhash8", funcTag, 124},
++ {"memhash16", funcTag, 124},
++ {"memhash32", funcTag, 124},
++ {"memhash64", funcTag, 124},
++ {"memhash128", funcTag, 124},
++ {"f32hash", funcTag, 124},
++ {"f64hash", funcTag, 124},
++ {"c64hash", funcTag, 124},
++ {"c128hash", funcTag, 124},
++ {"strhash", funcTag, 124},
++ {"interhash", funcTag, 124},
++ {"nilinterhash", funcTag, 124},
++ {"int64div", funcTag, 125},
++ {"uint64div", funcTag, 126},
++ {"int64mod", funcTag, 125},
++ {"uint64mod", funcTag, 126},
++ {"float64toint64", funcTag, 127},
++ {"float64touint64", funcTag, 128},
++ {"float64touint32", funcTag, 129},
++ {"int64tofloat64", funcTag, 130},
++ {"uint64tofloat64", funcTag, 131},
++ {"uint32tofloat64", funcTag, 132},
++ {"complex128div", funcTag, 133},
++ {"getcallerpc", funcTag, 134},
++ {"getcallersp", funcTag, 134},
+ {"racefuncenter", funcTag, 31},
+ {"racefuncexit", funcTag, 9},
+ {"raceread", funcTag, 31},
+ {"racewrite", funcTag, 31},
+- {"racereadrange", funcTag, 136},
+- {"racewriterange", funcTag, 136},
+- {"msanread", funcTag, 136},
+- {"msanwrite", funcTag, 136},
+- {"msanmove", funcTag, 137},
+- {"checkptrAlignment", funcTag, 138},
+- {"checkptrArithmetic", funcTag, 140},
+- {"libfuzzerTraceCmp1", funcTag, 141},
+- {"libfuzzerTraceCmp2", funcTag, 142},
+- {"libfuzzerTraceCmp4", funcTag, 143},
+- {"libfuzzerTraceCmp8", funcTag, 144},
+- {"libfuzzerTraceConstCmp1", funcTag, 141},
+- {"libfuzzerTraceConstCmp2", funcTag, 142},
+- {"libfuzzerTraceConstCmp4", funcTag, 143},
+- {"libfuzzerTraceConstCmp8", funcTag, 144},
++ {"racereadrange", funcTag, 135},
++ {"racewriterange", funcTag, 135},
++ {"msanread", funcTag, 135},
++ {"msanwrite", funcTag, 135},
++ {"msanmove", funcTag, 136},
++ {"checkptrAlignment", funcTag, 137},
++ {"checkptrArithmetic", funcTag, 139},
++ {"libfuzzerTraceCmp1", funcTag, 140},
++ {"libfuzzerTraceCmp2", funcTag, 141},
++ {"libfuzzerTraceCmp4", funcTag, 142},
++ {"libfuzzerTraceCmp8", funcTag, 143},
++ {"libfuzzerTraceConstCmp1", funcTag, 140},
++ {"libfuzzerTraceConstCmp2", funcTag, 141},
++ {"libfuzzerTraceConstCmp4", funcTag, 142},
++ {"libfuzzerTraceConstCmp8", funcTag, 143},
+ {"x86HasPOPCNT", varTag, 6},
+ {"x86HasSSE41", varTag, 6},
+ {"x86HasFMA", varTag, 6},
+@@ -224,7 +222,7 @@ func params(tlist ...*types.Type) []*types.Field {
+ }
+
+ func runtimeTypes() []*types.Type {
+- var typs [145]*types.Type
++ var typs [144]*types.Type
+ typs[0] = types.ByteType
+ typs[1] = types.NewPtr(typs[0])
+ typs[2] = types.Types[types.TANY]
+@@ -342,33 +340,32 @@ func runtimeTypes() []*types.Type {
+ typs[114] = newSig(params(typs[1], typs[15], typs[15], typs[7]), params(typs[7]))
+ typs[115] = types.NewSlice(typs[2])
+ typs[116] = newSig(params(typs[1], typs[115], typs[15]), params(typs[115]))
+- typs[117] = newSig(params(typs[1], typs[7], typs[15]), nil)
+- typs[118] = newSig(params(typs[1], typs[7], typs[22]), nil)
+- typs[119] = newSig(params(typs[3], typs[3], typs[5]), nil)
+- typs[120] = newSig(params(typs[7], typs[5]), nil)
+- typs[121] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
+- typs[122] = newSig(params(typs[3], typs[3]), params(typs[6]))
+- typs[123] = newSig(params(typs[7], typs[7]), params(typs[6]))
+- typs[124] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5]))
+- typs[125] = newSig(params(typs[7], typs[5]), params(typs[5]))
+- typs[126] = newSig(params(typs[22], typs[22]), params(typs[22]))
+- typs[127] = newSig(params(typs[24], typs[24]), params(typs[24]))
+- typs[128] = newSig(params(typs[20]), params(typs[22]))
+- typs[129] = newSig(params(typs[20]), params(typs[24]))
+- typs[130] = newSig(params(typs[20]), params(typs[60]))
+- typs[131] = newSig(params(typs[22]), params(typs[20]))
+- typs[132] = newSig(params(typs[24]), params(typs[20]))
+- typs[133] = newSig(params(typs[60]), params(typs[20]))
+- typs[134] = newSig(params(typs[26], typs[26]), params(typs[26]))
+- typs[135] = newSig(nil, params(typs[5]))
+- typs[136] = newSig(params(typs[5], typs[5]), nil)
+- typs[137] = newSig(params(typs[5], typs[5], typs[5]), nil)
+- typs[138] = newSig(params(typs[7], typs[1], typs[5]), nil)
+- typs[139] = types.NewSlice(typs[7])
+- typs[140] = newSig(params(typs[7], typs[139]), nil)
+- typs[141] = newSig(params(typs[64], typs[64]), nil)
+- typs[142] = newSig(params(typs[58], typs[58]), nil)
+- typs[143] = newSig(params(typs[60], typs[60]), nil)
+- typs[144] = newSig(params(typs[24], typs[24]), nil)
++ typs[117] = newSig(params(typs[1], typs[7], typs[22]), nil)
++ typs[118] = newSig(params(typs[3], typs[3], typs[5]), nil)
++ typs[119] = newSig(params(typs[7], typs[5]), nil)
++ typs[120] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
++ typs[121] = newSig(params(typs[3], typs[3]), params(typs[6]))
++ typs[122] = newSig(params(typs[7], typs[7]), params(typs[6]))
++ typs[123] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5]))
++ typs[124] = newSig(params(typs[7], typs[5]), params(typs[5]))
++ typs[125] = newSig(params(typs[22], typs[22]), params(typs[22]))
++ typs[126] = newSig(params(typs[24], typs[24]), params(typs[24]))
++ typs[127] = newSig(params(typs[20]), params(typs[22]))
++ typs[128] = newSig(params(typs[20]), params(typs[24]))
++ typs[129] = newSig(params(typs[20]), params(typs[60]))
++ typs[130] = newSig(params(typs[22]), params(typs[20]))
++ typs[131] = newSig(params(typs[24]), params(typs[20]))
++ typs[132] = newSig(params(typs[60]), params(typs[20]))
++ typs[133] = newSig(params(typs[26], typs[26]), params(typs[26]))
++ typs[134] = newSig(nil, params(typs[5]))
++ typs[135] = newSig(params(typs[5], typs[5]), nil)
++ typs[136] = newSig(params(typs[5], typs[5], typs[5]), nil)
++ typs[137] = newSig(params(typs[7], typs[1], typs[5]), nil)
++ typs[138] = types.NewSlice(typs[7])
++ typs[139] = newSig(params(typs[7], typs[138]), nil)
++ typs[140] = newSig(params(typs[64], typs[64]), nil)
++ typs[141] = newSig(params(typs[58], typs[58]), nil)
++ typs[142] = newSig(params(typs[60], typs[60]), nil)
++ typs[143] = newSig(params(typs[24], typs[24]), nil)
+ return typs[:]
+ }
+diff --git a/src/cmd/compile/internal/typecheck/builtin/runtime.go b/src/cmd/compile/internal/typecheck/builtin/runtime.go
+index 2b29ea3c08..bd45258058 100644
+--- a/src/cmd/compile/internal/typecheck/builtin/runtime.go
++++ b/src/cmd/compile/internal/typecheck/builtin/runtime.go
+@@ -183,8 +183,6 @@ func makeslice(typ *byte, len int, cap int) unsafe.Pointer
+ func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
+ func makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
+ func growslice(typ *byte, old []any, cap int) (ary []any)
+-func unsafeslice(typ *byte, ptr unsafe.Pointer, len int)
+-func unsafeslice64(typ *byte, ptr unsafe.Pointer, len int64)
+ func unsafeslicecheckptr(typ *byte, ptr unsafe.Pointer, len int64)
+
+ func memmove(to *any, frm *any, length uintptr)
+diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go
+index 14efc05e32..2843d468e5 100644
+--- a/src/cmd/compile/internal/walk/builtin.go
++++ b/src/cmd/compile/internal/walk/builtin.go
+@@ -656,27 +656,14 @@ func walkRecover(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
+ func walkUnsafeSlice(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+ ptr := safeExpr(n.X, init)
+ len := safeExpr(n.Y, init)
+-
+- fnname := "unsafeslice64"
+ lenType := types.Types[types.TINT64]
+-
+- // Type checking guarantees that TIDEAL len/cap are positive and fit in an int.
+- // The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
+- // will be handled by the negative range checks in unsafeslice during runtime.
++ t := n.Type()
+ if ir.ShouldCheckPtr(ir.CurFunc, 1) {
+- fnname = "unsafeslicecheckptr"
+- // for simplicity, unsafeslicecheckptr always uses int64
++ fn := typecheck.LookupRuntime("unsafeslicecheckptr")
++ init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]), typecheck.Conv(len, lenType)))
+ } else if len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size() {
+- fnname = "unsafeslice"
+ lenType = types.Types[types.TINT]
+ }
+-
+- t := n.Type()
+-
+- // Call runtime.unsafeslice{,64,checkptr} to check ptr and len.
+- fn := typecheck.LookupRuntime(fnname)
+- init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]), typecheck.Conv(len, lenType)))
+-
+ h := ir.NewSliceHeaderExpr(n.Pos(), t,
+ typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]),
+ typecheck.Conv(len, types.Types[types.TINT]),
+diff --git a/test/unsafebuiltins.go b/test/unsafebuiltins.go
+index 4c940aa855..d613088827 100644
+--- a/test/unsafebuiltins.go
++++ b/test/unsafebuiltins.go
+@@ -6,10 +6,7 @@
+
+ package main
+
+-import (
+- "math"
+- "unsafe"
+-)
++import "unsafe"
+
+ const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0)))
+
+@@ -29,24 +26,6 @@ func main() {
+ assert(&s[0] == &p[0])
+ assert(len(s) == len(p))
+ assert(cap(s) == len(p))
+-
+- // nil pointer with zero length returns nil
+- assert(unsafe.Slice((*int)(nil), 0) == nil)
+-
+- // nil pointer with positive length panics
+- mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) })
+-
+- // negative length
+- var neg int = -1
+- mustPanic(func() { _ = unsafe.Slice(new(byte), neg) })
+-
+- // length too large
+- var tooBig uint64 = math.MaxUint64
+- mustPanic(func() { _ = unsafe.Slice(new(byte), tooBig) })
+-
+- // size overflows address space
+- mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) })
+- mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) })
+ }
+ }
+
+@@ -55,10 +34,3 @@ func assert(ok bool) {
+ panic("FAIL")
+ }
+ }
+-
+-func mustPanic(f func()) {
+- defer func() {
+- assert(recover() != nil)
+- }()
+- f()
+-}
+--
+2.33.0
+