From: Russ Cox Date: Fri, 14 Feb 2025 17:52:02 +0000 (-0500) Subject: math/big: add tests for allocation during multiply X-Git-Tag: go1.25rc1~878 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2b737073587cb8f82d41fa96fdec9e56a5bac8ba;p=gostls13.git math/big: add tests for allocation during multiply Test that big.Int.Mul reusing the same target is not allocating temporary garbage during its computation. That code is going to be modified in an upcoming CL. Change-Id: I3ed55c06da030282233c29cd7af2a04f395dc7a2 Reviewed-on: https://go-review.googlesource.com/c/go/+/652056 LUCI-TryBot-Result: Go LUCI Reviewed-by: Alan Donovan Auto-Submit: Russ Cox --- diff --git a/src/math/big/escape_test.go b/src/math/big/escape_test.go new file mode 100644 index 0000000000..1e757f55ab --- /dev/null +++ b/src/math/big/escape_test.go @@ -0,0 +1,53 @@ +// Copyright 2025 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 big + +import ( + "internal/testenv" + "math/rand" + "os/exec" + "strings" + "testing" +) + +func TestEscape(t *testing.T) { + testenv.MustHaveGoBuild(t) + // The multiplication routines create many temporary Int values, + // expecting them to be stack-allocated. Make sure none escape to the heap. + out, err := exec.Command("go", "build", "-gcflags=-m").CombinedOutput() + if err != nil { + t.Fatalf("go build -gcflags=-m: %v\n%s", err, out) + } + for line := range strings.Lines(string(out)) { + if strings.Contains(line, "natmul.go") && strings.Contains(line, "Int") && strings.Contains(line, "escapes") { + t.Error(strings.TrimSpace(line)) + } + } +} + +func TestMulAlloc(t *testing.T) { + r := rand.New(rand.NewSource(1234)) + sizes := []int{karatsubaThreshold / 2, karatsubaThreshold} + for _, size := range sizes { + x := randInt(r, uint(size)) + y := randInt(r, uint(size)) + z := &Int{abs: make(nat, 2*uint(size))} + if n := testing.AllocsPerRun(10, func() { z.Mul(x, y) }); n >= 1 { + t.Errorf("Mul(len %d, len %d) allocates %.2f objects", size, size, n) + } + } +} + +func TestSqrAlloc(t *testing.T) { + r := rand.New(rand.NewSource(1234)) + sizes := []int{basicSqrThreshold / 2, basicSqrThreshold, karatsubaSqrThreshold} + for _, size := range sizes { + x := randInt(r, uint(size)) + z := &Int{abs: make(nat, 2*uint(size))} + if n := testing.AllocsPerRun(10, func() { z.Mul(x, x) }); n >= 1 { + t.Errorf("Mul(len %d with itself) allocates %.2f objects", size, n) + } + } +}