Source file
src/runtime/mgcmark_nogreenteagc.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "internal/goarch"
11 "internal/runtime/gc"
12 "internal/runtime/sys"
13 "unsafe"
14 )
15
16 func (s *mspan) markBitsForIndex(objIndex uintptr) markBits {
17 bytep, mask := s.gcmarkBits.bitp(objIndex)
18 return markBits{bytep, mask, objIndex}
19 }
20
21 func (s *mspan) markBitsForBase() markBits {
22 return markBits{&s.gcmarkBits.x, uint8(1), 0}
23 }
24
25 func tryDeferToSpanScan(p uintptr, gcw *gcWork) bool {
26 return false
27 }
28
29 func (s *mspan) initInlineMarkBits() {
30 }
31
32 func (s *mspan) moveInlineMarks(to *gcBits) {
33 throw("unimplemented")
34 }
35
36 func gcUsesSpanInlineMarkBits(_ uintptr) bool {
37 return false
38 }
39
40 func (s *mspan) inlineMarkBits() *spanInlineMarkBits {
41 return nil
42 }
43
44 func (s *mspan) scannedBitsForIndex(objIndex uintptr) markBits {
45 throw("unimplemented")
46 return markBits{}
47 }
48
49 type spanInlineMarkBits struct {
50 }
51
52 func (q *spanInlineMarkBits) tryAcquire() bool {
53 return false
54 }
55
56 type spanQueue struct {
57 _ uint32
58 }
59
60 func (q *spanQueue) empty() bool {
61 return true
62 }
63
64 func (q *spanQueue) size() int {
65 return 0
66 }
67
68 type localSpanQueue struct {
69 }
70
71 func (q *localSpanQueue) drain() bool {
72 return false
73 }
74
75 func (q *localSpanQueue) empty() bool {
76 return true
77 }
78
79 type objptr uintptr
80
81 func (w *gcWork) tryGetSpan(steal bool) objptr {
82 return 0
83 }
84
85 func scanSpan(p objptr, gcw *gcWork) {
86 throw("unimplemented")
87 }
88
89 type sizeClassScanStats struct {
90 sparseObjsScanned uint64
91 }
92
93 func dumpScanStats() {
94 var sparseObjsScanned uint64
95 for _, stats := range memstats.lastScanStats {
96 sparseObjsScanned += stats.sparseObjsScanned
97 }
98 print("scan: total ", sparseObjsScanned, " objs\n")
99 for i, stats := range memstats.lastScanStats {
100 if stats == (sizeClassScanStats{}) {
101 continue
102 }
103 if i == 0 {
104 print("scan: class L ")
105 } else {
106 print("scan: class ", gc.SizeClassToSize[i], "B ")
107 }
108 print(stats.sparseObjsScanned, " objs\n")
109 }
110 }
111
112 func (w *gcWork) flushScanStats(dst *[gc.NumSizeClasses]sizeClassScanStats) {
113 for i := range w.stats {
114 dst[i].sparseObjsScanned += w.stats[i].sparseObjsScanned
115 }
116 clear(w.stats[:])
117 }
118
119
120
121
122
123
124
125 func scanObject(b uintptr, gcw *gcWork) {
126
127
128
129
130 sys.Prefetch(b)
131
132
133
134
135
136
137 s := spanOfUnchecked(b)
138 n := s.elemsize
139 if n == 0 {
140 throw("scanObject n == 0")
141 }
142 if s.spanclass.noscan() {
143
144
145 throw("scanObject of a noscan object")
146 }
147
148 var tp typePointers
149 if n > maxObletBytes {
150
151
152 if b == s.base() {
153
154
155
156
157
158 for oblet := b + maxObletBytes; oblet < s.base()+s.elemsize; oblet += maxObletBytes {
159 if !gcw.putObjFast(oblet) {
160 gcw.putObj(oblet)
161 }
162 }
163 }
164
165
166
167
168 n = s.base() + s.elemsize - b
169 n = min(n, maxObletBytes)
170 tp = s.typePointersOfUnchecked(s.base())
171 tp = tp.fastForward(b-tp.addr, b+n)
172 } else {
173 tp = s.typePointersOfUnchecked(b)
174 }
175
176 var scanSize uintptr
177 for {
178 var addr uintptr
179 if tp, addr = tp.nextFast(); addr == 0 {
180 if tp, addr = tp.next(b + n); addr == 0 {
181 break
182 }
183 }
184
185
186
187
188 scanSize = addr - b + goarch.PtrSize
189
190
191
192 obj := *(*uintptr)(unsafe.Pointer(addr))
193
194
195
196 if obj != 0 && obj-b >= n {
197
198
199
200
201
202
203
204
205
206 if !tryDeferToSpanScan(obj, gcw) {
207 if obj, span, objIndex := findObject(obj, b, addr-b); obj != 0 {
208 greyobject(obj, b, addr-b, span, gcw, objIndex)
209 }
210 }
211 }
212 }
213 gcw.bytesMarked += uint64(n)
214 gcw.heapScanWork += int64(scanSize)
215 if debug.gctrace > 1 {
216 gcw.stats[s.spanclass.sizeclass()].sparseObjsScanned++
217 }
218 }
219
View as plain text