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