]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/test/inl_test.go
runtime: fix user arena heap bits writing on big endian platforms
[gostls13.git] / src / cmd / compile / internal / test / inl_test.go
index 9926985c58f461e8742ae3204d79f4b27b68cd2b..ea7f317ef52aac34cfe4dcc79061f797fdd6545d 100644 (file)
@@ -6,10 +6,10 @@ package test
 
 import (
        "bufio"
+       "internal/goexperiment"
        "internal/testenv"
        "io"
        "math/bits"
-       "os/exec"
        "regexp"
        "runtime"
        "strings"
@@ -47,11 +47,11 @@ func TestIntendedInlining(t *testing.T) {
                        "fastrand",
                        "float64bits",
                        "funcspdelta",
-                       "getArgInfoFast",
                        "getm",
                        "getMCache",
                        "isDirectIface",
                        "itabHashFunc",
+                       "nextslicecap",
                        "noescape",
                        "pcvalueCacheKey",
                        "readUnaligned32",
@@ -73,11 +73,13 @@ func TestIntendedInlining(t *testing.T) {
                        "gclinkptr.ptr",
                        "guintptr.ptr",
                        "writeHeapBitsForAddr",
+                       "heapBitsSlice",
                        "markBits.isMarked",
                        "muintptr.ptr",
                        "puintptr.ptr",
                        "spanOf",
                        "spanOfUnchecked",
+                       "typePointers.nextFast",
                        "(*gcWork).putFast",
                        "(*gcWork).tryGetFast",
                        "(*guintptr).set",
@@ -86,8 +88,11 @@ func TestIntendedInlining(t *testing.T) {
                        "(*mspan).base",
                        "(*mspan).markBitsForBase",
                        "(*mspan).markBitsForIndex",
+                       "(*mspan).writeUserArenaHeapBits",
                        "(*muintptr).set",
                        "(*puintptr).set",
+                       "(*wbBuf).get1",
+                       "(*wbBuf).get2",
                },
                "runtime/internal/sys": {},
                "runtime/internal/math": {
@@ -106,6 +111,9 @@ func TestIntendedInlining(t *testing.T) {
                        "(*Buffer).UnreadByte",
                        "(*Buffer).tryGrowByReslice",
                },
+               "internal/abi": {
+                       "UseInterfaceSwitchCache",
+               },
                "compress/flate": {
                        "byLiteral.Len",
                        "byLiteral.Less",
@@ -123,6 +131,9 @@ func TestIntendedInlining(t *testing.T) {
                        "AppendRune",
                        "ValidRune",
                },
+               "unicode/utf16": {
+                       "Decode",
+               },
                "reflect": {
                        "Value.Bool",
                        "Value.Bytes",
@@ -176,6 +187,15 @@ func TestIntendedInlining(t *testing.T) {
                "net": {
                        "(*UDPConn).ReadFromUDP",
                },
+               "sync": {
+                       // Both OnceFunc and its returned closure need to be inlinable so
+                       // that the returned closure can be inlined into the caller of OnceFunc.
+                       "OnceFunc",
+                       "OnceFunc.func2", // The returned closure.
+                       // TODO(austin): It would be good to check OnceValue and OnceValues,
+                       // too, but currently they aren't reported because they have type
+                       // parameters and aren't instantiated in sync.
+               },
                "sync/atomic": {
                        // (*Bool).CompareAndSwap handled below.
                        "(*Bool).Load",
@@ -206,28 +226,27 @@ func TestIntendedInlining(t *testing.T) {
                        "(*Uintptr).Load",
                        "(*Uintptr).Store",
                        "(*Uintptr).Swap",
-                       // TODO(rsc): Why are these not reported as inlined?
-                       // "(*Pointer[T]).CompareAndSwap",
-                       // "(*Pointer[T]).Load",
-                       // "(*Pointer[T]).Store",
-                       // "(*Pointer[T]).Swap",
+                       "(*Pointer[go.shape.int]).CompareAndSwap",
+                       "(*Pointer[go.shape.int]).Load",
+                       "(*Pointer[go.shape.int]).Store",
+                       "(*Pointer[go.shape.int]).Swap",
                },
        }
 
        if runtime.GOARCH != "386" && runtime.GOARCH != "loong64" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" && runtime.GOARCH != "riscv64" {
-               // nextFreeFast calls sys.Ctz64, which on 386 is implemented in asm and is not inlinable.
+               // nextFreeFast calls sys.TrailingZeros64, which on 386 is implemented in asm and is not inlinable.
                // We currently don't have midstack inlining so nextFreeFast is also not inlinable on 386.
-               // On loong64, mips64x and riscv64, Ctz64 is not intrinsified and causes nextFreeFast too expensive
-               // to inline (Issue 22239).
+               // On loong64, mips64x and riscv64, TrailingZeros64 is not intrinsified and causes nextFreeFast
+               // too expensive to inline (Issue 22239).
                want["runtime"] = append(want["runtime"], "nextFreeFast")
                // Same behavior for heapBits.nextFast.
                want["runtime"] = append(want["runtime"], "heapBits.nextFast")
        }
        if runtime.GOARCH != "386" {
-               // As explained above, Ctz64 and Ctz32 are not Go code on 386.
+               // As explained above, TrailingZeros64 and TrailingZeros32 are not Go code on 386.
                // The same applies to Bswap32.
-               want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Ctz64")
-               want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Ctz32")
+               want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "TrailingZeros64")
+               want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "TrailingZeros32")
                want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Bswap32")
        }
        if bits.UintSize == 64 {
@@ -274,7 +293,7 @@ func TestIntendedInlining(t *testing.T) {
        }
 
        args := append([]string{"build", "-gcflags=-m -m", "-tags=math_big_pure_go"}, pkgs...)
-       cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), args...))
+       cmd := testenv.CleanCmdEnv(testenv.Command(t, testenv.GoToolPath(t), args...))
        pr, pw := io.Pipe()
        cmd.Stdout = pw
        cmd.Stderr = pw
@@ -328,3 +347,57 @@ func TestIntendedInlining(t *testing.T) {
                t.Errorf("%s was not inlined: %s", fullName, reason)
        }
 }
+
+func collectInlCands(msgs string) map[string]struct{} {
+       rv := make(map[string]struct{})
+       lines := strings.Split(msgs, "\n")
+       re := regexp.MustCompile(`^\S+\s+can\s+inline\s+(\S+)`)
+       for _, line := range lines {
+               m := re.FindStringSubmatch(line)
+               if m != nil {
+                       rv[m[1]] = struct{}{}
+               }
+       }
+       return rv
+}
+
+func TestIssue56044(t *testing.T) {
+       if testing.Short() {
+               t.Skipf("skipping test: too long for short mode")
+       }
+       if !goexperiment.CoverageRedesign {
+               t.Skipf("skipping new coverage tests (experiment not enabled)")
+       }
+
+       testenv.MustHaveGoBuild(t)
+
+       modes := []string{"-covermode=set", "-covermode=atomic"}
+
+       for _, mode := range modes {
+               // Build the Go runtime with "-m", capturing output.
+               args := []string{"build", "-gcflags=runtime=-m", "runtime"}
+               cmd := testenv.Command(t, testenv.GoToolPath(t), args...)
+               b, err := cmd.CombinedOutput()
+               if err != nil {
+                       t.Fatalf("build failed (%v): %s", err, b)
+               }
+               mbase := collectInlCands(string(b))
+
+               // Redo the build with -cover, also with "-m".
+               args = []string{"build", "-gcflags=runtime=-m", mode, "runtime"}
+               cmd = testenv.Command(t, testenv.GoToolPath(t), args...)
+               b, err = cmd.CombinedOutput()
+               if err != nil {
+                       t.Fatalf("build failed (%v): %s", err, b)
+               }
+               mcov := collectInlCands(string(b))
+
+               // Make sure that there aren't any functions that are marked
+               // as inline candidates at base but not with coverage.
+               for k := range mbase {
+                       if _, ok := mcov[k]; !ok {
+                               t.Errorf("error: did not find %s in coverage -m output", k)
+                       }
+               }
+       }
+}