...
Source file
src/runtime/unsafepoint_test.go
Documentation: runtime
1
2
3
4
5 package runtime_test
6
7 import (
8 "internal/testenv"
9 "os"
10 "os/exec"
11 "reflect"
12 "runtime"
13 "strconv"
14 "strings"
15 "testing"
16 )
17
18
19
20 func setGlobalPointer() {
21 globalPointer = nil
22 }
23
24 var globalPointer *int
25
26 func TestUnsafePoint(t *testing.T) {
27 testenv.MustHaveExec(t)
28 switch runtime.GOARCH {
29 case "amd64", "arm64":
30 default:
31 t.Skipf("test not enabled for %s", runtime.GOARCH)
32 }
33
34
35
36 f := runtime.FuncForPC(reflect.ValueOf(setGlobalPointer).Pointer())
37
38
39
40
41
42
43 cmd := exec.Command(testenv.GoToolPath(t), "tool", "objdump", "-s", "setGlobalPointer", os.Args[0])
44 out, err := cmd.CombinedOutput()
45 if err != nil {
46 t.Fatalf("can't objdump %v", err)
47 }
48 lines := strings.Split(string(out), "\n")[1:]
49
50
51 var entry uint64
52 var startedWB bool
53 var doneWB bool
54 instructionCount := 0
55 unsafeCount := 0
56 for _, line := range lines {
57 line = strings.TrimSpace(line)
58 t.Logf("%s", line)
59 parts := strings.Fields(line)
60 if len(parts) < 4 {
61 continue
62 }
63 if !strings.HasPrefix(parts[0], "unsafepoint_test.go:") {
64 continue
65 }
66 pc, err := strconv.ParseUint(parts[1][2:], 16, 64)
67 if err != nil {
68 t.Fatalf("can't parse pc %s: %v", parts[1], err)
69 }
70 if entry == 0 {
71 entry = pc
72 }
73
74
75
76 unsafe := runtime.UnsafePoint(f.Entry() + uintptr(pc-entry))
77 t.Logf("unsafe: %v\n", unsafe)
78 instructionCount++
79 if unsafe {
80 unsafeCount++
81 }
82
83
84 if startedWB && !doneWB && !unsafe {
85 t.Errorf("instruction %s must be marked unsafe, but isn't", parts[1])
86 }
87
88
89 switch runtime.GOARCH {
90 case "arm64":
91 if parts[3] == "MOVWU" {
92
93
94 startedWB = true
95 }
96 if parts[3] == "MOVD" && parts[4] == "ZR," {
97
98
99 doneWB = true
100 }
101 case "amd64":
102 if parts[3] == "CMPL" {
103 startedWB = true
104 }
105 if parts[3] == "MOVQ" && parts[4] == "$0x0," {
106 doneWB = true
107 }
108 }
109 }
110
111 if instructionCount == 0 {
112 t.Errorf("no instructions")
113 }
114 if unsafeCount == instructionCount {
115 t.Errorf("no interruptible instructions")
116 }
117
118
119
120
121
122 }
123
View as plain text