]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/export_test.go
runtime: implement experiment to replace heap bitmap with alloc headers
[gostls13.git] / src / runtime / export_test.go
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Export guts for testing.
6
7 package runtime
8
9 import (
10         "internal/abi"
11         "internal/goarch"
12         "internal/goexperiment"
13         "internal/goos"
14         "runtime/internal/atomic"
15         "runtime/internal/sys"
16         "unsafe"
17 )
18
19 var Fadd64 = fadd64
20 var Fsub64 = fsub64
21 var Fmul64 = fmul64
22 var Fdiv64 = fdiv64
23 var F64to32 = f64to32
24 var F32to64 = f32to64
25 var Fcmp64 = fcmp64
26 var Fintto64 = fintto64
27 var F64toint = f64toint
28
29 var Entersyscall = entersyscall
30 var Exitsyscall = exitsyscall
31 var LockedOSThread = lockedOSThread
32 var Xadduintptr = atomic.Xadduintptr
33
34 var Fastlog2 = fastlog2
35
36 var Atoi = atoi
37 var Atoi32 = atoi32
38 var ParseByteCount = parseByteCount
39
40 var Nanotime = nanotime
41 var NetpollBreak = netpollBreak
42 var Usleep = usleep
43
44 var PhysPageSize = physPageSize
45 var PhysHugePageSize = physHugePageSize
46
47 var NetpollGenericInit = netpollGenericInit
48
49 var Memmove = memmove
50 var MemclrNoHeapPointers = memclrNoHeapPointers
51
52 var CgoCheckPointer = cgoCheckPointer
53
54 const CrashStackImplemented = crashStackImplemented
55
56 const TracebackInnerFrames = tracebackInnerFrames
57 const TracebackOuterFrames = tracebackOuterFrames
58
59 var MapKeys = keys
60 var MapValues = values
61
62 var LockPartialOrder = lockPartialOrder
63
64 type LockRank lockRank
65
66 func (l LockRank) String() string {
67         return lockRank(l).String()
68 }
69
70 const PreemptMSupported = preemptMSupported
71
72 type LFNode struct {
73         Next    uint64
74         Pushcnt uintptr
75 }
76
77 func LFStackPush(head *uint64, node *LFNode) {
78         (*lfstack)(head).push((*lfnode)(unsafe.Pointer(node)))
79 }
80
81 func LFStackPop(head *uint64) *LFNode {
82         return (*LFNode)((*lfstack)(head).pop())
83 }
84 func LFNodeValidate(node *LFNode) {
85         lfnodeValidate((*lfnode)(unsafe.Pointer(node)))
86 }
87
88 func Netpoll(delta int64) {
89         systemstack(func() {
90                 netpoll(delta)
91         })
92 }
93
94 func GCMask(x any) (ret []byte) {
95         systemstack(func() {
96                 ret = getgcmask(x)
97         })
98         return
99 }
100
101 func RunSchedLocalQueueTest() {
102         pp := new(p)
103         gs := make([]g, len(pp.runq))
104         Escape(gs) // Ensure gs doesn't move, since we use guintptrs
105         for i := 0; i < len(pp.runq); i++ {
106                 if g, _ := runqget(pp); g != nil {
107                         throw("runq is not empty initially")
108                 }
109                 for j := 0; j < i; j++ {
110                         runqput(pp, &gs[i], false)
111                 }
112                 for j := 0; j < i; j++ {
113                         if g, _ := runqget(pp); g != &gs[i] {
114                                 print("bad element at iter ", i, "/", j, "\n")
115                                 throw("bad element")
116                         }
117                 }
118                 if g, _ := runqget(pp); g != nil {
119                         throw("runq is not empty afterwards")
120                 }
121         }
122 }
123
124 func RunSchedLocalQueueStealTest() {
125         p1 := new(p)
126         p2 := new(p)
127         gs := make([]g, len(p1.runq))
128         Escape(gs) // Ensure gs doesn't move, since we use guintptrs
129         for i := 0; i < len(p1.runq); i++ {
130                 for j := 0; j < i; j++ {
131                         gs[j].sig = 0
132                         runqput(p1, &gs[j], false)
133                 }
134                 gp := runqsteal(p2, p1, true)
135                 s := 0
136                 if gp != nil {
137                         s++
138                         gp.sig++
139                 }
140                 for {
141                         gp, _ = runqget(p2)
142                         if gp == nil {
143                                 break
144                         }
145                         s++
146                         gp.sig++
147                 }
148                 for {
149                         gp, _ = runqget(p1)
150                         if gp == nil {
151                                 break
152                         }
153                         gp.sig++
154                 }
155                 for j := 0; j < i; j++ {
156                         if gs[j].sig != 1 {
157                                 print("bad element ", j, "(", gs[j].sig, ") at iter ", i, "\n")
158                                 throw("bad element")
159                         }
160                 }
161                 if s != i/2 && s != i/2+1 {
162                         print("bad steal ", s, ", want ", i/2, " or ", i/2+1, ", iter ", i, "\n")
163                         throw("bad steal")
164                 }
165         }
166 }
167
168 func RunSchedLocalQueueEmptyTest(iters int) {
169         // Test that runq is not spuriously reported as empty.
170         // Runq emptiness affects scheduling decisions and spurious emptiness
171         // can lead to underutilization (both runnable Gs and idle Ps coexist
172         // for arbitrary long time).
173         done := make(chan bool, 1)
174         p := new(p)
175         gs := make([]g, 2)
176         Escape(gs) // Ensure gs doesn't move, since we use guintptrs
177         ready := new(uint32)
178         for i := 0; i < iters; i++ {
179                 *ready = 0
180                 next0 := (i & 1) == 0
181                 next1 := (i & 2) == 0
182                 runqput(p, &gs[0], next0)
183                 go func() {
184                         for atomic.Xadd(ready, 1); atomic.Load(ready) != 2; {
185                         }
186                         if runqempty(p) {
187                                 println("next:", next0, next1)
188                                 throw("queue is empty")
189                         }
190                         done <- true
191                 }()
192                 for atomic.Xadd(ready, 1); atomic.Load(ready) != 2; {
193                 }
194                 runqput(p, &gs[1], next1)
195                 runqget(p)
196                 <-done
197                 runqget(p)
198         }
199 }
200
201 var (
202         StringHash = stringHash
203         BytesHash  = bytesHash
204         Int32Hash  = int32Hash
205         Int64Hash  = int64Hash
206         MemHash    = memhash
207         MemHash32  = memhash32
208         MemHash64  = memhash64
209         EfaceHash  = efaceHash
210         IfaceHash  = ifaceHash
211 )
212
213 var UseAeshash = &useAeshash
214
215 func MemclrBytes(b []byte) {
216         s := (*slice)(unsafe.Pointer(&b))
217         memclrNoHeapPointers(s.array, uintptr(s.len))
218 }
219
220 const HashLoad = hashLoad
221
222 // entry point for testing
223 func GostringW(w []uint16) (s string) {
224         systemstack(func() {
225                 s = gostringw(&w[0])
226         })
227         return
228 }
229
230 var Open = open
231 var Close = closefd
232 var Read = read
233 var Write = write
234
235 func Envs() []string     { return envs }
236 func SetEnvs(e []string) { envs = e }
237
238 // For benchmarking.
239
240 // blockWrapper is a wrapper type that ensures a T is placed within a
241 // large object. This is necessary for safely benchmarking things
242 // that manipulate the heap bitmap, like heapBitsSetType.
243 //
244 // More specifically, allocating threads assume they're the sole writers
245 // to their span's heap bits, which allows those writes to be non-atomic.
246 // The heap bitmap is written byte-wise, so if one tried to call heapBitsSetType
247 // on an existing object in a small object span, we might corrupt that
248 // span's bitmap with a concurrent byte write to the heap bitmap. Large
249 // object spans contain exactly one object, so we can be sure no other P
250 // is going to be allocating from it concurrently, hence this wrapper type
251 // which ensures we have a T in a large object span.
252 type blockWrapper[T any] struct {
253         value T
254         _     [_MaxSmallSize]byte // Ensure we're a large object.
255 }
256
257 func BenchSetType[T any](n int, resetTimer func()) {
258         x := new(blockWrapper[T])
259
260         // Escape x to ensure it is allocated on the heap, as we are
261         // working on the heap bits here.
262         Escape(x)
263
264         // Grab the type.
265         var i any = *new(T)
266         e := *efaceOf(&i)
267         t := e._type
268
269         // Benchmark setting the type bits for just the internal T of the block.
270         benchSetType(n, resetTimer, 1, unsafe.Pointer(&x.value), t)
271 }
272
273 const maxArrayBlockWrapperLen = 32
274
275 // arrayBlockWrapper is like blockWrapper, but the interior value is intended
276 // to be used as a backing store for a slice.
277 type arrayBlockWrapper[T any] struct {
278         value [maxArrayBlockWrapperLen]T
279         _     [_MaxSmallSize]byte // Ensure we're a large object.
280 }
281
282 // arrayLargeBlockWrapper is like arrayBlockWrapper, but the interior array
283 // accommodates many more elements.
284 type arrayLargeBlockWrapper[T any] struct {
285         value [1024]T
286         _     [_MaxSmallSize]byte // Ensure we're a large object.
287 }
288
289 func BenchSetTypeSlice[T any](n int, resetTimer func(), len int) {
290         // We have two separate cases here because we want to avoid
291         // tests on big types but relatively small slices to avoid generating
292         // an allocation that's really big. This will likely force a GC which will
293         // skew the test results.
294         var y unsafe.Pointer
295         if len <= maxArrayBlockWrapperLen {
296                 x := new(arrayBlockWrapper[T])
297                 // Escape x to ensure it is allocated on the heap, as we are
298                 // working on the heap bits here.
299                 Escape(x)
300                 y = unsafe.Pointer(&x.value[0])
301         } else {
302                 x := new(arrayLargeBlockWrapper[T])
303                 Escape(x)
304                 y = unsafe.Pointer(&x.value[0])
305         }
306
307         // Grab the type.
308         var i any = *new(T)
309         e := *efaceOf(&i)
310         t := e._type
311
312         // Benchmark setting the type for a slice created from the array
313         // of T within the arrayBlock.
314         benchSetType(n, resetTimer, len, y, t)
315 }
316
317 // benchSetType is the implementation of the BenchSetType* functions.
318 // x must be len consecutive Ts allocated within a large object span (to
319 // avoid a race on the heap bitmap).
320 //
321 // Note: this function cannot be generic. It would get its type from one of
322 // its callers (BenchSetType or BenchSetTypeSlice) whose type parameters are
323 // set by a call in the runtime_test package. That means this function and its
324 // callers will get instantiated in the package that provides the type argument,
325 // i.e. runtime_test. However, we call a function on the system stack. In race
326 // mode the runtime package is usually left uninstrumented because e.g. g0 has
327 // no valid racectx, but if we're instantiated in the runtime_test package,
328 // we might accidentally cause runtime code to be incorrectly instrumented.
329 func benchSetType(n int, resetTimer func(), len int, x unsafe.Pointer, t *_type) {
330         // This benchmark doesn't work with the allocheaders experiment. It sets up
331         // an elaborate scenario to be able to benchmark the function safely, but doing
332         // this work for the allocheaders' version of the function would be complex.
333         // Just fail instead and rely on the test code making sure we never get here.
334         if goexperiment.AllocHeaders {
335                 panic("called benchSetType with allocheaders experiment enabled")
336         }
337
338         // Compute the input sizes.
339         size := t.Size() * uintptr(len)
340
341         // Validate this function's invariant.
342         s := spanOfHeap(uintptr(x))
343         if s == nil {
344                 panic("no heap span for input")
345         }
346         if s.spanclass.sizeclass() != 0 {
347                 panic("span is not a large object span")
348         }
349
350         // Round up the size to the size class to make the benchmark a little more
351         // realistic. However, validate it, to make sure this is safe.
352         allocSize := roundupsize(size, t.PtrBytes == 0)
353         if s.npages*pageSize < allocSize {
354                 panic("backing span not large enough for benchmark")
355         }
356
357         // Benchmark heapBitsSetType by calling it in a loop. This is safe because
358         // x is in a large object span.
359         resetTimer()
360         systemstack(func() {
361                 for i := 0; i < n; i++ {
362                         heapBitsSetType(uintptr(x), allocSize, size, t)
363                 }
364         })
365
366         // Make sure x doesn't get freed, since we're taking a uintptr.
367         KeepAlive(x)
368 }
369
370 const PtrSize = goarch.PtrSize
371
372 var ForceGCPeriod = &forcegcperiod
373
374 // SetTracebackEnv is like runtime/debug.SetTraceback, but it raises
375 // the "environment" traceback level, so later calls to
376 // debug.SetTraceback (e.g., from testing timeouts) can't lower it.
377 func SetTracebackEnv(level string) {
378         setTraceback(level)
379         traceback_env = traceback_cache
380 }
381
382 var ReadUnaligned32 = readUnaligned32
383 var ReadUnaligned64 = readUnaligned64
384
385 func CountPagesInUse() (pagesInUse, counted uintptr) {
386         stopTheWorld(stwForTestCountPagesInUse)
387
388         pagesInUse = mheap_.pagesInUse.Load()
389
390         for _, s := range mheap_.allspans {
391                 if s.state.get() == mSpanInUse {
392                         counted += s.npages
393                 }
394         }
395
396         startTheWorld()
397
398         return
399 }
400
401 func Fastrand() uint32          { return fastrand() }
402 func Fastrand64() uint64        { return fastrand64() }
403 func Fastrandn(n uint32) uint32 { return fastrandn(n) }
404
405 type ProfBuf profBuf
406
407 func NewProfBuf(hdrsize, bufwords, tags int) *ProfBuf {
408         return (*ProfBuf)(newProfBuf(hdrsize, bufwords, tags))
409 }
410
411 func (p *ProfBuf) Write(tag *unsafe.Pointer, now int64, hdr []uint64, stk []uintptr) {
412         (*profBuf)(p).write(tag, now, hdr, stk)
413 }
414
415 const (
416         ProfBufBlocking    = profBufBlocking
417         ProfBufNonBlocking = profBufNonBlocking
418 )
419
420 func (p *ProfBuf) Read(mode profBufReadMode) ([]uint64, []unsafe.Pointer, bool) {
421         return (*profBuf)(p).read(mode)
422 }
423
424 func (p *ProfBuf) Close() {
425         (*profBuf)(p).close()
426 }
427
428 func ReadMetricsSlow(memStats *MemStats, samplesp unsafe.Pointer, len, cap int) {
429         stopTheWorld(stwForTestReadMetricsSlow)
430
431         // Initialize the metrics beforehand because this could
432         // allocate and skew the stats.
433         metricsLock()
434         initMetrics()
435
436         systemstack(func() {
437                 // Donate the racectx to g0. readMetricsLocked calls into the race detector
438                 // via map access.
439                 getg().racectx = getg().m.curg.racectx
440
441                 // Read the metrics once before in case it allocates and skews the metrics.
442                 // readMetricsLocked is designed to only allocate the first time it is called
443                 // with a given slice of samples. In effect, this extra read tests that this
444                 // remains true, since otherwise the second readMetricsLocked below could
445                 // allocate before it returns.
446                 readMetricsLocked(samplesp, len, cap)
447
448                 // Read memstats first. It's going to flush
449                 // the mcaches which readMetrics does not do, so
450                 // going the other way around may result in
451                 // inconsistent statistics.
452                 readmemstats_m(memStats)
453
454                 // Read metrics again. We need to be sure we're on the
455                 // system stack with readmemstats_m so that we don't call into
456                 // the stack allocator and adjust metrics between there and here.
457                 readMetricsLocked(samplesp, len, cap)
458
459                 // Undo the donation.
460                 getg().racectx = 0
461         })
462         metricsUnlock()
463
464         startTheWorld()
465 }
466
467 // ReadMemStatsSlow returns both the runtime-computed MemStats and
468 // MemStats accumulated by scanning the heap.
469 func ReadMemStatsSlow() (base, slow MemStats) {
470         stopTheWorld(stwForTestReadMemStatsSlow)
471
472         // Run on the system stack to avoid stack growth allocation.
473         systemstack(func() {
474                 // Make sure stats don't change.
475                 getg().m.mallocing++
476
477                 readmemstats_m(&base)
478
479                 // Initialize slow from base and zero the fields we're
480                 // recomputing.
481                 slow = base
482                 slow.Alloc = 0
483                 slow.TotalAlloc = 0
484                 slow.Mallocs = 0
485                 slow.Frees = 0
486                 slow.HeapReleased = 0
487                 var bySize [_NumSizeClasses]struct {
488                         Mallocs, Frees uint64
489                 }
490
491                 // Add up current allocations in spans.
492                 for _, s := range mheap_.allspans {
493                         if s.state.get() != mSpanInUse {
494                                 continue
495                         }
496                         if s.isUnusedUserArenaChunk() {
497                                 continue
498                         }
499                         if sizeclass := s.spanclass.sizeclass(); sizeclass == 0 {
500                                 slow.Mallocs++
501                                 slow.Alloc += uint64(s.elemsize)
502                         } else {
503                                 slow.Mallocs += uint64(s.allocCount)
504                                 slow.Alloc += uint64(s.allocCount) * uint64(s.elemsize)
505                                 bySize[sizeclass].Mallocs += uint64(s.allocCount)
506                         }
507                 }
508
509                 // Add in frees by just reading the stats for those directly.
510                 var m heapStatsDelta
511                 memstats.heapStats.unsafeRead(&m)
512
513                 // Collect per-sizeclass free stats.
514                 var smallFree uint64
515                 for i := 0; i < _NumSizeClasses; i++ {
516                         slow.Frees += m.smallFreeCount[i]
517                         bySize[i].Frees += m.smallFreeCount[i]
518                         bySize[i].Mallocs += m.smallFreeCount[i]
519                         smallFree += m.smallFreeCount[i] * uint64(class_to_size[i])
520                 }
521                 slow.Frees += m.tinyAllocCount + m.largeFreeCount
522                 slow.Mallocs += slow.Frees
523
524                 slow.TotalAlloc = slow.Alloc + m.largeFree + smallFree
525
526                 for i := range slow.BySize {
527                         slow.BySize[i].Mallocs = bySize[i].Mallocs
528                         slow.BySize[i].Frees = bySize[i].Frees
529                 }
530
531                 for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
532                         chunk := mheap_.pages.tryChunkOf(i)
533                         if chunk == nil {
534                                 continue
535                         }
536                         pg := chunk.scavenged.popcntRange(0, pallocChunkPages)
537                         slow.HeapReleased += uint64(pg) * pageSize
538                 }
539                 for _, p := range allp {
540                         pg := sys.OnesCount64(p.pcache.scav)
541                         slow.HeapReleased += uint64(pg) * pageSize
542                 }
543
544                 getg().m.mallocing--
545         })
546
547         startTheWorld()
548         return
549 }
550
551 // ShrinkStackAndVerifyFramePointers attempts to shrink the stack of the current goroutine
552 // and verifies that unwinding the new stack doesn't crash, even if the old
553 // stack has been freed or reused (simulated via poisoning).
554 func ShrinkStackAndVerifyFramePointers() {
555         before := stackPoisonCopy
556         defer func() { stackPoisonCopy = before }()
557         stackPoisonCopy = 1
558
559         gp := getg()
560         systemstack(func() {
561                 shrinkstack(gp)
562         })
563         // If our new stack contains frame pointers into the old stack, this will
564         // crash because the old stack has been poisoned.
565         FPCallers(make([]uintptr, 1024))
566 }
567
568 // BlockOnSystemStack switches to the system stack, prints "x\n" to
569 // stderr, and blocks in a stack containing
570 // "runtime.blockOnSystemStackInternal".
571 func BlockOnSystemStack() {
572         systemstack(blockOnSystemStackInternal)
573 }
574
575 func blockOnSystemStackInternal() {
576         print("x\n")
577         lock(&deadlock)
578         lock(&deadlock)
579 }
580
581 type RWMutex struct {
582         rw rwmutex
583 }
584
585 func (rw *RWMutex) RLock() {
586         rw.rw.rlock()
587 }
588
589 func (rw *RWMutex) RUnlock() {
590         rw.rw.runlock()
591 }
592
593 func (rw *RWMutex) Lock() {
594         rw.rw.lock()
595 }
596
597 func (rw *RWMutex) Unlock() {
598         rw.rw.unlock()
599 }
600
601 const RuntimeHmapSize = unsafe.Sizeof(hmap{})
602
603 func MapBucketsCount(m map[int]int) int {
604         h := *(**hmap)(unsafe.Pointer(&m))
605         return 1 << h.B
606 }
607
608 func MapBucketsPointerIsNil(m map[int]int) bool {
609         h := *(**hmap)(unsafe.Pointer(&m))
610         return h.buckets == nil
611 }
612
613 func OverLoadFactor(count int, B uint8) bool {
614         return overLoadFactor(count, B)
615 }
616
617 func LockOSCounts() (external, internal uint32) {
618         gp := getg()
619         if gp.m.lockedExt+gp.m.lockedInt == 0 {
620                 if gp.lockedm != 0 {
621                         panic("lockedm on non-locked goroutine")
622                 }
623         } else {
624                 if gp.lockedm == 0 {
625                         panic("nil lockedm on locked goroutine")
626                 }
627         }
628         return gp.m.lockedExt, gp.m.lockedInt
629 }
630
631 //go:noinline
632 func TracebackSystemstack(stk []uintptr, i int) int {
633         if i == 0 {
634                 pc, sp := getcallerpc(), getcallersp()
635                 var u unwinder
636                 u.initAt(pc, sp, 0, getg(), unwindJumpStack) // Don't ignore errors, for testing
637                 return tracebackPCs(&u, 0, stk)
638         }
639         n := 0
640         systemstack(func() {
641                 n = TracebackSystemstack(stk, i-1)
642         })
643         return n
644 }
645
646 func KeepNArenaHints(n int) {
647         hint := mheap_.arenaHints
648         for i := 1; i < n; i++ {
649                 hint = hint.next
650                 if hint == nil {
651                         return
652                 }
653         }
654         hint.next = nil
655 }
656
657 // MapNextArenaHint reserves a page at the next arena growth hint,
658 // preventing the arena from growing there, and returns the range of
659 // addresses that are no longer viable.
660 //
661 // This may fail to reserve memory. If it fails, it still returns the
662 // address range it attempted to reserve.
663 func MapNextArenaHint() (start, end uintptr, ok bool) {
664         hint := mheap_.arenaHints
665         addr := hint.addr
666         if hint.down {
667                 start, end = addr-heapArenaBytes, addr
668                 addr -= physPageSize
669         } else {
670                 start, end = addr, addr+heapArenaBytes
671         }
672         got := sysReserve(unsafe.Pointer(addr), physPageSize)
673         ok = (addr == uintptr(got))
674         if !ok {
675                 // We were unable to get the requested reservation.
676                 // Release what we did get and fail.
677                 sysFreeOS(got, physPageSize)
678         }
679         return
680 }
681
682 func GetNextArenaHint() uintptr {
683         return mheap_.arenaHints.addr
684 }
685
686 type G = g
687
688 type Sudog = sudog
689
690 func Getg() *G {
691         return getg()
692 }
693
694 func Goid() uint64 {
695         return getg().goid
696 }
697
698 func GIsWaitingOnMutex(gp *G) bool {
699         return readgstatus(gp) == _Gwaiting && gp.waitreason.isMutexWait()
700 }
701
702 var CasGStatusAlwaysTrack = &casgstatusAlwaysTrack
703
704 //go:noinline
705 func PanicForTesting(b []byte, i int) byte {
706         return unexportedPanicForTesting(b, i)
707 }
708
709 //go:noinline
710 func unexportedPanicForTesting(b []byte, i int) byte {
711         return b[i]
712 }
713
714 func G0StackOverflow() {
715         systemstack(func() {
716                 g0 := getg()
717                 sp := getcallersp()
718                 // The stack bounds for g0 stack is not always precise.
719                 // Use an artificially small stack, to trigger a stack overflow
720                 // without actually run out of the system stack (which may seg fault).
721                 g0.stack.lo = sp - 4096 - stackSystem
722                 g0.stackguard0 = g0.stack.lo + stackGuard
723                 g0.stackguard1 = g0.stackguard0
724
725                 stackOverflow(nil)
726         })
727 }
728
729 func stackOverflow(x *byte) {
730         var buf [256]byte
731         stackOverflow(&buf[0])
732 }
733
734 func MapTombstoneCheck(m map[int]int) {
735         // Make sure emptyOne and emptyRest are distributed correctly.
736         // We should have a series of filled and emptyOne cells, followed by
737         // a series of emptyRest cells.
738         h := *(**hmap)(unsafe.Pointer(&m))
739         i := any(m)
740         t := *(**maptype)(unsafe.Pointer(&i))
741
742         for x := 0; x < 1<<h.B; x++ {
743                 b0 := (*bmap)(add(h.buckets, uintptr(x)*uintptr(t.BucketSize)))
744                 n := 0
745                 for b := b0; b != nil; b = b.overflow(t) {
746                         for i := 0; i < bucketCnt; i++ {
747                                 if b.tophash[i] != emptyRest {
748                                         n++
749                                 }
750                         }
751                 }
752                 k := 0
753                 for b := b0; b != nil; b = b.overflow(t) {
754                         for i := 0; i < bucketCnt; i++ {
755                                 if k < n && b.tophash[i] == emptyRest {
756                                         panic("early emptyRest")
757                                 }
758                                 if k >= n && b.tophash[i] != emptyRest {
759                                         panic("late non-emptyRest")
760                                 }
761                                 if k == n-1 && b.tophash[i] == emptyOne {
762                                         panic("last non-emptyRest entry is emptyOne")
763                                 }
764                                 k++
765                         }
766                 }
767         }
768 }
769
770 func RunGetgThreadSwitchTest() {
771         // Test that getg works correctly with thread switch.
772         // With gccgo, if we generate getg inlined, the backend
773         // may cache the address of the TLS variable, which
774         // will become invalid after a thread switch. This test
775         // checks that the bad caching doesn't happen.
776
777         ch := make(chan int)
778         go func(ch chan int) {
779                 ch <- 5
780                 LockOSThread()
781         }(ch)
782
783         g1 := getg()
784
785         // Block on a receive. This is likely to get us a thread
786         // switch. If we yield to the sender goroutine, it will
787         // lock the thread, forcing us to resume on a different
788         // thread.
789         <-ch
790
791         g2 := getg()
792         if g1 != g2 {
793                 panic("g1 != g2")
794         }
795
796         // Also test getg after some control flow, as the
797         // backend is sensitive to control flow.
798         g3 := getg()
799         if g1 != g3 {
800                 panic("g1 != g3")
801         }
802 }
803
804 const (
805         PageSize         = pageSize
806         PallocChunkPages = pallocChunkPages
807         PageAlloc64Bit   = pageAlloc64Bit
808         PallocSumBytes   = pallocSumBytes
809 )
810
811 // Expose pallocSum for testing.
812 type PallocSum pallocSum
813
814 func PackPallocSum(start, max, end uint) PallocSum { return PallocSum(packPallocSum(start, max, end)) }
815 func (m PallocSum) Start() uint                    { return pallocSum(m).start() }
816 func (m PallocSum) Max() uint                      { return pallocSum(m).max() }
817 func (m PallocSum) End() uint                      { return pallocSum(m).end() }
818
819 // Expose pallocBits for testing.
820 type PallocBits pallocBits
821
822 func (b *PallocBits) Find(npages uintptr, searchIdx uint) (uint, uint) {
823         return (*pallocBits)(b).find(npages, searchIdx)
824 }
825 func (b *PallocBits) AllocRange(i, n uint)       { (*pallocBits)(b).allocRange(i, n) }
826 func (b *PallocBits) Free(i, n uint)             { (*pallocBits)(b).free(i, n) }
827 func (b *PallocBits) Summarize() PallocSum       { return PallocSum((*pallocBits)(b).summarize()) }
828 func (b *PallocBits) PopcntRange(i, n uint) uint { return (*pageBits)(b).popcntRange(i, n) }
829
830 // SummarizeSlow is a slow but more obviously correct implementation
831 // of (*pallocBits).summarize. Used for testing.
832 func SummarizeSlow(b *PallocBits) PallocSum {
833         var start, most, end uint
834
835         const N = uint(len(b)) * 64
836         for start < N && (*pageBits)(b).get(start) == 0 {
837                 start++
838         }
839         for end < N && (*pageBits)(b).get(N-end-1) == 0 {
840                 end++
841         }
842         run := uint(0)
843         for i := uint(0); i < N; i++ {
844                 if (*pageBits)(b).get(i) == 0 {
845                         run++
846                 } else {
847                         run = 0
848                 }
849                 most = max(most, run)
850         }
851         return PackPallocSum(start, most, end)
852 }
853
854 // Expose non-trivial helpers for testing.
855 func FindBitRange64(c uint64, n uint) uint { return findBitRange64(c, n) }
856
857 // Given two PallocBits, returns a set of bit ranges where
858 // they differ.
859 func DiffPallocBits(a, b *PallocBits) []BitRange {
860         ba := (*pageBits)(a)
861         bb := (*pageBits)(b)
862
863         var d []BitRange
864         base, size := uint(0), uint(0)
865         for i := uint(0); i < uint(len(ba))*64; i++ {
866                 if ba.get(i) != bb.get(i) {
867                         if size == 0 {
868                                 base = i
869                         }
870                         size++
871                 } else {
872                         if size != 0 {
873                                 d = append(d, BitRange{base, size})
874                         }
875                         size = 0
876                 }
877         }
878         if size != 0 {
879                 d = append(d, BitRange{base, size})
880         }
881         return d
882 }
883
884 // StringifyPallocBits gets the bits in the bit range r from b,
885 // and returns a string containing the bits as ASCII 0 and 1
886 // characters.
887 func StringifyPallocBits(b *PallocBits, r BitRange) string {
888         str := ""
889         for j := r.I; j < r.I+r.N; j++ {
890                 if (*pageBits)(b).get(j) != 0 {
891                         str += "1"
892                 } else {
893                         str += "0"
894                 }
895         }
896         return str
897 }
898
899 // Expose pallocData for testing.
900 type PallocData pallocData
901
902 func (d *PallocData) FindScavengeCandidate(searchIdx uint, min, max uintptr) (uint, uint) {
903         return (*pallocData)(d).findScavengeCandidate(searchIdx, min, max)
904 }
905 func (d *PallocData) AllocRange(i, n uint) { (*pallocData)(d).allocRange(i, n) }
906 func (d *PallocData) ScavengedSetRange(i, n uint) {
907         (*pallocData)(d).scavenged.setRange(i, n)
908 }
909 func (d *PallocData) PallocBits() *PallocBits {
910         return (*PallocBits)(&(*pallocData)(d).pallocBits)
911 }
912 func (d *PallocData) Scavenged() *PallocBits {
913         return (*PallocBits)(&(*pallocData)(d).scavenged)
914 }
915
916 // Expose fillAligned for testing.
917 func FillAligned(x uint64, m uint) uint64 { return fillAligned(x, m) }
918
919 // Expose pageCache for testing.
920 type PageCache pageCache
921
922 const PageCachePages = pageCachePages
923
924 func NewPageCache(base uintptr, cache, scav uint64) PageCache {
925         return PageCache(pageCache{base: base, cache: cache, scav: scav})
926 }
927 func (c *PageCache) Empty() bool   { return (*pageCache)(c).empty() }
928 func (c *PageCache) Base() uintptr { return (*pageCache)(c).base }
929 func (c *PageCache) Cache() uint64 { return (*pageCache)(c).cache }
930 func (c *PageCache) Scav() uint64  { return (*pageCache)(c).scav }
931 func (c *PageCache) Alloc(npages uintptr) (uintptr, uintptr) {
932         return (*pageCache)(c).alloc(npages)
933 }
934 func (c *PageCache) Flush(s *PageAlloc) {
935         cp := (*pageCache)(c)
936         sp := (*pageAlloc)(s)
937
938         systemstack(func() {
939                 // None of the tests need any higher-level locking, so we just
940                 // take the lock internally.
941                 lock(sp.mheapLock)
942                 cp.flush(sp)
943                 unlock(sp.mheapLock)
944         })
945 }
946
947 // Expose chunk index type.
948 type ChunkIdx chunkIdx
949
950 // Expose pageAlloc for testing. Note that because pageAlloc is
951 // not in the heap, so is PageAlloc.
952 type PageAlloc pageAlloc
953
954 func (p *PageAlloc) Alloc(npages uintptr) (uintptr, uintptr) {
955         pp := (*pageAlloc)(p)
956
957         var addr, scav uintptr
958         systemstack(func() {
959                 // None of the tests need any higher-level locking, so we just
960                 // take the lock internally.
961                 lock(pp.mheapLock)
962                 addr, scav = pp.alloc(npages)
963                 unlock(pp.mheapLock)
964         })
965         return addr, scav
966 }
967 func (p *PageAlloc) AllocToCache() PageCache {
968         pp := (*pageAlloc)(p)
969
970         var c PageCache
971         systemstack(func() {
972                 // None of the tests need any higher-level locking, so we just
973                 // take the lock internally.
974                 lock(pp.mheapLock)
975                 c = PageCache(pp.allocToCache())
976                 unlock(pp.mheapLock)
977         })
978         return c
979 }
980 func (p *PageAlloc) Free(base, npages uintptr) {
981         pp := (*pageAlloc)(p)
982
983         systemstack(func() {
984                 // None of the tests need any higher-level locking, so we just
985                 // take the lock internally.
986                 lock(pp.mheapLock)
987                 pp.free(base, npages)
988                 unlock(pp.mheapLock)
989         })
990 }
991 func (p *PageAlloc) Bounds() (ChunkIdx, ChunkIdx) {
992         return ChunkIdx((*pageAlloc)(p).start), ChunkIdx((*pageAlloc)(p).end)
993 }
994 func (p *PageAlloc) Scavenge(nbytes uintptr) (r uintptr) {
995         pp := (*pageAlloc)(p)
996         systemstack(func() {
997                 r = pp.scavenge(nbytes, nil, true)
998         })
999         return
1000 }
1001 func (p *PageAlloc) InUse() []AddrRange {
1002         ranges := make([]AddrRange, 0, len(p.inUse.ranges))
1003         for _, r := range p.inUse.ranges {
1004                 ranges = append(ranges, AddrRange{r})
1005         }
1006         return ranges
1007 }
1008
1009 // Returns nil if the PallocData's L2 is missing.
1010 func (p *PageAlloc) PallocData(i ChunkIdx) *PallocData {
1011         ci := chunkIdx(i)
1012         return (*PallocData)((*pageAlloc)(p).tryChunkOf(ci))
1013 }
1014
1015 // AddrRange is a wrapper around addrRange for testing.
1016 type AddrRange struct {
1017         addrRange
1018 }
1019
1020 // MakeAddrRange creates a new address range.
1021 func MakeAddrRange(base, limit uintptr) AddrRange {
1022         return AddrRange{makeAddrRange(base, limit)}
1023 }
1024
1025 // Base returns the virtual base address of the address range.
1026 func (a AddrRange) Base() uintptr {
1027         return a.addrRange.base.addr()
1028 }
1029
1030 // Base returns the virtual address of the limit of the address range.
1031 func (a AddrRange) Limit() uintptr {
1032         return a.addrRange.limit.addr()
1033 }
1034
1035 // Equals returns true if the two address ranges are exactly equal.
1036 func (a AddrRange) Equals(b AddrRange) bool {
1037         return a == b
1038 }
1039
1040 // Size returns the size in bytes of the address range.
1041 func (a AddrRange) Size() uintptr {
1042         return a.addrRange.size()
1043 }
1044
1045 // testSysStat is the sysStat passed to test versions of various
1046 // runtime structures. We do actually have to keep track of this
1047 // because otherwise memstats.mappedReady won't actually line up
1048 // with other stats in the runtime during tests.
1049 var testSysStat = &memstats.other_sys
1050
1051 // AddrRanges is a wrapper around addrRanges for testing.
1052 type AddrRanges struct {
1053         addrRanges
1054         mutable bool
1055 }
1056
1057 // NewAddrRanges creates a new empty addrRanges.
1058 //
1059 // Note that this initializes addrRanges just like in the
1060 // runtime, so its memory is persistentalloc'd. Call this
1061 // function sparingly since the memory it allocates is
1062 // leaked.
1063 //
1064 // This AddrRanges is mutable, so we can test methods like
1065 // Add.
1066 func NewAddrRanges() AddrRanges {
1067         r := addrRanges{}
1068         r.init(testSysStat)
1069         return AddrRanges{r, true}
1070 }
1071
1072 // MakeAddrRanges creates a new addrRanges populated with
1073 // the ranges in a.
1074 //
1075 // The returned AddrRanges is immutable, so methods like
1076 // Add will fail.
1077 func MakeAddrRanges(a ...AddrRange) AddrRanges {
1078         // Methods that manipulate the backing store of addrRanges.ranges should
1079         // not be used on the result from this function (e.g. add) since they may
1080         // trigger reallocation. That would normally be fine, except the new
1081         // backing store won't come from the heap, but from persistentalloc, so
1082         // we'll leak some memory implicitly.
1083         ranges := make([]addrRange, 0, len(a))
1084         total := uintptr(0)
1085         for _, r := range a {
1086                 ranges = append(ranges, r.addrRange)
1087                 total += r.Size()
1088         }
1089         return AddrRanges{addrRanges{
1090                 ranges:     ranges,
1091                 totalBytes: total,
1092                 sysStat:    testSysStat,
1093         }, false}
1094 }
1095
1096 // Ranges returns a copy of the ranges described by the
1097 // addrRanges.
1098 func (a *AddrRanges) Ranges() []AddrRange {
1099         result := make([]AddrRange, 0, len(a.addrRanges.ranges))
1100         for _, r := range a.addrRanges.ranges {
1101                 result = append(result, AddrRange{r})
1102         }
1103         return result
1104 }
1105
1106 // FindSucc returns the successor to base. See addrRanges.findSucc
1107 // for more details.
1108 func (a *AddrRanges) FindSucc(base uintptr) int {
1109         return a.findSucc(base)
1110 }
1111
1112 // Add adds a new AddrRange to the AddrRanges.
1113 //
1114 // The AddrRange must be mutable (i.e. created by NewAddrRanges),
1115 // otherwise this method will throw.
1116 func (a *AddrRanges) Add(r AddrRange) {
1117         if !a.mutable {
1118                 throw("attempt to mutate immutable AddrRanges")
1119         }
1120         a.add(r.addrRange)
1121 }
1122
1123 // TotalBytes returns the totalBytes field of the addrRanges.
1124 func (a *AddrRanges) TotalBytes() uintptr {
1125         return a.addrRanges.totalBytes
1126 }
1127
1128 // BitRange represents a range over a bitmap.
1129 type BitRange struct {
1130         I, N uint // bit index and length in bits
1131 }
1132
1133 // NewPageAlloc creates a new page allocator for testing and
1134 // initializes it with the scav and chunks maps. Each key in these maps
1135 // represents a chunk index and each value is a series of bit ranges to
1136 // set within each bitmap's chunk.
1137 //
1138 // The initialization of the pageAlloc preserves the invariant that if a
1139 // scavenged bit is set the alloc bit is necessarily unset, so some
1140 // of the bits described by scav may be cleared in the final bitmap if
1141 // ranges in chunks overlap with them.
1142 //
1143 // scav is optional, and if nil, the scavenged bitmap will be cleared
1144 // (as opposed to all 1s, which it usually is). Furthermore, every
1145 // chunk index in scav must appear in chunks; ones that do not are
1146 // ignored.
1147 func NewPageAlloc(chunks, scav map[ChunkIdx][]BitRange) *PageAlloc {
1148         p := new(pageAlloc)
1149
1150         // We've got an entry, so initialize the pageAlloc.
1151         p.init(new(mutex), testSysStat, true)
1152         lockInit(p.mheapLock, lockRankMheap)
1153         for i, init := range chunks {
1154                 addr := chunkBase(chunkIdx(i))
1155
1156                 // Mark the chunk's existence in the pageAlloc.
1157                 systemstack(func() {
1158                         lock(p.mheapLock)
1159                         p.grow(addr, pallocChunkBytes)
1160                         unlock(p.mheapLock)
1161                 })
1162
1163                 // Initialize the bitmap and update pageAlloc metadata.
1164                 ci := chunkIndex(addr)
1165                 chunk := p.chunkOf(ci)
1166
1167                 // Clear all the scavenged bits which grow set.
1168                 chunk.scavenged.clearRange(0, pallocChunkPages)
1169
1170                 // Simulate the allocation and subsequent free of all pages in
1171                 // the chunk for the scavenge index. This sets the state equivalent
1172                 // with all pages within the index being free.
1173                 p.scav.index.alloc(ci, pallocChunkPages)
1174                 p.scav.index.free(ci, 0, pallocChunkPages)
1175
1176                 // Apply scavenge state if applicable.
1177                 if scav != nil {
1178                         if scvg, ok := scav[i]; ok {
1179                                 for _, s := range scvg {
1180                                         // Ignore the case of s.N == 0. setRange doesn't handle
1181                                         // it and it's a no-op anyway.
1182                                         if s.N != 0 {
1183                                                 chunk.scavenged.setRange(s.I, s.N)
1184                                         }
1185                                 }
1186                         }
1187                 }
1188
1189                 // Apply alloc state.
1190                 for _, s := range init {
1191                         // Ignore the case of s.N == 0. allocRange doesn't handle
1192                         // it and it's a no-op anyway.
1193                         if s.N != 0 {
1194                                 chunk.allocRange(s.I, s.N)
1195
1196                                 // Make sure the scavenge index is updated.
1197                                 p.scav.index.alloc(ci, s.N)
1198                         }
1199                 }
1200
1201                 // Update heap metadata for the allocRange calls above.
1202                 systemstack(func() {
1203                         lock(p.mheapLock)
1204                         p.update(addr, pallocChunkPages, false, false)
1205                         unlock(p.mheapLock)
1206                 })
1207         }
1208
1209         return (*PageAlloc)(p)
1210 }
1211
1212 // FreePageAlloc releases hard OS resources owned by the pageAlloc. Once this
1213 // is called the pageAlloc may no longer be used. The object itself will be
1214 // collected by the garbage collector once it is no longer live.
1215 func FreePageAlloc(pp *PageAlloc) {
1216         p := (*pageAlloc)(pp)
1217
1218         // Free all the mapped space for the summary levels.
1219         if pageAlloc64Bit != 0 {
1220                 for l := 0; l < summaryLevels; l++ {
1221                         sysFreeOS(unsafe.Pointer(&p.summary[l][0]), uintptr(cap(p.summary[l]))*pallocSumBytes)
1222                 }
1223         } else {
1224                 resSize := uintptr(0)
1225                 for _, s := range p.summary {
1226                         resSize += uintptr(cap(s)) * pallocSumBytes
1227                 }
1228                 sysFreeOS(unsafe.Pointer(&p.summary[0][0]), alignUp(resSize, physPageSize))
1229         }
1230
1231         // Free extra data structures.
1232         sysFreeOS(unsafe.Pointer(&p.scav.index.chunks[0]), uintptr(cap(p.scav.index.chunks))*unsafe.Sizeof(atomicScavChunkData{}))
1233
1234         // Subtract back out whatever we mapped for the summaries.
1235         // sysUsed adds to p.sysStat and memstats.mappedReady no matter what
1236         // (and in anger should actually be accounted for), and there's no other
1237         // way to figure out how much we actually mapped.
1238         gcController.mappedReady.Add(-int64(p.summaryMappedReady))
1239         testSysStat.add(-int64(p.summaryMappedReady))
1240
1241         // Free the mapped space for chunks.
1242         for i := range p.chunks {
1243                 if x := p.chunks[i]; x != nil {
1244                         p.chunks[i] = nil
1245                         // This memory comes from sysAlloc and will always be page-aligned.
1246                         sysFree(unsafe.Pointer(x), unsafe.Sizeof(*p.chunks[0]), testSysStat)
1247                 }
1248         }
1249 }
1250
1251 // BaseChunkIdx is a convenient chunkIdx value which works on both
1252 // 64 bit and 32 bit platforms, allowing the tests to share code
1253 // between the two.
1254 //
1255 // This should not be higher than 0x100*pallocChunkBytes to support
1256 // mips and mipsle, which only have 31-bit address spaces.
1257 var BaseChunkIdx = func() ChunkIdx {
1258         var prefix uintptr
1259         if pageAlloc64Bit != 0 {
1260                 prefix = 0xc000
1261         } else {
1262                 prefix = 0x100
1263         }
1264         baseAddr := prefix * pallocChunkBytes
1265         if goos.IsAix != 0 {
1266                 baseAddr += arenaBaseOffset
1267         }
1268         return ChunkIdx(chunkIndex(baseAddr))
1269 }()
1270
1271 // PageBase returns an address given a chunk index and a page index
1272 // relative to that chunk.
1273 func PageBase(c ChunkIdx, pageIdx uint) uintptr {
1274         return chunkBase(chunkIdx(c)) + uintptr(pageIdx)*pageSize
1275 }
1276
1277 type BitsMismatch struct {
1278         Base      uintptr
1279         Got, Want uint64
1280 }
1281
1282 func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
1283         ok = true
1284
1285         // Run on the system stack to avoid stack growth allocation.
1286         systemstack(func() {
1287                 getg().m.mallocing++
1288
1289                 // Lock so that we can safely access the bitmap.
1290                 lock(&mheap_.lock)
1291         chunkLoop:
1292                 for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
1293                         chunk := mheap_.pages.tryChunkOf(i)
1294                         if chunk == nil {
1295                                 continue
1296                         }
1297                         for j := 0; j < pallocChunkPages/64; j++ {
1298                                 // Run over each 64-bit bitmap section and ensure
1299                                 // scavenged is being cleared properly on allocation.
1300                                 // If a used bit and scavenged bit are both set, that's
1301                                 // an error, and could indicate a larger problem, or
1302                                 // an accounting problem.
1303                                 want := chunk.scavenged[j] &^ chunk.pallocBits[j]
1304                                 got := chunk.scavenged[j]
1305                                 if want != got {
1306                                         ok = false
1307                                         if n >= len(mismatches) {
1308                                                 break chunkLoop
1309                                         }
1310                                         mismatches[n] = BitsMismatch{
1311                                                 Base: chunkBase(i) + uintptr(j)*64*pageSize,
1312                                                 Got:  got,
1313                                                 Want: want,
1314                                         }
1315                                         n++
1316                                 }
1317                         }
1318                 }
1319                 unlock(&mheap_.lock)
1320
1321                 getg().m.mallocing--
1322         })
1323         return
1324 }
1325
1326 func PageCachePagesLeaked() (leaked uintptr) {
1327         stopTheWorld(stwForTestPageCachePagesLeaked)
1328
1329         // Walk over destroyed Ps and look for unflushed caches.
1330         deadp := allp[len(allp):cap(allp)]
1331         for _, p := range deadp {
1332                 // Since we're going past len(allp) we may see nil Ps.
1333                 // Just ignore them.
1334                 if p != nil {
1335                         leaked += uintptr(sys.OnesCount64(p.pcache.cache))
1336                 }
1337         }
1338
1339         startTheWorld()
1340         return
1341 }
1342
1343 var Semacquire = semacquire
1344 var Semrelease1 = semrelease1
1345
1346 func SemNwait(addr *uint32) uint32 {
1347         root := semtable.rootFor(addr)
1348         return root.nwait.Load()
1349 }
1350
1351 const SemTableSize = semTabSize
1352
1353 // SemTable is a wrapper around semTable exported for testing.
1354 type SemTable struct {
1355         semTable
1356 }
1357
1358 // Enqueue simulates enqueuing a waiter for a semaphore (or lock) at addr.
1359 func (t *SemTable) Enqueue(addr *uint32) {
1360         s := acquireSudog()
1361         s.releasetime = 0
1362         s.acquiretime = 0
1363         s.ticket = 0
1364         t.semTable.rootFor(addr).queue(addr, s, false)
1365 }
1366
1367 // Dequeue simulates dequeuing a waiter for a semaphore (or lock) at addr.
1368 //
1369 // Returns true if there actually was a waiter to be dequeued.
1370 func (t *SemTable) Dequeue(addr *uint32) bool {
1371         s, _, _ := t.semTable.rootFor(addr).dequeue(addr)
1372         if s != nil {
1373                 releaseSudog(s)
1374                 return true
1375         }
1376         return false
1377 }
1378
1379 // mspan wrapper for testing.
1380 type MSpan mspan
1381
1382 // Allocate an mspan for testing.
1383 func AllocMSpan() *MSpan {
1384         var s *mspan
1385         systemstack(func() {
1386                 lock(&mheap_.lock)
1387                 s = (*mspan)(mheap_.spanalloc.alloc())
1388                 unlock(&mheap_.lock)
1389         })
1390         return (*MSpan)(s)
1391 }
1392
1393 // Free an allocated mspan.
1394 func FreeMSpan(s *MSpan) {
1395         systemstack(func() {
1396                 lock(&mheap_.lock)
1397                 mheap_.spanalloc.free(unsafe.Pointer(s))
1398                 unlock(&mheap_.lock)
1399         })
1400 }
1401
1402 func MSpanCountAlloc(ms *MSpan, bits []byte) int {
1403         s := (*mspan)(ms)
1404         s.nelems = uint16(len(bits) * 8)
1405         s.gcmarkBits = (*gcBits)(unsafe.Pointer(&bits[0]))
1406         result := s.countAlloc()
1407         s.gcmarkBits = nil
1408         return result
1409 }
1410
1411 const (
1412         TimeHistSubBucketBits = timeHistSubBucketBits
1413         TimeHistNumSubBuckets = timeHistNumSubBuckets
1414         TimeHistNumBuckets    = timeHistNumBuckets
1415         TimeHistMinBucketBits = timeHistMinBucketBits
1416         TimeHistMaxBucketBits = timeHistMaxBucketBits
1417 )
1418
1419 type TimeHistogram timeHistogram
1420
1421 // Counts returns the counts for the given bucket, subBucket indices.
1422 // Returns true if the bucket was valid, otherwise returns the counts
1423 // for the overflow bucket if bucket > 0 or the underflow bucket if
1424 // bucket < 0, and false.
1425 func (th *TimeHistogram) Count(bucket, subBucket int) (uint64, bool) {
1426         t := (*timeHistogram)(th)
1427         if bucket < 0 {
1428                 return t.underflow.Load(), false
1429         }
1430         i := bucket*TimeHistNumSubBuckets + subBucket
1431         if i >= len(t.counts) {
1432                 return t.overflow.Load(), false
1433         }
1434         return t.counts[i].Load(), true
1435 }
1436
1437 func (th *TimeHistogram) Record(duration int64) {
1438         (*timeHistogram)(th).record(duration)
1439 }
1440
1441 var TimeHistogramMetricsBuckets = timeHistogramMetricsBuckets
1442
1443 func SetIntArgRegs(a int) int {
1444         lock(&finlock)
1445         old := intArgRegs
1446         if a >= 0 {
1447                 intArgRegs = a
1448         }
1449         unlock(&finlock)
1450         return old
1451 }
1452
1453 func FinalizerGAsleep() bool {
1454         return fingStatus.Load()&fingWait != 0
1455 }
1456
1457 // For GCTestMoveStackOnNextCall, it's important not to introduce an
1458 // extra layer of call, since then there's a return before the "real"
1459 // next call.
1460 var GCTestMoveStackOnNextCall = gcTestMoveStackOnNextCall
1461
1462 // For GCTestIsReachable, it's important that we do this as a call so
1463 // escape analysis can see through it.
1464 func GCTestIsReachable(ptrs ...unsafe.Pointer) (mask uint64) {
1465         return gcTestIsReachable(ptrs...)
1466 }
1467
1468 // For GCTestPointerClass, it's important that we do this as a call so
1469 // escape analysis can see through it.
1470 //
1471 // This is nosplit because gcTestPointerClass is.
1472 //
1473 //go:nosplit
1474 func GCTestPointerClass(p unsafe.Pointer) string {
1475         return gcTestPointerClass(p)
1476 }
1477
1478 const Raceenabled = raceenabled
1479
1480 const (
1481         GCBackgroundUtilization            = gcBackgroundUtilization
1482         GCGoalUtilization                  = gcGoalUtilization
1483         DefaultHeapMinimum                 = defaultHeapMinimum
1484         MemoryLimitHeapGoalHeadroomPercent = memoryLimitHeapGoalHeadroomPercent
1485         MemoryLimitMinHeapGoalHeadroom     = memoryLimitMinHeapGoalHeadroom
1486 )
1487
1488 type GCController struct {
1489         gcControllerState
1490 }
1491
1492 func NewGCController(gcPercent int, memoryLimit int64) *GCController {
1493         // Force the controller to escape. We're going to
1494         // do 64-bit atomics on it, and if it gets stack-allocated
1495         // on a 32-bit architecture, it may get allocated unaligned
1496         // space.
1497         g := Escape(new(GCController))
1498         g.gcControllerState.test = true // Mark it as a test copy.
1499         g.init(int32(gcPercent), memoryLimit)
1500         return g
1501 }
1502
1503 func (c *GCController) StartCycle(stackSize, globalsSize uint64, scannableFrac float64, gomaxprocs int) {
1504         trigger, _ := c.trigger()
1505         if c.heapMarked > trigger {
1506                 trigger = c.heapMarked
1507         }
1508         c.maxStackScan.Store(stackSize)
1509         c.globalsScan.Store(globalsSize)
1510         c.heapLive.Store(trigger)
1511         c.heapScan.Add(int64(float64(trigger-c.heapMarked) * scannableFrac))
1512         c.startCycle(0, gomaxprocs, gcTrigger{kind: gcTriggerHeap})
1513 }
1514
1515 func (c *GCController) AssistWorkPerByte() float64 {
1516         return c.assistWorkPerByte.Load()
1517 }
1518
1519 func (c *GCController) HeapGoal() uint64 {
1520         return c.heapGoal()
1521 }
1522
1523 func (c *GCController) HeapLive() uint64 {
1524         return c.heapLive.Load()
1525 }
1526
1527 func (c *GCController) HeapMarked() uint64 {
1528         return c.heapMarked
1529 }
1530
1531 func (c *GCController) Triggered() uint64 {
1532         return c.triggered
1533 }
1534
1535 type GCControllerReviseDelta struct {
1536         HeapLive        int64
1537         HeapScan        int64
1538         HeapScanWork    int64
1539         StackScanWork   int64
1540         GlobalsScanWork int64
1541 }
1542
1543 func (c *GCController) Revise(d GCControllerReviseDelta) {
1544         c.heapLive.Add(d.HeapLive)
1545         c.heapScan.Add(d.HeapScan)
1546         c.heapScanWork.Add(d.HeapScanWork)
1547         c.stackScanWork.Add(d.StackScanWork)
1548         c.globalsScanWork.Add(d.GlobalsScanWork)
1549         c.revise()
1550 }
1551
1552 func (c *GCController) EndCycle(bytesMarked uint64, assistTime, elapsed int64, gomaxprocs int) {
1553         c.assistTime.Store(assistTime)
1554         c.endCycle(elapsed, gomaxprocs, false)
1555         c.resetLive(bytesMarked)
1556         c.commit(false)
1557 }
1558
1559 func (c *GCController) AddIdleMarkWorker() bool {
1560         return c.addIdleMarkWorker()
1561 }
1562
1563 func (c *GCController) NeedIdleMarkWorker() bool {
1564         return c.needIdleMarkWorker()
1565 }
1566
1567 func (c *GCController) RemoveIdleMarkWorker() {
1568         c.removeIdleMarkWorker()
1569 }
1570
1571 func (c *GCController) SetMaxIdleMarkWorkers(max int32) {
1572         c.setMaxIdleMarkWorkers(max)
1573 }
1574
1575 var alwaysFalse bool
1576 var escapeSink any
1577
1578 func Escape[T any](x T) T {
1579         if alwaysFalse {
1580                 escapeSink = x
1581         }
1582         return x
1583 }
1584
1585 // Acquirem blocks preemption.
1586 func Acquirem() {
1587         acquirem()
1588 }
1589
1590 func Releasem() {
1591         releasem(getg().m)
1592 }
1593
1594 var Timediv = timediv
1595
1596 type PIController struct {
1597         piController
1598 }
1599
1600 func NewPIController(kp, ti, tt, min, max float64) *PIController {
1601         return &PIController{piController{
1602                 kp:  kp,
1603                 ti:  ti,
1604                 tt:  tt,
1605                 min: min,
1606                 max: max,
1607         }}
1608 }
1609
1610 func (c *PIController) Next(input, setpoint, period float64) (float64, bool) {
1611         return c.piController.next(input, setpoint, period)
1612 }
1613
1614 const (
1615         CapacityPerProc          = capacityPerProc
1616         GCCPULimiterUpdatePeriod = gcCPULimiterUpdatePeriod
1617 )
1618
1619 type GCCPULimiter struct {
1620         limiter gcCPULimiterState
1621 }
1622
1623 func NewGCCPULimiter(now int64, gomaxprocs int32) *GCCPULimiter {
1624         // Force the controller to escape. We're going to
1625         // do 64-bit atomics on it, and if it gets stack-allocated
1626         // on a 32-bit architecture, it may get allocated unaligned
1627         // space.
1628         l := Escape(new(GCCPULimiter))
1629         l.limiter.test = true
1630         l.limiter.resetCapacity(now, gomaxprocs)
1631         return l
1632 }
1633
1634 func (l *GCCPULimiter) Fill() uint64 {
1635         return l.limiter.bucket.fill
1636 }
1637
1638 func (l *GCCPULimiter) Capacity() uint64 {
1639         return l.limiter.bucket.capacity
1640 }
1641
1642 func (l *GCCPULimiter) Overflow() uint64 {
1643         return l.limiter.overflow
1644 }
1645
1646 func (l *GCCPULimiter) Limiting() bool {
1647         return l.limiter.limiting()
1648 }
1649
1650 func (l *GCCPULimiter) NeedUpdate(now int64) bool {
1651         return l.limiter.needUpdate(now)
1652 }
1653
1654 func (l *GCCPULimiter) StartGCTransition(enableGC bool, now int64) {
1655         l.limiter.startGCTransition(enableGC, now)
1656 }
1657
1658 func (l *GCCPULimiter) FinishGCTransition(now int64) {
1659         l.limiter.finishGCTransition(now)
1660 }
1661
1662 func (l *GCCPULimiter) Update(now int64) {
1663         l.limiter.update(now)
1664 }
1665
1666 func (l *GCCPULimiter) AddAssistTime(t int64) {
1667         l.limiter.addAssistTime(t)
1668 }
1669
1670 func (l *GCCPULimiter) ResetCapacity(now int64, nprocs int32) {
1671         l.limiter.resetCapacity(now, nprocs)
1672 }
1673
1674 const ScavengePercent = scavengePercent
1675
1676 type Scavenger struct {
1677         Sleep      func(int64) int64
1678         Scavenge   func(uintptr) (uintptr, int64)
1679         ShouldStop func() bool
1680         GoMaxProcs func() int32
1681
1682         released  atomic.Uintptr
1683         scavenger scavengerState
1684         stop      chan<- struct{}
1685         done      <-chan struct{}
1686 }
1687
1688 func (s *Scavenger) Start() {
1689         if s.Sleep == nil || s.Scavenge == nil || s.ShouldStop == nil || s.GoMaxProcs == nil {
1690                 panic("must populate all stubs")
1691         }
1692
1693         // Install hooks.
1694         s.scavenger.sleepStub = s.Sleep
1695         s.scavenger.scavenge = s.Scavenge
1696         s.scavenger.shouldStop = s.ShouldStop
1697         s.scavenger.gomaxprocs = s.GoMaxProcs
1698
1699         // Start up scavenger goroutine, and wait for it to be ready.
1700         stop := make(chan struct{})
1701         s.stop = stop
1702         done := make(chan struct{})
1703         s.done = done
1704         go func() {
1705                 // This should match bgscavenge, loosely.
1706                 s.scavenger.init()
1707                 s.scavenger.park()
1708                 for {
1709                         select {
1710                         case <-stop:
1711                                 close(done)
1712                                 return
1713                         default:
1714                         }
1715                         released, workTime := s.scavenger.run()
1716                         if released == 0 {
1717                                 s.scavenger.park()
1718                                 continue
1719                         }
1720                         s.released.Add(released)
1721                         s.scavenger.sleep(workTime)
1722                 }
1723         }()
1724         if !s.BlockUntilParked(1e9 /* 1 second */) {
1725                 panic("timed out waiting for scavenger to get ready")
1726         }
1727 }
1728
1729 // BlockUntilParked blocks until the scavenger parks, or until
1730 // timeout is exceeded. Returns true if the scavenger parked.
1731 //
1732 // Note that in testing, parked means something slightly different.
1733 // In anger, the scavenger parks to sleep, too, but in testing,
1734 // it only parks when it actually has no work to do.
1735 func (s *Scavenger) BlockUntilParked(timeout int64) bool {
1736         // Just spin, waiting for it to park.
1737         //
1738         // The actual parking process is racy with respect to
1739         // wakeups, which is fine, but for testing we need something
1740         // a bit more robust.
1741         start := nanotime()
1742         for nanotime()-start < timeout {
1743                 lock(&s.scavenger.lock)
1744                 parked := s.scavenger.parked
1745                 unlock(&s.scavenger.lock)
1746                 if parked {
1747                         return true
1748                 }
1749                 Gosched()
1750         }
1751         return false
1752 }
1753
1754 // Released returns how many bytes the scavenger released.
1755 func (s *Scavenger) Released() uintptr {
1756         return s.released.Load()
1757 }
1758
1759 // Wake wakes up a parked scavenger to keep running.
1760 func (s *Scavenger) Wake() {
1761         s.scavenger.wake()
1762 }
1763
1764 // Stop cleans up the scavenger's resources. The scavenger
1765 // must be parked for this to work.
1766 func (s *Scavenger) Stop() {
1767         lock(&s.scavenger.lock)
1768         parked := s.scavenger.parked
1769         unlock(&s.scavenger.lock)
1770         if !parked {
1771                 panic("tried to clean up scavenger that is not parked")
1772         }
1773         close(s.stop)
1774         s.Wake()
1775         <-s.done
1776 }
1777
1778 type ScavengeIndex struct {
1779         i scavengeIndex
1780 }
1781
1782 func NewScavengeIndex(min, max ChunkIdx) *ScavengeIndex {
1783         s := new(ScavengeIndex)
1784         // This is a bit lazy but we easily guarantee we'll be able
1785         // to reference all the relevant chunks. The worst-case
1786         // memory usage here is 512 MiB, but tests generally use
1787         // small offsets from BaseChunkIdx, which results in ~100s
1788         // of KiB in memory use.
1789         //
1790         // This may still be worth making better, at least by sharing
1791         // this fairly large array across calls with a sync.Pool or
1792         // something. Currently, when the tests are run serially,
1793         // it takes around 0.5s. Not all that much, but if we have
1794         // a lot of tests like this it could add up.
1795         s.i.chunks = make([]atomicScavChunkData, max)
1796         s.i.min.Store(uintptr(min))
1797         s.i.max.Store(uintptr(max))
1798         s.i.minHeapIdx.Store(uintptr(min))
1799         s.i.test = true
1800         return s
1801 }
1802
1803 func (s *ScavengeIndex) Find(force bool) (ChunkIdx, uint) {
1804         ci, off := s.i.find(force)
1805         return ChunkIdx(ci), off
1806 }
1807
1808 func (s *ScavengeIndex) AllocRange(base, limit uintptr) {
1809         sc, ec := chunkIndex(base), chunkIndex(limit-1)
1810         si, ei := chunkPageIndex(base), chunkPageIndex(limit-1)
1811
1812         if sc == ec {
1813                 // The range doesn't cross any chunk boundaries.
1814                 s.i.alloc(sc, ei+1-si)
1815         } else {
1816                 // The range crosses at least one chunk boundary.
1817                 s.i.alloc(sc, pallocChunkPages-si)
1818                 for c := sc + 1; c < ec; c++ {
1819                         s.i.alloc(c, pallocChunkPages)
1820                 }
1821                 s.i.alloc(ec, ei+1)
1822         }
1823 }
1824
1825 func (s *ScavengeIndex) FreeRange(base, limit uintptr) {
1826         sc, ec := chunkIndex(base), chunkIndex(limit-1)
1827         si, ei := chunkPageIndex(base), chunkPageIndex(limit-1)
1828
1829         if sc == ec {
1830                 // The range doesn't cross any chunk boundaries.
1831                 s.i.free(sc, si, ei+1-si)
1832         } else {
1833                 // The range crosses at least one chunk boundary.
1834                 s.i.free(sc, si, pallocChunkPages-si)
1835                 for c := sc + 1; c < ec; c++ {
1836                         s.i.free(c, 0, pallocChunkPages)
1837                 }
1838                 s.i.free(ec, 0, ei+1)
1839         }
1840 }
1841
1842 func (s *ScavengeIndex) ResetSearchAddrs() {
1843         for _, a := range []*atomicOffAddr{&s.i.searchAddrBg, &s.i.searchAddrForce} {
1844                 addr, marked := a.Load()
1845                 if marked {
1846                         a.StoreUnmark(addr, addr)
1847                 }
1848                 a.Clear()
1849         }
1850         s.i.freeHWM = minOffAddr
1851 }
1852
1853 func (s *ScavengeIndex) NextGen() {
1854         s.i.nextGen()
1855 }
1856
1857 func (s *ScavengeIndex) SetEmpty(ci ChunkIdx) {
1858         s.i.setEmpty(chunkIdx(ci))
1859 }
1860
1861 func CheckPackScavChunkData(gen uint32, inUse, lastInUse uint16, flags uint8) bool {
1862         sc0 := scavChunkData{
1863                 gen:            gen,
1864                 inUse:          inUse,
1865                 lastInUse:      lastInUse,
1866                 scavChunkFlags: scavChunkFlags(flags),
1867         }
1868         scp := sc0.pack()
1869         sc1 := unpackScavChunkData(scp)
1870         return sc0 == sc1
1871 }
1872
1873 const GTrackingPeriod = gTrackingPeriod
1874
1875 var ZeroBase = unsafe.Pointer(&zerobase)
1876
1877 const UserArenaChunkBytes = userArenaChunkBytes
1878
1879 type UserArena struct {
1880         arena *userArena
1881 }
1882
1883 func NewUserArena() *UserArena {
1884         return &UserArena{newUserArena()}
1885 }
1886
1887 func (a *UserArena) New(out *any) {
1888         i := efaceOf(out)
1889         typ := i._type
1890         if typ.Kind_&kindMask != kindPtr {
1891                 panic("new result of non-ptr type")
1892         }
1893         typ = (*ptrtype)(unsafe.Pointer(typ)).Elem
1894         i.data = a.arena.new(typ)
1895 }
1896
1897 func (a *UserArena) Slice(sl any, cap int) {
1898         a.arena.slice(sl, cap)
1899 }
1900
1901 func (a *UserArena) Free() {
1902         a.arena.free()
1903 }
1904
1905 func GlobalWaitingArenaChunks() int {
1906         n := 0
1907         systemstack(func() {
1908                 lock(&mheap_.lock)
1909                 for s := mheap_.userArena.quarantineList.first; s != nil; s = s.next {
1910                         n++
1911                 }
1912                 unlock(&mheap_.lock)
1913         })
1914         return n
1915 }
1916
1917 func UserArenaClone[T any](s T) T {
1918         return arena_heapify(s).(T)
1919 }
1920
1921 var AlignUp = alignUp
1922
1923 // BlockUntilEmptyFinalizerQueue blocks until either the finalizer
1924 // queue is emptied (and the finalizers have executed) or the timeout
1925 // is reached. Returns true if the finalizer queue was emptied.
1926 func BlockUntilEmptyFinalizerQueue(timeout int64) bool {
1927         start := nanotime()
1928         for nanotime()-start < timeout {
1929                 lock(&finlock)
1930                 // We know the queue has been drained when both finq is nil
1931                 // and the finalizer g has stopped executing.
1932                 empty := finq == nil
1933                 empty = empty && readgstatus(fing) == _Gwaiting && fing.waitreason == waitReasonFinalizerWait
1934                 unlock(&finlock)
1935                 if empty {
1936                         return true
1937                 }
1938                 Gosched()
1939         }
1940         return false
1941 }
1942
1943 func FrameStartLine(f *Frame) int {
1944         return f.startLine
1945 }
1946
1947 // PersistentAlloc allocates some memory that lives outside the Go heap.
1948 // This memory will never be freed; use sparingly.
1949 func PersistentAlloc(n uintptr) unsafe.Pointer {
1950         return persistentalloc(n, 0, &memstats.other_sys)
1951 }
1952
1953 // FPCallers works like Callers and uses frame pointer unwinding to populate
1954 // pcBuf with the return addresses of the physical frames on the stack.
1955 func FPCallers(pcBuf []uintptr) int {
1956         return fpTracebackPCs(unsafe.Pointer(getfp()), pcBuf)
1957 }
1958
1959 const FramePointerEnabled = framepointer_enabled
1960
1961 var (
1962         IsPinned      = isPinned
1963         GetPinCounter = pinnerGetPinCounter
1964 )
1965
1966 func SetPinnerLeakPanic(f func()) {
1967         pinnerLeakPanic = f
1968 }
1969 func GetPinnerLeakPanic() func() {
1970         return pinnerLeakPanic
1971 }
1972
1973 var testUintptr uintptr
1974
1975 func MyGenericFunc[T any]() {
1976         systemstack(func() {
1977                 testUintptr = 4
1978         })
1979 }
1980
1981 func UnsafePoint(pc uintptr) bool {
1982         fi := findfunc(pc)
1983         v := pcdatavalue(fi, abi.PCDATA_UnsafePoint, pc)
1984         switch v {
1985         case abi.UnsafePointUnsafe:
1986                 return true
1987         case abi.UnsafePointSafe:
1988                 return false
1989         case abi.UnsafePointRestart1, abi.UnsafePointRestart2, abi.UnsafePointRestartAtEntry:
1990                 // These are all interruptible, they just encode a nonstandard
1991                 // way of recovering when interrupted.
1992                 return false
1993         default:
1994                 var buf [20]byte
1995                 panic("invalid unsafe point code " + string(itoa(buf[:], uint64(v))))
1996         }
1997 }