github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/mheap.go (about) 1 // Copyright 2009 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 // Page heap. 6 // 7 // See malloc.go for overview. 8 9 package runtime 10 11 import ( 12 "internal/cpu" 13 "internal/goarch" 14 "runtime/internal/atomic" 15 "runtime/internal/sys" 16 "unsafe" 17 ) 18 19 const ( 20 // minPhysPageSize is a lower-bound on the physical page size. The 21 // true physical page size may be larger than this. In contrast, 22 // sys.PhysPageSize is an upper-bound on the physical page size. 23 minPhysPageSize = 4096 24 25 // maxPhysPageSize is the maximum page size the runtime supports. 26 maxPhysPageSize = 512 << 10 27 28 // maxPhysHugePageSize sets an upper-bound on the maximum huge page size 29 // that the runtime supports. 30 maxPhysHugePageSize = pallocChunkBytes 31 32 // pagesPerReclaimerChunk indicates how many pages to scan from the 33 // pageInUse bitmap at a time. Used by the page reclaimer. 34 // 35 // Higher values reduce contention on scanning indexes (such as 36 // h.reclaimIndex), but increase the minimum latency of the 37 // operation. 38 // 39 // The time required to scan this many pages can vary a lot depending 40 // on how many spans are actually freed. Experimentally, it can 41 // scan for pages at ~300 GB/ms on a 2.6GHz Core i7, but can only 42 // free spans at ~32 MB/ms. Using 512 pages bounds this at 43 // roughly 100µs. 44 // 45 // Must be a multiple of the pageInUse bitmap element size and 46 // must also evenly divide pagesPerArena. 47 pagesPerReclaimerChunk = 512 48 49 // physPageAlignedStacks indicates whether stack allocations must be 50 // physical page aligned. This is a requirement for MAP_STACK on 51 // OpenBSD. 52 physPageAlignedStacks = GOOS == "openbsd" 53 ) 54 55 // Main malloc heap. 56 // The heap itself is the "free" and "scav" treaps, 57 // but all the other global data is here too. 58 // 59 // mheap must not be heap-allocated because it contains mSpanLists, 60 // which must not be heap-allocated. 61 type mheap struct { 62 _ sys.NotInHeap 63 64 // lock must only be acquired on the system stack, otherwise a g 65 // could self-deadlock if its stack grows with the lock held. 66 lock mutex 67 68 pages pageAlloc // page allocation data structure 69 70 sweepgen uint32 // sweep generation, see comment in mspan; written during STW 71 72 // allspans is a slice of all mspans ever created. Each mspan 73 // appears exactly once. 74 // 75 // The memory for allspans is manually managed and can be 76 // reallocated and move as the heap grows. 77 // 78 // In general, allspans is protected by mheap_.lock, which 79 // prevents concurrent access as well as freeing the backing 80 // store. Accesses during STW might not hold the lock, but 81 // must ensure that allocation cannot happen around the 82 // access (since that may free the backing store). 83 allspans []*mspan // all spans out there 84 85 // Proportional sweep 86 // 87 // These parameters represent a linear function from gcController.heapLive 88 // to page sweep count. The proportional sweep system works to 89 // stay in the black by keeping the current page sweep count 90 // above this line at the current gcController.heapLive. 91 // 92 // The line has slope sweepPagesPerByte and passes through a 93 // basis point at (sweepHeapLiveBasis, pagesSweptBasis). At 94 // any given time, the system is at (gcController.heapLive, 95 // pagesSwept) in this space. 96 // 97 // It is important that the line pass through a point we 98 // control rather than simply starting at a 0,0 origin 99 // because that lets us adjust sweep pacing at any time while 100 // accounting for current progress. If we could only adjust 101 // the slope, it would create a discontinuity in debt if any 102 // progress has already been made. 103 pagesInUse atomic.Uintptr // pages of spans in stats mSpanInUse 104 pagesSwept atomic.Uint64 // pages swept this cycle 105 pagesSweptBasis atomic.Uint64 // pagesSwept to use as the origin of the sweep ratio 106 sweepHeapLiveBasis uint64 // value of gcController.heapLive to use as the origin of sweep ratio; written with lock, read without 107 sweepPagesPerByte float64 // proportional sweep ratio; written with lock, read without 108 109 // Page reclaimer state 110 111 // reclaimIndex is the page index in allArenas of next page to 112 // reclaim. Specifically, it refers to page (i % 113 // pagesPerArena) of arena allArenas[i / pagesPerArena]. 114 // 115 // If this is >= 1<<63, the page reclaimer is done scanning 116 // the page marks. 117 reclaimIndex atomic.Uint64 118 119 // reclaimCredit is spare credit for extra pages swept. Since 120 // the page reclaimer works in large chunks, it may reclaim 121 // more than requested. Any spare pages released go to this 122 // credit pool. 123 reclaimCredit atomic.Uintptr 124 125 // arenas is the heap arena map. It points to the metadata for 126 // the heap for every arena frame of the entire usable virtual 127 // address space. 128 // 129 // Use arenaIndex to compute indexes into this array. 130 // 131 // For regions of the address space that are not backed by the 132 // Go heap, the arena map contains nil. 133 // 134 // Modifications are protected by mheap_.lock. Reads can be 135 // performed without locking; however, a given entry can 136 // transition from nil to non-nil at any time when the lock 137 // isn't held. (Entries never transitions back to nil.) 138 // 139 // In general, this is a two-level mapping consisting of an L1 140 // map and possibly many L2 maps. This saves space when there 141 // are a huge number of arena frames. However, on many 142 // platforms (even 64-bit), arenaL1Bits is 0, making this 143 // effectively a single-level map. In this case, arenas[0] 144 // will never be nil. 145 arenas [1 << arenaL1Bits]*[1 << arenaL2Bits]*heapArena 146 147 // arenasHugePages indicates whether arenas' L2 entries are eligible 148 // to be backed by huge pages. 149 arenasHugePages bool 150 151 // heapArenaAlloc is pre-reserved space for allocating heapArena 152 // objects. This is only used on 32-bit, where we pre-reserve 153 // this space to avoid interleaving it with the heap itself. 154 heapArenaAlloc linearAlloc 155 156 // arenaHints is a list of addresses at which to attempt to 157 // add more heap arenas. This is initially populated with a 158 // set of general hint addresses, and grown with the bounds of 159 // actual heap arena ranges. 160 arenaHints *arenaHint 161 162 // arena is a pre-reserved space for allocating heap arenas 163 // (the actual arenas). This is only used on 32-bit. 164 arena linearAlloc 165 166 // allArenas is the arenaIndex of every mapped arena. This can 167 // be used to iterate through the address space. 168 // 169 // Access is protected by mheap_.lock. However, since this is 170 // append-only and old backing arrays are never freed, it is 171 // safe to acquire mheap_.lock, copy the slice header, and 172 // then release mheap_.lock. 173 allArenas []arenaIdx 174 175 // sweepArenas is a snapshot of allArenas taken at the 176 // beginning of the sweep cycle. This can be read safely by 177 // simply blocking GC (by disabling preemption). 178 sweepArenas []arenaIdx 179 180 // markArenas is a snapshot of allArenas taken at the beginning 181 // of the mark cycle. Because allArenas is append-only, neither 182 // this slice nor its contents will change during the mark, so 183 // it can be read safely. 184 markArenas []arenaIdx 185 186 // curArena is the arena that the heap is currently growing 187 // into. This should always be physPageSize-aligned. 188 curArena struct { 189 base, end uintptr 190 } 191 192 // central free lists for small size classes. 193 // the padding makes sure that the mcentrals are 194 // spaced CacheLinePadSize bytes apart, so that each mcentral.lock 195 // gets its own cache line. 196 // central is indexed by spanClass. 197 central [numSpanClasses]struct { 198 mcentral mcentral 199 pad [(cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte 200 } 201 202 spanalloc fixalloc // allocator for span* 203 cachealloc fixalloc // allocator for mcache* 204 specialfinalizeralloc fixalloc // allocator for specialfinalizer* 205 specialprofilealloc fixalloc // allocator for specialprofile* 206 specialReachableAlloc fixalloc // allocator for specialReachable 207 speciallock mutex // lock for special record allocators. 208 arenaHintAlloc fixalloc // allocator for arenaHints 209 210 // User arena state. 211 // 212 // Protected by mheap_.lock. 213 userArena struct { 214 // arenaHints is a list of addresses at which to attempt to 215 // add more heap arenas for user arena chunks. This is initially 216 // populated with a set of general hint addresses, and grown with 217 // the bounds of actual heap arena ranges. 218 arenaHints *arenaHint 219 220 // quarantineList is a list of user arena spans that have been set to fault, but 221 // are waiting for all pointers into them to go away. Sweeping handles 222 // identifying when this is true, and moves the span to the ready list. 223 quarantineList mSpanList 224 225 // readyList is a list of empty user arena spans that are ready for reuse. 226 readyList mSpanList 227 } 228 229 unused *specialfinalizer // never set, just here to force the specialfinalizer type into DWARF 230 } 231 232 var mheap_ mheap 233 234 // A heapArena stores metadata for a heap arena. heapArenas are stored 235 // outside of the Go heap and accessed via the mheap_.arenas index. 236 type heapArena struct { 237 _ sys.NotInHeap 238 239 // bitmap stores the pointer/scalar bitmap for the words in 240 // this arena. See mbitmap.go for a description. 241 // This array uses 1 bit per word of heap, or 1.6% of the heap size (for 64-bit). 242 bitmap [heapArenaBitmapWords]uintptr 243 244 // If the ith bit of noMorePtrs is true, then there are no more 245 // pointers for the object containing the word described by the 246 // high bit of bitmap[i]. 247 // In that case, bitmap[i+1], ... must be zero until the start 248 // of the next object. 249 // We never operate on these entries using bit-parallel techniques, 250 // so it is ok if they are small. Also, they can't be bigger than 251 // uint16 because at that size a single noMorePtrs entry 252 // represents 8K of memory, the minimum size of a span. Any larger 253 // and we'd have to worry about concurrent updates. 254 // This array uses 1 bit per word of bitmap, or .024% of the heap size (for 64-bit). 255 noMorePtrs [heapArenaBitmapWords / 8]uint8 256 257 // spans maps from virtual address page ID within this arena to *mspan. 258 // For allocated spans, their pages map to the span itself. 259 // For free spans, only the lowest and highest pages map to the span itself. 260 // Internal pages map to an arbitrary span. 261 // For pages that have never been allocated, spans entries are nil. 262 // 263 // Modifications are protected by mheap.lock. Reads can be 264 // performed without locking, but ONLY from indexes that are 265 // known to contain in-use or stack spans. This means there 266 // must not be a safe-point between establishing that an 267 // address is live and looking it up in the spans array. 268 spans [pagesPerArena]*mspan 269 270 // pageInUse is a bitmap that indicates which spans are in 271 // state mSpanInUse. This bitmap is indexed by page number, 272 // but only the bit corresponding to the first page in each 273 // span is used. 274 // 275 // Reads and writes are atomic. 276 pageInUse [pagesPerArena / 8]uint8 277 278 // pageMarks is a bitmap that indicates which spans have any 279 // marked objects on them. Like pageInUse, only the bit 280 // corresponding to the first page in each span is used. 281 // 282 // Writes are done atomically during marking. Reads are 283 // non-atomic and lock-free since they only occur during 284 // sweeping (and hence never race with writes). 285 // 286 // This is used to quickly find whole spans that can be freed. 287 // 288 // TODO(austin): It would be nice if this was uint64 for 289 // faster scanning, but we don't have 64-bit atomic bit 290 // operations. 291 pageMarks [pagesPerArena / 8]uint8 292 293 // pageSpecials is a bitmap that indicates which spans have 294 // specials (finalizers or other). Like pageInUse, only the bit 295 // corresponding to the first page in each span is used. 296 // 297 // Writes are done atomically whenever a special is added to 298 // a span and whenever the last special is removed from a span. 299 // Reads are done atomically to find spans containing specials 300 // during marking. 301 pageSpecials [pagesPerArena / 8]uint8 302 303 // checkmarks stores the debug.gccheckmark state. It is only 304 // used if debug.gccheckmark > 0. 305 checkmarks *checkmarksMap 306 307 // zeroedBase marks the first byte of the first page in this 308 // arena which hasn't been used yet and is therefore already 309 // zero. zeroedBase is relative to the arena base. 310 // Increases monotonically until it hits heapArenaBytes. 311 // 312 // This field is sufficient to determine if an allocation 313 // needs to be zeroed because the page allocator follows an 314 // address-ordered first-fit policy. 315 // 316 // Read atomically and written with an atomic CAS. 317 zeroedBase uintptr 318 } 319 320 // arenaHint is a hint for where to grow the heap arenas. See 321 // mheap_.arenaHints. 322 type arenaHint struct { 323 _ sys.NotInHeap 324 addr uintptr 325 down bool 326 next *arenaHint 327 } 328 329 // An mspan is a run of pages. 330 // 331 // When a mspan is in the heap free treap, state == mSpanFree 332 // and heapmap(s->start) == span, heapmap(s->start+s->npages-1) == span. 333 // If the mspan is in the heap scav treap, then in addition to the 334 // above scavenged == true. scavenged == false in all other cases. 335 // 336 // When a mspan is allocated, state == mSpanInUse or mSpanManual 337 // and heapmap(i) == span for all s->start <= i < s->start+s->npages. 338 339 // Every mspan is in one doubly-linked list, either in the mheap's 340 // busy list or one of the mcentral's span lists. 341 342 // An mspan representing actual memory has state mSpanInUse, 343 // mSpanManual, or mSpanFree. Transitions between these states are 344 // constrained as follows: 345 // 346 // - A span may transition from free to in-use or manual during any GC 347 // phase. 348 // 349 // - During sweeping (gcphase == _GCoff), a span may transition from 350 // in-use to free (as a result of sweeping) or manual to free (as a 351 // result of stacks being freed). 352 // 353 // - During GC (gcphase != _GCoff), a span *must not* transition from 354 // manual or in-use to free. Because concurrent GC may read a pointer 355 // and then look up its span, the span state must be monotonic. 356 // 357 // Setting mspan.state to mSpanInUse or mSpanManual must be done 358 // atomically and only after all other span fields are valid. 359 // Likewise, if inspecting a span is contingent on it being 360 // mSpanInUse, the state should be loaded atomically and checked 361 // before depending on other fields. This allows the garbage collector 362 // to safely deal with potentially invalid pointers, since resolving 363 // such pointers may race with a span being allocated. 364 type mSpanState uint8 365 366 const ( 367 mSpanDead mSpanState = iota 368 mSpanInUse // allocated for garbage collected heap 369 mSpanManual // allocated for manual management (e.g., stack allocator) 370 ) 371 372 // mSpanStateNames are the names of the span states, indexed by 373 // mSpanState. 374 var mSpanStateNames = []string{ 375 "mSpanDead", 376 "mSpanInUse", 377 "mSpanManual", 378 } 379 380 // mSpanStateBox holds an atomic.Uint8 to provide atomic operations on 381 // an mSpanState. This is a separate type to disallow accidental comparison 382 // or assignment with mSpanState. 383 type mSpanStateBox struct { 384 s atomic.Uint8 385 } 386 387 // It is nosplit to match get, below. 388 389 //go:nosplit 390 func (b *mSpanStateBox) set(s mSpanState) { 391 b.s.Store(uint8(s)) 392 } 393 394 // It is nosplit because it's called indirectly by typedmemclr, 395 // which must not be preempted. 396 397 //go:nosplit 398 func (b *mSpanStateBox) get() mSpanState { 399 return mSpanState(b.s.Load()) 400 } 401 402 // mSpanList heads a linked list of spans. 403 type mSpanList struct { 404 _ sys.NotInHeap 405 first *mspan // first span in list, or nil if none 406 last *mspan // last span in list, or nil if none 407 } 408 409 type mspan struct { 410 _ sys.NotInHeap 411 next *mspan // next span in list, or nil if none 412 prev *mspan // previous span in list, or nil if none 413 list *mSpanList // For debugging. TODO: Remove. 414 415 startAddr uintptr // address of first byte of span aka s.base() 416 npages uintptr // number of pages in span 417 418 manualFreeList gclinkptr // list of free objects in mSpanManual spans 419 420 // freeindex is the slot index between 0 and nelems at which to begin scanning 421 // for the next free object in this span. 422 // Each allocation scans allocBits starting at freeindex until it encounters a 0 423 // indicating a free object. freeindex is then adjusted so that subsequent scans begin 424 // just past the newly discovered free object. 425 // 426 // If freeindex == nelem, this span has no free objects. 427 // 428 // allocBits is a bitmap of objects in this span. 429 // If n >= freeindex and allocBits[n/8] & (1<<(n%8)) is 0 430 // then object n is free; 431 // otherwise, object n is allocated. Bits starting at nelem are 432 // undefined and should never be referenced. 433 // 434 // Object n starts at address n*elemsize + (start << pageShift). 435 freeindex uintptr 436 // TODO: Look up nelems from sizeclass and remove this field if it 437 // helps performance. 438 nelems uintptr // number of object in the span. 439 440 // Cache of the allocBits at freeindex. allocCache is shifted 441 // such that the lowest bit corresponds to the bit freeindex. 442 // allocCache holds the complement of allocBits, thus allowing 443 // ctz (count trailing zero) to use it directly. 444 // allocCache may contain bits beyond s.nelems; the caller must ignore 445 // these. 446 allocCache uint64 447 448 // allocBits and gcmarkBits hold pointers to a span's mark and 449 // allocation bits. The pointers are 8 byte aligned. 450 // There are three arenas where this data is held. 451 // free: Dirty arenas that are no longer accessed 452 // and can be reused. 453 // next: Holds information to be used in the next GC cycle. 454 // current: Information being used during this GC cycle. 455 // previous: Information being used during the last GC cycle. 456 // A new GC cycle starts with the call to finishsweep_m. 457 // finishsweep_m moves the previous arena to the free arena, 458 // the current arena to the previous arena, and 459 // the next arena to the current arena. 460 // The next arena is populated as the spans request 461 // memory to hold gcmarkBits for the next GC cycle as well 462 // as allocBits for newly allocated spans. 463 // 464 // The pointer arithmetic is done "by hand" instead of using 465 // arrays to avoid bounds checks along critical performance 466 // paths. 467 // The sweep will free the old allocBits and set allocBits to the 468 // gcmarkBits. The gcmarkBits are replaced with a fresh zeroed 469 // out memory. 470 allocBits *gcBits 471 gcmarkBits *gcBits 472 473 // sweep generation: 474 // if sweepgen == h->sweepgen - 2, the span needs sweeping 475 // if sweepgen == h->sweepgen - 1, the span is currently being swept 476 // if sweepgen == h->sweepgen, the span is swept and ready to use 477 // if sweepgen == h->sweepgen + 1, the span was cached before sweep began and is still cached, and needs sweeping 478 // if sweepgen == h->sweepgen + 3, the span was swept and then cached and is still cached 479 // h->sweepgen is incremented by 2 after every GC 480 481 sweepgen uint32 482 divMul uint32 // for divide by elemsize 483 allocCount uint16 // number of allocated objects 484 spanclass spanClass // size class and noscan (uint8) 485 state mSpanStateBox // mSpanInUse etc; accessed atomically (get/set methods) 486 needzero uint8 // needs to be zeroed before allocation 487 isUserArenaChunk bool // whether or not this span represents a user arena 488 allocCountBeforeCache uint16 // a copy of allocCount that is stored just before this span is cached 489 elemsize uintptr // computed from sizeclass or from npages 490 limit uintptr // end of data in span 491 speciallock mutex // guards specials list 492 specials *special // linked list of special records sorted by offset. 493 userArenaChunkFree addrRange // interval for managing chunk allocation 494 495 // freeIndexForScan is like freeindex, except that freeindex is 496 // used by the allocator whereas freeIndexForScan is used by the 497 // GC scanner. They are two fields so that the GC sees the object 498 // is allocated only when the object and the heap bits are 499 // initialized (see also the assignment of freeIndexForScan in 500 // mallocgc, and issue 54596). 501 freeIndexForScan uintptr 502 } 503 504 func (s *mspan) base() uintptr { 505 return s.startAddr 506 } 507 508 func (s *mspan) layout() (size, n, total uintptr) { 509 total = s.npages << _PageShift 510 size = s.elemsize 511 if size > 0 { 512 n = total / size 513 } 514 return 515 } 516 517 // recordspan adds a newly allocated span to h.allspans. 518 // 519 // This only happens the first time a span is allocated from 520 // mheap.spanalloc (it is not called when a span is reused). 521 // 522 // Write barriers are disallowed here because it can be called from 523 // gcWork when allocating new workbufs. However, because it's an 524 // indirect call from the fixalloc initializer, the compiler can't see 525 // this. 526 // 527 // The heap lock must be held. 528 // 529 //go:nowritebarrierrec 530 func recordspan(vh unsafe.Pointer, p unsafe.Pointer) { 531 h := (*mheap)(vh) 532 s := (*mspan)(p) 533 534 assertLockHeld(&h.lock) 535 536 if len(h.allspans) >= cap(h.allspans) { 537 n := 64 * 1024 / goarch.PtrSize 538 if n < cap(h.allspans)*3/2 { 539 n = cap(h.allspans) * 3 / 2 540 } 541 var new []*mspan 542 sp := (*slice)(unsafe.Pointer(&new)) 543 sp.array = sysAlloc(uintptr(n)*goarch.PtrSize, &memstats.other_sys) 544 if sp.array == nil { 545 throw("runtime: cannot allocate memory") 546 } 547 sp.len = len(h.allspans) 548 sp.cap = n 549 if len(h.allspans) > 0 { 550 copy(new, h.allspans) 551 } 552 oldAllspans := h.allspans 553 *(*notInHeapSlice)(unsafe.Pointer(&h.allspans)) = *(*notInHeapSlice)(unsafe.Pointer(&new)) 554 if len(oldAllspans) != 0 { 555 sysFree(unsafe.Pointer(&oldAllspans[0]), uintptr(cap(oldAllspans))*unsafe.Sizeof(oldAllspans[0]), &memstats.other_sys) 556 } 557 } 558 h.allspans = h.allspans[:len(h.allspans)+1] 559 h.allspans[len(h.allspans)-1] = s 560 } 561 562 // A spanClass represents the size class and noscan-ness of a span. 563 // 564 // Each size class has a noscan spanClass and a scan spanClass. The 565 // noscan spanClass contains only noscan objects, which do not contain 566 // pointers and thus do not need to be scanned by the garbage 567 // collector. 568 type spanClass uint8 569 570 const ( 571 numSpanClasses = _NumSizeClasses << 1 572 tinySpanClass = spanClass(tinySizeClass<<1 | 1) 573 ) 574 575 func makeSpanClass(sizeclass uint8, noscan bool) spanClass { 576 return spanClass(sizeclass<<1) | spanClass(bool2int(noscan)) 577 } 578 579 func (sc spanClass) sizeclass() int8 { 580 return int8(sc >> 1) 581 } 582 583 func (sc spanClass) noscan() bool { 584 return sc&1 != 0 585 } 586 587 // arenaIndex returns the index into mheap_.arenas of the arena 588 // containing metadata for p. This index combines of an index into the 589 // L1 map and an index into the L2 map and should be used as 590 // mheap_.arenas[ai.l1()][ai.l2()]. 591 // 592 // If p is outside the range of valid heap addresses, either l1() or 593 // l2() will be out of bounds. 594 // 595 // It is nosplit because it's called by spanOf and several other 596 // nosplit functions. 597 // 598 //go:nosplit 599 func arenaIndex(p uintptr) arenaIdx { 600 return arenaIdx((p - arenaBaseOffset) / heapArenaBytes) 601 } 602 603 // arenaBase returns the low address of the region covered by heap 604 // arena i. 605 func arenaBase(i arenaIdx) uintptr { 606 return uintptr(i)*heapArenaBytes + arenaBaseOffset 607 } 608 609 type arenaIdx uint 610 611 // l1 returns the "l1" portion of an arenaIdx. 612 // 613 // Marked nosplit because it's called by spanOf and other nosplit 614 // functions. 615 // 616 //go:nosplit 617 func (i arenaIdx) l1() uint { 618 if arenaL1Bits == 0 { 619 // Let the compiler optimize this away if there's no 620 // L1 map. 621 return 0 622 } else { 623 return uint(i) >> arenaL1Shift 624 } 625 } 626 627 // l2 returns the "l2" portion of an arenaIdx. 628 // 629 // Marked nosplit because it's called by spanOf and other nosplit funcs. 630 // functions. 631 // 632 //go:nosplit 633 func (i arenaIdx) l2() uint { 634 if arenaL1Bits == 0 { 635 return uint(i) 636 } else { 637 return uint(i) & (1<<arenaL2Bits - 1) 638 } 639 } 640 641 // inheap reports whether b is a pointer into a (potentially dead) heap object. 642 // It returns false for pointers into mSpanManual spans. 643 // Non-preemptible because it is used by write barriers. 644 // 645 //go:nowritebarrier 646 //go:nosplit 647 func inheap(b uintptr) bool { 648 return spanOfHeap(b) != nil 649 } 650 651 // inHeapOrStack is a variant of inheap that returns true for pointers 652 // into any allocated heap span. 653 // 654 //go:nowritebarrier 655 //go:nosplit 656 func inHeapOrStack(b uintptr) bool { 657 s := spanOf(b) 658 if s == nil || b < s.base() { 659 return false 660 } 661 switch s.state.get() { 662 case mSpanInUse, mSpanManual: 663 return b < s.limit 664 default: 665 return false 666 } 667 } 668 669 // spanOf returns the span of p. If p does not point into the heap 670 // arena or no span has ever contained p, spanOf returns nil. 671 // 672 // If p does not point to allocated memory, this may return a non-nil 673 // span that does *not* contain p. If this is a possibility, the 674 // caller should either call spanOfHeap or check the span bounds 675 // explicitly. 676 // 677 // Must be nosplit because it has callers that are nosplit. 678 // 679 //go:nosplit 680 func spanOf(p uintptr) *mspan { 681 // This function looks big, but we use a lot of constant 682 // folding around arenaL1Bits to get it under the inlining 683 // budget. Also, many of the checks here are safety checks 684 // that Go needs to do anyway, so the generated code is quite 685 // short. 686 ri := arenaIndex(p) 687 if arenaL1Bits == 0 { 688 // If there's no L1, then ri.l1() can't be out of bounds but ri.l2() can. 689 if ri.l2() >= uint(len(mheap_.arenas[0])) { 690 return nil 691 } 692 } else { 693 // If there's an L1, then ri.l1() can be out of bounds but ri.l2() can't. 694 if ri.l1() >= uint(len(mheap_.arenas)) { 695 return nil 696 } 697 } 698 l2 := mheap_.arenas[ri.l1()] 699 if arenaL1Bits != 0 && l2 == nil { // Should never happen if there's no L1. 700 return nil 701 } 702 ha := l2[ri.l2()] 703 if ha == nil { 704 return nil 705 } 706 return ha.spans[(p/pageSize)%pagesPerArena] 707 } 708 709 // spanOfUnchecked is equivalent to spanOf, but the caller must ensure 710 // that p points into an allocated heap arena. 711 // 712 // Must be nosplit because it has callers that are nosplit. 713 // 714 //go:nosplit 715 func spanOfUnchecked(p uintptr) *mspan { 716 ai := arenaIndex(p) 717 return mheap_.arenas[ai.l1()][ai.l2()].spans[(p/pageSize)%pagesPerArena] 718 } 719 720 // spanOfHeap is like spanOf, but returns nil if p does not point to a 721 // heap object. 722 // 723 // Must be nosplit because it has callers that are nosplit. 724 // 725 //go:nosplit 726 func spanOfHeap(p uintptr) *mspan { 727 s := spanOf(p) 728 // s is nil if it's never been allocated. Otherwise, we check 729 // its state first because we don't trust this pointer, so we 730 // have to synchronize with span initialization. Then, it's 731 // still possible we picked up a stale span pointer, so we 732 // have to check the span's bounds. 733 if s == nil || s.state.get() != mSpanInUse || p < s.base() || p >= s.limit { 734 return nil 735 } 736 return s 737 } 738 739 // pageIndexOf returns the arena, page index, and page mask for pointer p. 740 // The caller must ensure p is in the heap. 741 func pageIndexOf(p uintptr) (arena *heapArena, pageIdx uintptr, pageMask uint8) { 742 ai := arenaIndex(p) 743 arena = mheap_.arenas[ai.l1()][ai.l2()] 744 pageIdx = ((p / pageSize) / 8) % uintptr(len(arena.pageInUse)) 745 pageMask = byte(1 << ((p / pageSize) % 8)) 746 return 747 } 748 749 // Initialize the heap. 750 func (h *mheap) init() { 751 lockInit(&h.lock, lockRankMheap) 752 lockInit(&h.speciallock, lockRankMheapSpecial) 753 754 h.spanalloc.init(unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &memstats.mspan_sys) 755 h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys) 756 h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys) 757 h.specialprofilealloc.init(unsafe.Sizeof(specialprofile{}), nil, nil, &memstats.other_sys) 758 h.specialReachableAlloc.init(unsafe.Sizeof(specialReachable{}), nil, nil, &memstats.other_sys) 759 h.arenaHintAlloc.init(unsafe.Sizeof(arenaHint{}), nil, nil, &memstats.other_sys) 760 761 // Don't zero mspan allocations. Background sweeping can 762 // inspect a span concurrently with allocating it, so it's 763 // important that the span's sweepgen survive across freeing 764 // and re-allocating a span to prevent background sweeping 765 // from improperly cas'ing it from 0. 766 // 767 // This is safe because mspan contains no heap pointers. 768 h.spanalloc.zero = false 769 770 // h->mapcache needs no init 771 772 for i := range h.central { 773 h.central[i].mcentral.init(spanClass(i)) 774 } 775 776 h.pages.init(&h.lock, &memstats.gcMiscSys, false) 777 } 778 779 // reclaim sweeps and reclaims at least npage pages into the heap. 780 // It is called before allocating npage pages to keep growth in check. 781 // 782 // reclaim implements the page-reclaimer half of the sweeper. 783 // 784 // h.lock must NOT be held. 785 func (h *mheap) reclaim(npage uintptr) { 786 // TODO(austin): Half of the time spent freeing spans is in 787 // locking/unlocking the heap (even with low contention). We 788 // could make the slow path here several times faster by 789 // batching heap frees. 790 791 // Bail early if there's no more reclaim work. 792 if h.reclaimIndex.Load() >= 1<<63 { 793 return 794 } 795 796 // Disable preemption so the GC can't start while we're 797 // sweeping, so we can read h.sweepArenas, and so 798 // traceGCSweepStart/Done pair on the P. 799 mp := acquirem() 800 801 if traceEnabled() { 802 traceGCSweepStart() 803 } 804 805 arenas := h.sweepArenas 806 locked := false 807 for npage > 0 { 808 // Pull from accumulated credit first. 809 if credit := h.reclaimCredit.Load(); credit > 0 { 810 take := credit 811 if take > npage { 812 // Take only what we need. 813 take = npage 814 } 815 if h.reclaimCredit.CompareAndSwap(credit, credit-take) { 816 npage -= take 817 } 818 continue 819 } 820 821 // Claim a chunk of work. 822 idx := uintptr(h.reclaimIndex.Add(pagesPerReclaimerChunk) - pagesPerReclaimerChunk) 823 if idx/pagesPerArena >= uintptr(len(arenas)) { 824 // Page reclaiming is done. 825 h.reclaimIndex.Store(1 << 63) 826 break 827 } 828 829 if !locked { 830 // Lock the heap for reclaimChunk. 831 lock(&h.lock) 832 locked = true 833 } 834 835 // Scan this chunk. 836 nfound := h.reclaimChunk(arenas, idx, pagesPerReclaimerChunk) 837 if nfound <= npage { 838 npage -= nfound 839 } else { 840 // Put spare pages toward global credit. 841 h.reclaimCredit.Add(nfound - npage) 842 npage = 0 843 } 844 } 845 if locked { 846 unlock(&h.lock) 847 } 848 849 if traceEnabled() { 850 traceGCSweepDone() 851 } 852 releasem(mp) 853 } 854 855 // reclaimChunk sweeps unmarked spans that start at page indexes [pageIdx, pageIdx+n). 856 // It returns the number of pages returned to the heap. 857 // 858 // h.lock must be held and the caller must be non-preemptible. Note: h.lock may be 859 // temporarily unlocked and re-locked in order to do sweeping or if tracing is 860 // enabled. 861 func (h *mheap) reclaimChunk(arenas []arenaIdx, pageIdx, n uintptr) uintptr { 862 // The heap lock must be held because this accesses the 863 // heapArena.spans arrays using potentially non-live pointers. 864 // In particular, if a span were freed and merged concurrently 865 // with this probing heapArena.spans, it would be possible to 866 // observe arbitrary, stale span pointers. 867 assertLockHeld(&h.lock) 868 869 n0 := n 870 var nFreed uintptr 871 sl := sweep.active.begin() 872 if !sl.valid { 873 return 0 874 } 875 for n > 0 { 876 ai := arenas[pageIdx/pagesPerArena] 877 ha := h.arenas[ai.l1()][ai.l2()] 878 879 // Get a chunk of the bitmap to work on. 880 arenaPage := uint(pageIdx % pagesPerArena) 881 inUse := ha.pageInUse[arenaPage/8:] 882 marked := ha.pageMarks[arenaPage/8:] 883 if uintptr(len(inUse)) > n/8 { 884 inUse = inUse[:n/8] 885 marked = marked[:n/8] 886 } 887 888 // Scan this bitmap chunk for spans that are in-use 889 // but have no marked objects on them. 890 for i := range inUse { 891 inUseUnmarked := atomic.Load8(&inUse[i]) &^ marked[i] 892 if inUseUnmarked == 0 { 893 continue 894 } 895 896 for j := uint(0); j < 8; j++ { 897 if inUseUnmarked&(1<<j) != 0 { 898 s := ha.spans[arenaPage+uint(i)*8+j] 899 if s, ok := sl.tryAcquire(s); ok { 900 npages := s.npages 901 unlock(&h.lock) 902 if s.sweep(false) { 903 nFreed += npages 904 } 905 lock(&h.lock) 906 // Reload inUse. It's possible nearby 907 // spans were freed when we dropped the 908 // lock and we don't want to get stale 909 // pointers from the spans array. 910 inUseUnmarked = atomic.Load8(&inUse[i]) &^ marked[i] 911 } 912 } 913 } 914 } 915 916 // Advance. 917 pageIdx += uintptr(len(inUse) * 8) 918 n -= uintptr(len(inUse) * 8) 919 } 920 sweep.active.end(sl) 921 if traceEnabled() { 922 unlock(&h.lock) 923 // Account for pages scanned but not reclaimed. 924 traceGCSweepSpan((n0 - nFreed) * pageSize) 925 lock(&h.lock) 926 } 927 928 assertLockHeld(&h.lock) // Must be locked on return. 929 return nFreed 930 } 931 932 // spanAllocType represents the type of allocation to make, or 933 // the type of allocation to be freed. 934 type spanAllocType uint8 935 936 const ( 937 spanAllocHeap spanAllocType = iota // heap span 938 spanAllocStack // stack span 939 spanAllocPtrScalarBits // unrolled GC prog bitmap span 940 spanAllocWorkBuf // work buf span 941 ) 942 943 // manual returns true if the span allocation is manually managed. 944 func (s spanAllocType) manual() bool { 945 return s != spanAllocHeap 946 } 947 948 // alloc allocates a new span of npage pages from the GC'd heap. 949 // 950 // spanclass indicates the span's size class and scannability. 951 // 952 // Returns a span that has been fully initialized. span.needzero indicates 953 // whether the span has been zeroed. Note that it may not be. 954 func (h *mheap) alloc(npages uintptr, spanclass spanClass) *mspan { 955 // Don't do any operations that lock the heap on the G stack. 956 // It might trigger stack growth, and the stack growth code needs 957 // to be able to allocate heap. 958 var s *mspan 959 systemstack(func() { 960 // To prevent excessive heap growth, before allocating n pages 961 // we need to sweep and reclaim at least n pages. 962 if !isSweepDone() { 963 h.reclaim(npages) 964 } 965 s = h.allocSpan(npages, spanAllocHeap, spanclass) 966 }) 967 return s 968 } 969 970 // allocManual allocates a manually-managed span of npage pages. 971 // allocManual returns nil if allocation fails. 972 // 973 // allocManual adds the bytes used to *stat, which should be a 974 // memstats in-use field. Unlike allocations in the GC'd heap, the 975 // allocation does *not* count toward heapInUse. 976 // 977 // The memory backing the returned span may not be zeroed if 978 // span.needzero is set. 979 // 980 // allocManual must be called on the system stack because it may 981 // acquire the heap lock via allocSpan. See mheap for details. 982 // 983 // If new code is written to call allocManual, do NOT use an 984 // existing spanAllocType value and instead declare a new one. 985 // 986 //go:systemstack 987 func (h *mheap) allocManual(npages uintptr, typ spanAllocType) *mspan { 988 if !typ.manual() { 989 throw("manual span allocation called with non-manually-managed type") 990 } 991 return h.allocSpan(npages, typ, 0) 992 } 993 994 // setSpans modifies the span map so [spanOf(base), spanOf(base+npage*pageSize)) 995 // is s. 996 func (h *mheap) setSpans(base, npage uintptr, s *mspan) { 997 p := base / pageSize 998 ai := arenaIndex(base) 999 ha := h.arenas[ai.l1()][ai.l2()] 1000 for n := uintptr(0); n < npage; n++ { 1001 i := (p + n) % pagesPerArena 1002 if i == 0 { 1003 ai = arenaIndex(base + n*pageSize) 1004 ha = h.arenas[ai.l1()][ai.l2()] 1005 } 1006 ha.spans[i] = s 1007 } 1008 } 1009 1010 // allocNeedsZero checks if the region of address space [base, base+npage*pageSize), 1011 // assumed to be allocated, needs to be zeroed, updating heap arena metadata for 1012 // future allocations. 1013 // 1014 // This must be called each time pages are allocated from the heap, even if the page 1015 // allocator can otherwise prove the memory it's allocating is already zero because 1016 // they're fresh from the operating system. It updates heapArena metadata that is 1017 // critical for future page allocations. 1018 // 1019 // There are no locking constraints on this method. 1020 func (h *mheap) allocNeedsZero(base, npage uintptr) (needZero bool) { 1021 for npage > 0 { 1022 ai := arenaIndex(base) 1023 ha := h.arenas[ai.l1()][ai.l2()] 1024 1025 zeroedBase := atomic.Loaduintptr(&ha.zeroedBase) 1026 arenaBase := base % heapArenaBytes 1027 if arenaBase < zeroedBase { 1028 // We extended into the non-zeroed part of the 1029 // arena, so this region needs to be zeroed before use. 1030 // 1031 // zeroedBase is monotonically increasing, so if we see this now then 1032 // we can be sure we need to zero this memory region. 1033 // 1034 // We still need to update zeroedBase for this arena, and 1035 // potentially more arenas. 1036 needZero = true 1037 } 1038 // We may observe arenaBase > zeroedBase if we're racing with one or more 1039 // allocations which are acquiring memory directly before us in the address 1040 // space. But, because we know no one else is acquiring *this* memory, it's 1041 // still safe to not zero. 1042 1043 // Compute how far into the arena we extend into, capped 1044 // at heapArenaBytes. 1045 arenaLimit := arenaBase + npage*pageSize 1046 if arenaLimit > heapArenaBytes { 1047 arenaLimit = heapArenaBytes 1048 } 1049 // Increase ha.zeroedBase so it's >= arenaLimit. 1050 // We may be racing with other updates. 1051 for arenaLimit > zeroedBase { 1052 if atomic.Casuintptr(&ha.zeroedBase, zeroedBase, arenaLimit) { 1053 break 1054 } 1055 zeroedBase = atomic.Loaduintptr(&ha.zeroedBase) 1056 // Double check basic conditions of zeroedBase. 1057 if zeroedBase <= arenaLimit && zeroedBase > arenaBase { 1058 // The zeroedBase moved into the space we were trying to 1059 // claim. That's very bad, and indicates someone allocated 1060 // the same region we did. 1061 throw("potentially overlapping in-use allocations detected") 1062 } 1063 } 1064 1065 // Move base forward and subtract from npage to move into 1066 // the next arena, or finish. 1067 base += arenaLimit - arenaBase 1068 npage -= (arenaLimit - arenaBase) / pageSize 1069 } 1070 return 1071 } 1072 1073 // tryAllocMSpan attempts to allocate an mspan object from 1074 // the P-local cache, but may fail. 1075 // 1076 // h.lock need not be held. 1077 // 1078 // This caller must ensure that its P won't change underneath 1079 // it during this function. Currently to ensure that we enforce 1080 // that the function is run on the system stack, because that's 1081 // the only place it is used now. In the future, this requirement 1082 // may be relaxed if its use is necessary elsewhere. 1083 // 1084 //go:systemstack 1085 func (h *mheap) tryAllocMSpan() *mspan { 1086 pp := getg().m.p.ptr() 1087 // If we don't have a p or the cache is empty, we can't do 1088 // anything here. 1089 if pp == nil || pp.mspancache.len == 0 { 1090 return nil 1091 } 1092 // Pull off the last entry in the cache. 1093 s := pp.mspancache.buf[pp.mspancache.len-1] 1094 pp.mspancache.len-- 1095 return s 1096 } 1097 1098 // allocMSpanLocked allocates an mspan object. 1099 // 1100 // h.lock must be held. 1101 // 1102 // allocMSpanLocked must be called on the system stack because 1103 // its caller holds the heap lock. See mheap for details. 1104 // Running on the system stack also ensures that we won't 1105 // switch Ps during this function. See tryAllocMSpan for details. 1106 // 1107 //go:systemstack 1108 func (h *mheap) allocMSpanLocked() *mspan { 1109 assertLockHeld(&h.lock) 1110 1111 pp := getg().m.p.ptr() 1112 if pp == nil { 1113 // We don't have a p so just do the normal thing. 1114 return (*mspan)(h.spanalloc.alloc()) 1115 } 1116 // Refill the cache if necessary. 1117 if pp.mspancache.len == 0 { 1118 const refillCount = len(pp.mspancache.buf) / 2 1119 for i := 0; i < refillCount; i++ { 1120 pp.mspancache.buf[i] = (*mspan)(h.spanalloc.alloc()) 1121 } 1122 pp.mspancache.len = refillCount 1123 } 1124 // Pull off the last entry in the cache. 1125 s := pp.mspancache.buf[pp.mspancache.len-1] 1126 pp.mspancache.len-- 1127 return s 1128 } 1129 1130 // freeMSpanLocked free an mspan object. 1131 // 1132 // h.lock must be held. 1133 // 1134 // freeMSpanLocked must be called on the system stack because 1135 // its caller holds the heap lock. See mheap for details. 1136 // Running on the system stack also ensures that we won't 1137 // switch Ps during this function. See tryAllocMSpan for details. 1138 // 1139 //go:systemstack 1140 func (h *mheap) freeMSpanLocked(s *mspan) { 1141 assertLockHeld(&h.lock) 1142 1143 pp := getg().m.p.ptr() 1144 // First try to free the mspan directly to the cache. 1145 if pp != nil && pp.mspancache.len < len(pp.mspancache.buf) { 1146 pp.mspancache.buf[pp.mspancache.len] = s 1147 pp.mspancache.len++ 1148 return 1149 } 1150 // Failing that (or if we don't have a p), just free it to 1151 // the heap. 1152 h.spanalloc.free(unsafe.Pointer(s)) 1153 } 1154 1155 // allocSpan allocates an mspan which owns npages worth of memory. 1156 // 1157 // If typ.manual() == false, allocSpan allocates a heap span of class spanclass 1158 // and updates heap accounting. If manual == true, allocSpan allocates a 1159 // manually-managed span (spanclass is ignored), and the caller is 1160 // responsible for any accounting related to its use of the span. Either 1161 // way, allocSpan will atomically add the bytes in the newly allocated 1162 // span to *sysStat. 1163 // 1164 // The returned span is fully initialized. 1165 // 1166 // h.lock must not be held. 1167 // 1168 // allocSpan must be called on the system stack both because it acquires 1169 // the heap lock and because it must block GC transitions. 1170 // 1171 //go:systemstack 1172 func (h *mheap) allocSpan(npages uintptr, typ spanAllocType, spanclass spanClass) (s *mspan) { 1173 // Function-global state. 1174 gp := getg() 1175 base, scav := uintptr(0), uintptr(0) 1176 growth := uintptr(0) 1177 1178 // On some platforms we need to provide physical page aligned stack 1179 // allocations. Where the page size is less than the physical page 1180 // size, we already manage to do this by default. 1181 needPhysPageAlign := physPageAlignedStacks && typ == spanAllocStack && pageSize < physPageSize 1182 1183 // If the allocation is small enough, try the page cache! 1184 // The page cache does not support aligned allocations, so we cannot use 1185 // it if we need to provide a physical page aligned stack allocation. 1186 pp := gp.m.p.ptr() 1187 if !needPhysPageAlign && pp != nil && npages < pageCachePages/4 { 1188 c := &pp.pcache 1189 1190 // If the cache is empty, refill it. 1191 if c.empty() { 1192 lock(&h.lock) 1193 *c = h.pages.allocToCache() 1194 unlock(&h.lock) 1195 } 1196 1197 // Try to allocate from the cache. 1198 base, scav = c.alloc(npages) 1199 if base != 0 { 1200 s = h.tryAllocMSpan() 1201 if s != nil { 1202 goto HaveSpan 1203 } 1204 // We have a base but no mspan, so we need 1205 // to lock the heap. 1206 } 1207 } 1208 1209 // For one reason or another, we couldn't get the 1210 // whole job done without the heap lock. 1211 lock(&h.lock) 1212 1213 if needPhysPageAlign { 1214 // Overallocate by a physical page to allow for later alignment. 1215 extraPages := physPageSize / pageSize 1216 1217 // Find a big enough region first, but then only allocate the 1218 // aligned portion. We can't just allocate and then free the 1219 // edges because we need to account for scavenged memory, and 1220 // that's difficult with alloc. 1221 // 1222 // Note that we skip updates to searchAddr here. It's OK if 1223 // it's stale and higher than normal; it'll operate correctly, 1224 // just come with a performance cost. 1225 base, _ = h.pages.find(npages + extraPages) 1226 if base == 0 { 1227 var ok bool 1228 growth, ok = h.grow(npages + extraPages) 1229 if !ok { 1230 unlock(&h.lock) 1231 return nil 1232 } 1233 base, _ = h.pages.find(npages + extraPages) 1234 if base == 0 { 1235 throw("grew heap, but no adequate free space found") 1236 } 1237 } 1238 base = alignUp(base, physPageSize) 1239 scav = h.pages.allocRange(base, npages) 1240 } 1241 1242 if base == 0 { 1243 // Try to acquire a base address. 1244 base, scav = h.pages.alloc(npages) 1245 if base == 0 { 1246 var ok bool 1247 growth, ok = h.grow(npages) 1248 if !ok { 1249 unlock(&h.lock) 1250 return nil 1251 } 1252 base, scav = h.pages.alloc(npages) 1253 if base == 0 { 1254 throw("grew heap, but no adequate free space found") 1255 } 1256 } 1257 } 1258 if s == nil { 1259 // We failed to get an mspan earlier, so grab 1260 // one now that we have the heap lock. 1261 s = h.allocMSpanLocked() 1262 } 1263 unlock(&h.lock) 1264 1265 HaveSpan: 1266 // Decide if we need to scavenge in response to what we just allocated. 1267 // Specifically, we track the maximum amount of memory to scavenge of all 1268 // the alternatives below, assuming that the maximum satisfies *all* 1269 // conditions we check (e.g. if we need to scavenge X to satisfy the 1270 // memory limit and Y to satisfy heap-growth scavenging, and Y > X, then 1271 // it's fine to pick Y, because the memory limit is still satisfied). 1272 // 1273 // It's fine to do this after allocating because we expect any scavenged 1274 // pages not to get touched until we return. Simultaneously, it's important 1275 // to do this before calling sysUsed because that may commit address space. 1276 bytesToScavenge := uintptr(0) 1277 forceScavenge := false 1278 if limit := gcController.memoryLimit.Load(); !gcCPULimiter.limiting() { 1279 // Assist with scavenging to maintain the memory limit by the amount 1280 // that we expect to page in. 1281 inuse := gcController.mappedReady.Load() 1282 // Be careful about overflow, especially with uintptrs. Even on 32-bit platforms 1283 // someone can set a really big memory limit that isn't maxInt64. 1284 if uint64(scav)+inuse > uint64(limit) { 1285 bytesToScavenge = uintptr(uint64(scav) + inuse - uint64(limit)) 1286 forceScavenge = true 1287 } 1288 } 1289 if goal := scavenge.gcPercentGoal.Load(); goal != ^uint64(0) && growth > 0 { 1290 // We just caused a heap growth, so scavenge down what will soon be used. 1291 // By scavenging inline we deal with the failure to allocate out of 1292 // memory fragments by scavenging the memory fragments that are least 1293 // likely to be re-used. 1294 // 1295 // Only bother with this because we're not using a memory limit. We don't 1296 // care about heap growths as long as we're under the memory limit, and the 1297 // previous check for scaving already handles that. 1298 if retained := heapRetained(); retained+uint64(growth) > goal { 1299 // The scavenging algorithm requires the heap lock to be dropped so it 1300 // can acquire it only sparingly. This is a potentially expensive operation 1301 // so it frees up other goroutines to allocate in the meanwhile. In fact, 1302 // they can make use of the growth we just created. 1303 todo := growth 1304 if overage := uintptr(retained + uint64(growth) - goal); todo > overage { 1305 todo = overage 1306 } 1307 if todo > bytesToScavenge { 1308 bytesToScavenge = todo 1309 } 1310 } 1311 } 1312 // There are a few very limited circumstances where we won't have a P here. 1313 // It's OK to simply skip scavenging in these cases. Something else will notice 1314 // and pick up the tab. 1315 var now int64 1316 if pp != nil && bytesToScavenge > 0 { 1317 // Measure how long we spent scavenging and add that measurement to the assist 1318 // time so we can track it for the GC CPU limiter. 1319 // 1320 // Limiter event tracking might be disabled if we end up here 1321 // while on a mark worker. 1322 start := nanotime() 1323 track := pp.limiterEvent.start(limiterEventScavengeAssist, start) 1324 1325 // Scavenge, but back out if the limiter turns on. 1326 h.pages.scavenge(bytesToScavenge, func() bool { 1327 return gcCPULimiter.limiting() 1328 }, forceScavenge) 1329 1330 // Finish up accounting. 1331 now = nanotime() 1332 if track { 1333 pp.limiterEvent.stop(limiterEventScavengeAssist, now) 1334 } 1335 scavenge.assistTime.Add(now - start) 1336 } 1337 1338 // Initialize the span. 1339 h.initSpan(s, typ, spanclass, base, npages) 1340 1341 // Commit and account for any scavenged memory that the span now owns. 1342 nbytes := npages * pageSize 1343 if scav != 0 { 1344 // sysUsed all the pages that are actually available 1345 // in the span since some of them might be scavenged. 1346 sysUsed(unsafe.Pointer(base), nbytes, scav) 1347 gcController.heapReleased.add(-int64(scav)) 1348 } 1349 // Update stats. 1350 gcController.heapFree.add(-int64(nbytes - scav)) 1351 if typ == spanAllocHeap { 1352 gcController.heapInUse.add(int64(nbytes)) 1353 } 1354 // Update consistent stats. 1355 stats := memstats.heapStats.acquire() 1356 atomic.Xaddint64(&stats.committed, int64(scav)) 1357 atomic.Xaddint64(&stats.released, -int64(scav)) 1358 switch typ { 1359 case spanAllocHeap: 1360 atomic.Xaddint64(&stats.inHeap, int64(nbytes)) 1361 case spanAllocStack: 1362 atomic.Xaddint64(&stats.inStacks, int64(nbytes)) 1363 case spanAllocPtrScalarBits: 1364 atomic.Xaddint64(&stats.inPtrScalarBits, int64(nbytes)) 1365 case spanAllocWorkBuf: 1366 atomic.Xaddint64(&stats.inWorkBufs, int64(nbytes)) 1367 } 1368 memstats.heapStats.release() 1369 1370 pageTraceAlloc(pp, now, base, npages) 1371 return s 1372 } 1373 1374 // initSpan initializes a blank span s which will represent the range 1375 // [base, base+npages*pageSize). typ is the type of span being allocated. 1376 func (h *mheap) initSpan(s *mspan, typ spanAllocType, spanclass spanClass, base, npages uintptr) { 1377 // At this point, both s != nil and base != 0, and the heap 1378 // lock is no longer held. Initialize the span. 1379 s.init(base, npages) 1380 if h.allocNeedsZero(base, npages) { 1381 s.needzero = 1 1382 } 1383 nbytes := npages * pageSize 1384 if typ.manual() { 1385 s.manualFreeList = 0 1386 s.nelems = 0 1387 s.limit = s.base() + s.npages*pageSize 1388 s.state.set(mSpanManual) 1389 } else { 1390 // We must set span properties before the span is published anywhere 1391 // since we're not holding the heap lock. 1392 s.spanclass = spanclass 1393 if sizeclass := spanclass.sizeclass(); sizeclass == 0 { 1394 s.elemsize = nbytes 1395 s.nelems = 1 1396 s.divMul = 0 1397 } else { 1398 s.elemsize = uintptr(class_to_size[sizeclass]) 1399 s.nelems = nbytes / s.elemsize 1400 s.divMul = class_to_divmagic[sizeclass] 1401 } 1402 1403 // Initialize mark and allocation structures. 1404 s.freeindex = 0 1405 s.freeIndexForScan = 0 1406 s.allocCache = ^uint64(0) // all 1s indicating all free. 1407 s.gcmarkBits = newMarkBits(s.nelems) 1408 s.allocBits = newAllocBits(s.nelems) 1409 1410 // It's safe to access h.sweepgen without the heap lock because it's 1411 // only ever updated with the world stopped and we run on the 1412 // systemstack which blocks a STW transition. 1413 atomic.Store(&s.sweepgen, h.sweepgen) 1414 1415 // Now that the span is filled in, set its state. This 1416 // is a publication barrier for the other fields in 1417 // the span. While valid pointers into this span 1418 // should never be visible until the span is returned, 1419 // if the garbage collector finds an invalid pointer, 1420 // access to the span may race with initialization of 1421 // the span. We resolve this race by atomically 1422 // setting the state after the span is fully 1423 // initialized, and atomically checking the state in 1424 // any situation where a pointer is suspect. 1425 s.state.set(mSpanInUse) 1426 } 1427 1428 // Publish the span in various locations. 1429 1430 // This is safe to call without the lock held because the slots 1431 // related to this span will only ever be read or modified by 1432 // this thread until pointers into the span are published (and 1433 // we execute a publication barrier at the end of this function 1434 // before that happens) or pageInUse is updated. 1435 h.setSpans(s.base(), npages, s) 1436 1437 if !typ.manual() { 1438 // Mark in-use span in arena page bitmap. 1439 // 1440 // This publishes the span to the page sweeper, so 1441 // it's imperative that the span be completely initialized 1442 // prior to this line. 1443 arena, pageIdx, pageMask := pageIndexOf(s.base()) 1444 atomic.Or8(&arena.pageInUse[pageIdx], pageMask) 1445 1446 // Update related page sweeper stats. 1447 h.pagesInUse.Add(npages) 1448 } 1449 1450 // Make sure the newly allocated span will be observed 1451 // by the GC before pointers into the span are published. 1452 publicationBarrier() 1453 } 1454 1455 // Try to add at least npage pages of memory to the heap, 1456 // returning how much the heap grew by and whether it worked. 1457 // 1458 // h.lock must be held. 1459 func (h *mheap) grow(npage uintptr) (uintptr, bool) { 1460 assertLockHeld(&h.lock) 1461 1462 // We must grow the heap in whole palloc chunks. 1463 // We call sysMap below but note that because we 1464 // round up to pallocChunkPages which is on the order 1465 // of MiB (generally >= to the huge page size) we 1466 // won't be calling it too much. 1467 ask := alignUp(npage, pallocChunkPages) * pageSize 1468 1469 totalGrowth := uintptr(0) 1470 // This may overflow because ask could be very large 1471 // and is otherwise unrelated to h.curArena.base. 1472 end := h.curArena.base + ask 1473 nBase := alignUp(end, physPageSize) 1474 if nBase > h.curArena.end || /* overflow */ end < h.curArena.base { 1475 // Not enough room in the current arena. Allocate more 1476 // arena space. This may not be contiguous with the 1477 // current arena, so we have to request the full ask. 1478 av, asize := h.sysAlloc(ask, &h.arenaHints, true) 1479 if av == nil { 1480 inUse := gcController.heapFree.load() + gcController.heapReleased.load() + gcController.heapInUse.load() 1481 print("runtime: out of memory: cannot allocate ", ask, "-byte block (", inUse, " in use)\n") 1482 return 0, false 1483 } 1484 1485 if uintptr(av) == h.curArena.end { 1486 // The new space is contiguous with the old 1487 // space, so just extend the current space. 1488 h.curArena.end = uintptr(av) + asize 1489 } else { 1490 // The new space is discontiguous. Track what 1491 // remains of the current space and switch to 1492 // the new space. This should be rare. 1493 if size := h.curArena.end - h.curArena.base; size != 0 { 1494 // Transition this space from Reserved to Prepared and mark it 1495 // as released since we'll be able to start using it after updating 1496 // the page allocator and releasing the lock at any time. 1497 sysMap(unsafe.Pointer(h.curArena.base), size, &gcController.heapReleased) 1498 // Update stats. 1499 stats := memstats.heapStats.acquire() 1500 atomic.Xaddint64(&stats.released, int64(size)) 1501 memstats.heapStats.release() 1502 // Update the page allocator's structures to make this 1503 // space ready for allocation. 1504 h.pages.grow(h.curArena.base, size) 1505 totalGrowth += size 1506 } 1507 // Switch to the new space. 1508 h.curArena.base = uintptr(av) 1509 h.curArena.end = uintptr(av) + asize 1510 } 1511 1512 // Recalculate nBase. 1513 // We know this won't overflow, because sysAlloc returned 1514 // a valid region starting at h.curArena.base which is at 1515 // least ask bytes in size. 1516 nBase = alignUp(h.curArena.base+ask, physPageSize) 1517 } 1518 1519 // Grow into the current arena. 1520 v := h.curArena.base 1521 h.curArena.base = nBase 1522 1523 // Transition the space we're going to use from Reserved to Prepared. 1524 // 1525 // The allocation is always aligned to the heap arena 1526 // size which is always > physPageSize, so its safe to 1527 // just add directly to heapReleased. 1528 sysMap(unsafe.Pointer(v), nBase-v, &gcController.heapReleased) 1529 1530 // The memory just allocated counts as both released 1531 // and idle, even though it's not yet backed by spans. 1532 stats := memstats.heapStats.acquire() 1533 atomic.Xaddint64(&stats.released, int64(nBase-v)) 1534 memstats.heapStats.release() 1535 1536 // Update the page allocator's structures to make this 1537 // space ready for allocation. 1538 h.pages.grow(v, nBase-v) 1539 totalGrowth += nBase - v 1540 return totalGrowth, true 1541 } 1542 1543 // Free the span back into the heap. 1544 func (h *mheap) freeSpan(s *mspan) { 1545 systemstack(func() { 1546 pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages) 1547 1548 lock(&h.lock) 1549 if msanenabled { 1550 // Tell msan that this entire span is no longer in use. 1551 base := unsafe.Pointer(s.base()) 1552 bytes := s.npages << _PageShift 1553 msanfree(base, bytes) 1554 } 1555 if asanenabled { 1556 // Tell asan that this entire span is no longer in use. 1557 base := unsafe.Pointer(s.base()) 1558 bytes := s.npages << _PageShift 1559 asanpoison(base, bytes) 1560 } 1561 h.freeSpanLocked(s, spanAllocHeap) 1562 unlock(&h.lock) 1563 }) 1564 } 1565 1566 // freeManual frees a manually-managed span returned by allocManual. 1567 // typ must be the same as the spanAllocType passed to the allocManual that 1568 // allocated s. 1569 // 1570 // This must only be called when gcphase == _GCoff. See mSpanState for 1571 // an explanation. 1572 // 1573 // freeManual must be called on the system stack because it acquires 1574 // the heap lock. See mheap for details. 1575 // 1576 //go:systemstack 1577 func (h *mheap) freeManual(s *mspan, typ spanAllocType) { 1578 pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages) 1579 1580 s.needzero = 1 1581 lock(&h.lock) 1582 h.freeSpanLocked(s, typ) 1583 unlock(&h.lock) 1584 } 1585 1586 func (h *mheap) freeSpanLocked(s *mspan, typ spanAllocType) { 1587 assertLockHeld(&h.lock) 1588 1589 switch s.state.get() { 1590 case mSpanManual: 1591 if s.allocCount != 0 { 1592 throw("mheap.freeSpanLocked - invalid stack free") 1593 } 1594 case mSpanInUse: 1595 if s.isUserArenaChunk { 1596 throw("mheap.freeSpanLocked - invalid free of user arena chunk") 1597 } 1598 if s.allocCount != 0 || s.sweepgen != h.sweepgen { 1599 print("mheap.freeSpanLocked - span ", s, " ptr ", hex(s.base()), " allocCount ", s.allocCount, " sweepgen ", s.sweepgen, "/", h.sweepgen, "\n") 1600 throw("mheap.freeSpanLocked - invalid free") 1601 } 1602 h.pagesInUse.Add(-s.npages) 1603 1604 // Clear in-use bit in arena page bitmap. 1605 arena, pageIdx, pageMask := pageIndexOf(s.base()) 1606 atomic.And8(&arena.pageInUse[pageIdx], ^pageMask) 1607 default: 1608 throw("mheap.freeSpanLocked - invalid span state") 1609 } 1610 1611 // Update stats. 1612 // 1613 // Mirrors the code in allocSpan. 1614 nbytes := s.npages * pageSize 1615 gcController.heapFree.add(int64(nbytes)) 1616 if typ == spanAllocHeap { 1617 gcController.heapInUse.add(-int64(nbytes)) 1618 } 1619 // Update consistent stats. 1620 stats := memstats.heapStats.acquire() 1621 switch typ { 1622 case spanAllocHeap: 1623 atomic.Xaddint64(&stats.inHeap, -int64(nbytes)) 1624 case spanAllocStack: 1625 atomic.Xaddint64(&stats.inStacks, -int64(nbytes)) 1626 case spanAllocPtrScalarBits: 1627 atomic.Xaddint64(&stats.inPtrScalarBits, -int64(nbytes)) 1628 case spanAllocWorkBuf: 1629 atomic.Xaddint64(&stats.inWorkBufs, -int64(nbytes)) 1630 } 1631 memstats.heapStats.release() 1632 1633 // Mark the space as free. 1634 h.pages.free(s.base(), s.npages) 1635 1636 // Free the span structure. We no longer have a use for it. 1637 s.state.set(mSpanDead) 1638 h.freeMSpanLocked(s) 1639 } 1640 1641 // scavengeAll acquires the heap lock (blocking any additional 1642 // manipulation of the page allocator) and iterates over the whole 1643 // heap, scavenging every free page available. 1644 // 1645 // Must run on the system stack because it acquires the heap lock. 1646 // 1647 //go:systemstack 1648 func (h *mheap) scavengeAll() { 1649 // Disallow malloc or panic while holding the heap lock. We do 1650 // this here because this is a non-mallocgc entry-point to 1651 // the mheap API. 1652 gp := getg() 1653 gp.m.mallocing++ 1654 1655 // Force scavenge everything. 1656 released := h.pages.scavenge(^uintptr(0), nil, true) 1657 1658 gp.m.mallocing-- 1659 1660 if debug.scavtrace > 0 { 1661 printScavTrace(released, true) 1662 } 1663 } 1664 1665 //go:linkname runtime_debug_freeOSMemory runtime/debug.freeOSMemory 1666 func runtime_debug_freeOSMemory() { 1667 GC() 1668 systemstack(func() { mheap_.scavengeAll() }) 1669 } 1670 1671 // Initialize a new span with the given start and npages. 1672 func (span *mspan) init(base uintptr, npages uintptr) { 1673 // span is *not* zeroed. 1674 span.next = nil 1675 span.prev = nil 1676 span.list = nil 1677 span.startAddr = base 1678 span.npages = npages 1679 span.allocCount = 0 1680 span.spanclass = 0 1681 span.elemsize = 0 1682 span.speciallock.key = 0 1683 span.specials = nil 1684 span.needzero = 0 1685 span.freeindex = 0 1686 span.freeIndexForScan = 0 1687 span.allocBits = nil 1688 span.gcmarkBits = nil 1689 span.state.set(mSpanDead) 1690 lockInit(&span.speciallock, lockRankMspanSpecial) 1691 } 1692 1693 func (span *mspan) inList() bool { 1694 return span.list != nil 1695 } 1696 1697 // Initialize an empty doubly-linked list. 1698 func (list *mSpanList) init() { 1699 list.first = nil 1700 list.last = nil 1701 } 1702 1703 func (list *mSpanList) remove(span *mspan) { 1704 if span.list != list { 1705 print("runtime: failed mSpanList.remove span.npages=", span.npages, 1706 " span=", span, " prev=", span.prev, " span.list=", span.list, " list=", list, "\n") 1707 throw("mSpanList.remove") 1708 } 1709 if list.first == span { 1710 list.first = span.next 1711 } else { 1712 span.prev.next = span.next 1713 } 1714 if list.last == span { 1715 list.last = span.prev 1716 } else { 1717 span.next.prev = span.prev 1718 } 1719 span.next = nil 1720 span.prev = nil 1721 span.list = nil 1722 } 1723 1724 func (list *mSpanList) isEmpty() bool { 1725 return list.first == nil 1726 } 1727 1728 func (list *mSpanList) insert(span *mspan) { 1729 if span.next != nil || span.prev != nil || span.list != nil { 1730 println("runtime: failed mSpanList.insert", span, span.next, span.prev, span.list) 1731 throw("mSpanList.insert") 1732 } 1733 span.next = list.first 1734 if list.first != nil { 1735 // The list contains at least one span; link it in. 1736 // The last span in the list doesn't change. 1737 list.first.prev = span 1738 } else { 1739 // The list contains no spans, so this is also the last span. 1740 list.last = span 1741 } 1742 list.first = span 1743 span.list = list 1744 } 1745 1746 func (list *mSpanList) insertBack(span *mspan) { 1747 if span.next != nil || span.prev != nil || span.list != nil { 1748 println("runtime: failed mSpanList.insertBack", span, span.next, span.prev, span.list) 1749 throw("mSpanList.insertBack") 1750 } 1751 span.prev = list.last 1752 if list.last != nil { 1753 // The list contains at least one span. 1754 list.last.next = span 1755 } else { 1756 // The list contains no spans, so this is also the first span. 1757 list.first = span 1758 } 1759 list.last = span 1760 span.list = list 1761 } 1762 1763 // takeAll removes all spans from other and inserts them at the front 1764 // of list. 1765 func (list *mSpanList) takeAll(other *mSpanList) { 1766 if other.isEmpty() { 1767 return 1768 } 1769 1770 // Reparent everything in other to list. 1771 for s := other.first; s != nil; s = s.next { 1772 s.list = list 1773 } 1774 1775 // Concatenate the lists. 1776 if list.isEmpty() { 1777 *list = *other 1778 } else { 1779 // Neither list is empty. Put other before list. 1780 other.last.next = list.first 1781 list.first.prev = other.last 1782 list.first = other.first 1783 } 1784 1785 other.first, other.last = nil, nil 1786 } 1787 1788 const ( 1789 _KindSpecialFinalizer = 1 1790 _KindSpecialProfile = 2 1791 // _KindSpecialReachable is a special used for tracking 1792 // reachability during testing. 1793 _KindSpecialReachable = 3 1794 // Note: The finalizer special must be first because if we're freeing 1795 // an object, a finalizer special will cause the freeing operation 1796 // to abort, and we want to keep the other special records around 1797 // if that happens. 1798 ) 1799 1800 type special struct { 1801 _ sys.NotInHeap 1802 next *special // linked list in span 1803 offset uint16 // span offset of object 1804 kind byte // kind of special 1805 } 1806 1807 // spanHasSpecials marks a span as having specials in the arena bitmap. 1808 func spanHasSpecials(s *mspan) { 1809 arenaPage := (s.base() / pageSize) % pagesPerArena 1810 ai := arenaIndex(s.base()) 1811 ha := mheap_.arenas[ai.l1()][ai.l2()] 1812 atomic.Or8(&ha.pageSpecials[arenaPage/8], uint8(1)<<(arenaPage%8)) 1813 } 1814 1815 // spanHasNoSpecials marks a span as having no specials in the arena bitmap. 1816 func spanHasNoSpecials(s *mspan) { 1817 arenaPage := (s.base() / pageSize) % pagesPerArena 1818 ai := arenaIndex(s.base()) 1819 ha := mheap_.arenas[ai.l1()][ai.l2()] 1820 atomic.And8(&ha.pageSpecials[arenaPage/8], ^(uint8(1) << (arenaPage % 8))) 1821 } 1822 1823 // Adds the special record s to the list of special records for 1824 // the object p. All fields of s should be filled in except for 1825 // offset & next, which this routine will fill in. 1826 // Returns true if the special was successfully added, false otherwise. 1827 // (The add will fail only if a record with the same p and s->kind 1828 // already exists.) 1829 func addspecial(p unsafe.Pointer, s *special) bool { 1830 span := spanOfHeap(uintptr(p)) 1831 if span == nil { 1832 throw("addspecial on invalid pointer") 1833 } 1834 1835 // Ensure that the span is swept. 1836 // Sweeping accesses the specials list w/o locks, so we have 1837 // to synchronize with it. And it's just much safer. 1838 mp := acquirem() 1839 span.ensureSwept() 1840 1841 offset := uintptr(p) - span.base() 1842 kind := s.kind 1843 1844 lock(&span.speciallock) 1845 1846 // Find splice point, check for existing record. 1847 t := &span.specials 1848 for { 1849 x := *t 1850 if x == nil { 1851 break 1852 } 1853 if offset == uintptr(x.offset) && kind == x.kind { 1854 unlock(&span.speciallock) 1855 releasem(mp) 1856 return false // already exists 1857 } 1858 if offset < uintptr(x.offset) || (offset == uintptr(x.offset) && kind < x.kind) { 1859 break 1860 } 1861 t = &x.next 1862 } 1863 1864 // Splice in record, fill in offset. 1865 s.offset = uint16(offset) 1866 s.next = *t 1867 *t = s 1868 spanHasSpecials(span) 1869 unlock(&span.speciallock) 1870 releasem(mp) 1871 1872 return true 1873 } 1874 1875 // Removes the Special record of the given kind for the object p. 1876 // Returns the record if the record existed, nil otherwise. 1877 // The caller must FixAlloc_Free the result. 1878 func removespecial(p unsafe.Pointer, kind uint8) *special { 1879 span := spanOfHeap(uintptr(p)) 1880 if span == nil { 1881 throw("removespecial on invalid pointer") 1882 } 1883 1884 // Ensure that the span is swept. 1885 // Sweeping accesses the specials list w/o locks, so we have 1886 // to synchronize with it. And it's just much safer. 1887 mp := acquirem() 1888 span.ensureSwept() 1889 1890 offset := uintptr(p) - span.base() 1891 1892 var result *special 1893 lock(&span.speciallock) 1894 t := &span.specials 1895 for { 1896 s := *t 1897 if s == nil { 1898 break 1899 } 1900 // This function is used for finalizers only, so we don't check for 1901 // "interior" specials (p must be exactly equal to s->offset). 1902 if offset == uintptr(s.offset) && kind == s.kind { 1903 *t = s.next 1904 result = s 1905 break 1906 } 1907 t = &s.next 1908 } 1909 if span.specials == nil { 1910 spanHasNoSpecials(span) 1911 } 1912 unlock(&span.speciallock) 1913 releasem(mp) 1914 return result 1915 } 1916 1917 // The described object has a finalizer set for it. 1918 // 1919 // specialfinalizer is allocated from non-GC'd memory, so any heap 1920 // pointers must be specially handled. 1921 type specialfinalizer struct { 1922 _ sys.NotInHeap 1923 special special 1924 fn *funcval // May be a heap pointer. 1925 nret uintptr 1926 fint *_type // May be a heap pointer, but always live. 1927 ot *ptrtype // May be a heap pointer, but always live. 1928 } 1929 1930 // Adds a finalizer to the object p. Returns true if it succeeded. 1931 func addfinalizer(p unsafe.Pointer, f *funcval, nret uintptr, fint *_type, ot *ptrtype) bool { 1932 lock(&mheap_.speciallock) 1933 s := (*specialfinalizer)(mheap_.specialfinalizeralloc.alloc()) 1934 unlock(&mheap_.speciallock) 1935 s.special.kind = _KindSpecialFinalizer 1936 s.fn = f 1937 s.nret = nret 1938 s.fint = fint 1939 s.ot = ot 1940 if addspecial(p, &s.special) { 1941 // This is responsible for maintaining the same 1942 // GC-related invariants as markrootSpans in any 1943 // situation where it's possible that markrootSpans 1944 // has already run but mark termination hasn't yet. 1945 if gcphase != _GCoff { 1946 base, span, _ := findObject(uintptr(p), 0, 0) 1947 mp := acquirem() 1948 gcw := &mp.p.ptr().gcw 1949 // Mark everything reachable from the object 1950 // so it's retained for the finalizer. 1951 if !span.spanclass.noscan() { 1952 scanobject(base, gcw) 1953 } 1954 // Mark the finalizer itself, since the 1955 // special isn't part of the GC'd heap. 1956 scanblock(uintptr(unsafe.Pointer(&s.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil) 1957 releasem(mp) 1958 } 1959 return true 1960 } 1961 1962 // There was an old finalizer 1963 lock(&mheap_.speciallock) 1964 mheap_.specialfinalizeralloc.free(unsafe.Pointer(s)) 1965 unlock(&mheap_.speciallock) 1966 return false 1967 } 1968 1969 // Removes the finalizer (if any) from the object p. 1970 func removefinalizer(p unsafe.Pointer) { 1971 s := (*specialfinalizer)(unsafe.Pointer(removespecial(p, _KindSpecialFinalizer))) 1972 if s == nil { 1973 return // there wasn't a finalizer to remove 1974 } 1975 lock(&mheap_.speciallock) 1976 mheap_.specialfinalizeralloc.free(unsafe.Pointer(s)) 1977 unlock(&mheap_.speciallock) 1978 } 1979 1980 // The described object is being heap profiled. 1981 type specialprofile struct { 1982 _ sys.NotInHeap 1983 special special 1984 b *bucket 1985 } 1986 1987 // Set the heap profile bucket associated with addr to b. 1988 func setprofilebucket(p unsafe.Pointer, b *bucket) { 1989 lock(&mheap_.speciallock) 1990 s := (*specialprofile)(mheap_.specialprofilealloc.alloc()) 1991 unlock(&mheap_.speciallock) 1992 s.special.kind = _KindSpecialProfile 1993 s.b = b 1994 if !addspecial(p, &s.special) { 1995 throw("setprofilebucket: profile already set") 1996 } 1997 } 1998 1999 // specialReachable tracks whether an object is reachable on the next 2000 // GC cycle. This is used by testing. 2001 type specialReachable struct { 2002 special special 2003 done bool 2004 reachable bool 2005 } 2006 2007 // specialsIter helps iterate over specials lists. 2008 type specialsIter struct { 2009 pprev **special 2010 s *special 2011 } 2012 2013 func newSpecialsIter(span *mspan) specialsIter { 2014 return specialsIter{&span.specials, span.specials} 2015 } 2016 2017 func (i *specialsIter) valid() bool { 2018 return i.s != nil 2019 } 2020 2021 func (i *specialsIter) next() { 2022 i.pprev = &i.s.next 2023 i.s = *i.pprev 2024 } 2025 2026 // unlinkAndNext removes the current special from the list and moves 2027 // the iterator to the next special. It returns the unlinked special. 2028 func (i *specialsIter) unlinkAndNext() *special { 2029 cur := i.s 2030 i.s = cur.next 2031 *i.pprev = i.s 2032 return cur 2033 } 2034 2035 // freeSpecial performs any cleanup on special s and deallocates it. 2036 // s must already be unlinked from the specials list. 2037 func freeSpecial(s *special, p unsafe.Pointer, size uintptr) { 2038 switch s.kind { 2039 case _KindSpecialFinalizer: 2040 sf := (*specialfinalizer)(unsafe.Pointer(s)) 2041 queuefinalizer(p, sf.fn, sf.nret, sf.fint, sf.ot) 2042 lock(&mheap_.speciallock) 2043 mheap_.specialfinalizeralloc.free(unsafe.Pointer(sf)) 2044 unlock(&mheap_.speciallock) 2045 case _KindSpecialProfile: 2046 sp := (*specialprofile)(unsafe.Pointer(s)) 2047 mProf_Free(sp.b, size) 2048 lock(&mheap_.speciallock) 2049 mheap_.specialprofilealloc.free(unsafe.Pointer(sp)) 2050 unlock(&mheap_.speciallock) 2051 case _KindSpecialReachable: 2052 sp := (*specialReachable)(unsafe.Pointer(s)) 2053 sp.done = true 2054 // The creator frees these. 2055 default: 2056 throw("bad special kind") 2057 panic("not reached") 2058 } 2059 } 2060 2061 // gcBits is an alloc/mark bitmap. This is always used as gcBits.x. 2062 type gcBits struct { 2063 _ sys.NotInHeap 2064 x uint8 2065 } 2066 2067 // bytep returns a pointer to the n'th byte of b. 2068 func (b *gcBits) bytep(n uintptr) *uint8 { 2069 return addb(&b.x, n) 2070 } 2071 2072 // bitp returns a pointer to the byte containing bit n and a mask for 2073 // selecting that bit from *bytep. 2074 func (b *gcBits) bitp(n uintptr) (bytep *uint8, mask uint8) { 2075 return b.bytep(n / 8), 1 << (n % 8) 2076 } 2077 2078 const gcBitsChunkBytes = uintptr(64 << 10) 2079 const gcBitsHeaderBytes = unsafe.Sizeof(gcBitsHeader{}) 2080 2081 type gcBitsHeader struct { 2082 free uintptr // free is the index into bits of the next free byte. 2083 next uintptr // *gcBits triggers recursive type bug. (issue 14620) 2084 } 2085 2086 type gcBitsArena struct { 2087 _ sys.NotInHeap 2088 // gcBitsHeader // side step recursive type bug (issue 14620) by including fields by hand. 2089 free uintptr // free is the index into bits of the next free byte; read/write atomically 2090 next *gcBitsArena 2091 bits [gcBitsChunkBytes - gcBitsHeaderBytes]gcBits 2092 } 2093 2094 var gcBitsArenas struct { 2095 lock mutex 2096 free *gcBitsArena 2097 next *gcBitsArena // Read atomically. Write atomically under lock. 2098 current *gcBitsArena 2099 previous *gcBitsArena 2100 } 2101 2102 // tryAlloc allocates from b or returns nil if b does not have enough room. 2103 // This is safe to call concurrently. 2104 func (b *gcBitsArena) tryAlloc(bytes uintptr) *gcBits { 2105 if b == nil || atomic.Loaduintptr(&b.free)+bytes > uintptr(len(b.bits)) { 2106 return nil 2107 } 2108 // Try to allocate from this block. 2109 end := atomic.Xadduintptr(&b.free, bytes) 2110 if end > uintptr(len(b.bits)) { 2111 return nil 2112 } 2113 // There was enough room. 2114 start := end - bytes 2115 return &b.bits[start] 2116 } 2117 2118 // newMarkBits returns a pointer to 8 byte aligned bytes 2119 // to be used for a span's mark bits. 2120 func newMarkBits(nelems uintptr) *gcBits { 2121 blocksNeeded := uintptr((nelems + 63) / 64) 2122 bytesNeeded := blocksNeeded * 8 2123 2124 // Try directly allocating from the current head arena. 2125 head := (*gcBitsArena)(atomic.Loadp(unsafe.Pointer(&gcBitsArenas.next))) 2126 if p := head.tryAlloc(bytesNeeded); p != nil { 2127 return p 2128 } 2129 2130 // There's not enough room in the head arena. We may need to 2131 // allocate a new arena. 2132 lock(&gcBitsArenas.lock) 2133 // Try the head arena again, since it may have changed. Now 2134 // that we hold the lock, the list head can't change, but its 2135 // free position still can. 2136 if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil { 2137 unlock(&gcBitsArenas.lock) 2138 return p 2139 } 2140 2141 // Allocate a new arena. This may temporarily drop the lock. 2142 fresh := newArenaMayUnlock() 2143 // If newArenaMayUnlock dropped the lock, another thread may 2144 // have put a fresh arena on the "next" list. Try allocating 2145 // from next again. 2146 if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil { 2147 // Put fresh back on the free list. 2148 // TODO: Mark it "already zeroed" 2149 fresh.next = gcBitsArenas.free 2150 gcBitsArenas.free = fresh 2151 unlock(&gcBitsArenas.lock) 2152 return p 2153 } 2154 2155 // Allocate from the fresh arena. We haven't linked it in yet, so 2156 // this cannot race and is guaranteed to succeed. 2157 p := fresh.tryAlloc(bytesNeeded) 2158 if p == nil { 2159 throw("markBits overflow") 2160 } 2161 2162 // Add the fresh arena to the "next" list. 2163 fresh.next = gcBitsArenas.next 2164 atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), unsafe.Pointer(fresh)) 2165 2166 unlock(&gcBitsArenas.lock) 2167 return p 2168 } 2169 2170 // newAllocBits returns a pointer to 8 byte aligned bytes 2171 // to be used for this span's alloc bits. 2172 // newAllocBits is used to provide newly initialized spans 2173 // allocation bits. For spans not being initialized the 2174 // mark bits are repurposed as allocation bits when 2175 // the span is swept. 2176 func newAllocBits(nelems uintptr) *gcBits { 2177 return newMarkBits(nelems) 2178 } 2179 2180 // nextMarkBitArenaEpoch establishes a new epoch for the arenas 2181 // holding the mark bits. The arenas are named relative to the 2182 // current GC cycle which is demarcated by the call to finishweep_m. 2183 // 2184 // All current spans have been swept. 2185 // During that sweep each span allocated room for its gcmarkBits in 2186 // gcBitsArenas.next block. gcBitsArenas.next becomes the gcBitsArenas.current 2187 // where the GC will mark objects and after each span is swept these bits 2188 // will be used to allocate objects. 2189 // gcBitsArenas.current becomes gcBitsArenas.previous where the span's 2190 // gcAllocBits live until all the spans have been swept during this GC cycle. 2191 // The span's sweep extinguishes all the references to gcBitsArenas.previous 2192 // by pointing gcAllocBits into the gcBitsArenas.current. 2193 // The gcBitsArenas.previous is released to the gcBitsArenas.free list. 2194 func nextMarkBitArenaEpoch() { 2195 lock(&gcBitsArenas.lock) 2196 if gcBitsArenas.previous != nil { 2197 if gcBitsArenas.free == nil { 2198 gcBitsArenas.free = gcBitsArenas.previous 2199 } else { 2200 // Find end of previous arenas. 2201 last := gcBitsArenas.previous 2202 for last = gcBitsArenas.previous; last.next != nil; last = last.next { 2203 } 2204 last.next = gcBitsArenas.free 2205 gcBitsArenas.free = gcBitsArenas.previous 2206 } 2207 } 2208 gcBitsArenas.previous = gcBitsArenas.current 2209 gcBitsArenas.current = gcBitsArenas.next 2210 atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), nil) // newMarkBits calls newArena when needed 2211 unlock(&gcBitsArenas.lock) 2212 } 2213 2214 // newArenaMayUnlock allocates and zeroes a gcBits arena. 2215 // The caller must hold gcBitsArena.lock. This may temporarily release it. 2216 func newArenaMayUnlock() *gcBitsArena { 2217 var result *gcBitsArena 2218 if gcBitsArenas.free == nil { 2219 unlock(&gcBitsArenas.lock) 2220 result = (*gcBitsArena)(sysAlloc(gcBitsChunkBytes, &memstats.gcMiscSys)) 2221 if result == nil { 2222 throw("runtime: cannot allocate memory") 2223 } 2224 lock(&gcBitsArenas.lock) 2225 } else { 2226 result = gcBitsArenas.free 2227 gcBitsArenas.free = gcBitsArenas.free.next 2228 memclrNoHeapPointers(unsafe.Pointer(result), gcBitsChunkBytes) 2229 } 2230 result.next = nil 2231 // If result.bits is not 8 byte aligned adjust index so 2232 // that &result.bits[result.free] is 8 byte aligned. 2233 if uintptr(unsafe.Offsetof(gcBitsArena{}.bits))&7 == 0 { 2234 result.free = 0 2235 } else { 2236 result.free = 8 - (uintptr(unsafe.Pointer(&result.bits[0])) & 7) 2237 } 2238 return result 2239 }