Skip to content

Commit 847cb6f

Browse files
qmuntalgopherbot
authored andcommitted
[release-branch.go1.23] syscall: mark SyscallN as noescape
syscall.SyscallN is implemented by runtime.syscall_syscalln, which makes sure that the variadic argument doesn't escape. There is no need to worry about the lifetime of the elements of the variadic argument, as the compiler will keep them live until the function returns. For #70197 Fixes #70202 Change-Id: I12991f0be12062eea68f2b103fa0a794c1b527eb Reviewed-on: https://go-review.googlesource.com/c/go/+/625297 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Alex Brainman <[email protected]> Reviewed-by: David Chase <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> (cherry picked from commit 7fff741) Reviewed-on: https://go-review.googlesource.com/c/go/+/630196 Reviewed-by: Dmitri Shuralyov <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Quim Muntal <[email protected]>
1 parent 777f43a commit 847cb6f

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/syscall/dll_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a
4242
// Deprecated: Use [SyscallN] instead.
4343
func Syscall18(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2 uintptr, err Errno)
4444

45+
//go:noescape
4546
func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno)
4647
func loadlibrary(filename *uint16) (handle uintptr, err Errno)
4748
func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno)

src/syscall/syscall_windows_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,51 @@ func TestGetStartupInfo(t *testing.T) {
213213
}
214214
}
215215

216+
func TestSyscallAllocations(t *testing.T) {
217+
testenv.SkipIfOptimizationOff(t)
218+
219+
// Test that syscall.SyscallN arguments do not escape.
220+
// The function used (in this case GetVersion) doesn't matter
221+
// as long as it is always available and doesn't panic.
222+
h, err := syscall.LoadLibrary("kernel32.dll")
223+
if err != nil {
224+
t.Fatal(err)
225+
}
226+
defer syscall.FreeLibrary(h)
227+
proc, err := syscall.GetProcAddress(h, "GetVersion")
228+
if err != nil {
229+
t.Fatal(err)
230+
}
231+
232+
testAllocs := func(t *testing.T, name string, fn func() error) {
233+
t.Run(name, func(t *testing.T) {
234+
n := int(testing.AllocsPerRun(10, func() {
235+
if err := fn(); err != nil {
236+
t.Fatalf("%s: %v", name, err)
237+
}
238+
}))
239+
if n > 0 {
240+
t.Errorf("allocs = %d, want 0", n)
241+
}
242+
})
243+
}
244+
245+
testAllocs(t, "SyscallN", func() error {
246+
r0, _, e1 := syscall.SyscallN(proc, 0, 0, 0)
247+
if r0 == 0 {
248+
return syscall.Errno(e1)
249+
}
250+
return nil
251+
})
252+
testAllocs(t, "Syscall", func() error {
253+
r0, _, e1 := syscall.Syscall(proc, 3, 0, 0, 0)
254+
if r0 == 0 {
255+
return syscall.Errno(e1)
256+
}
257+
return nil
258+
})
259+
}
260+
216261
func FuzzUTF16FromString(f *testing.F) {
217262
f.Add("hi") // ASCII
218263
f.Add("â") // latin1

0 commit comments

Comments
 (0)