github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/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 "runtime/internal/atomic" 14 "runtime/internal/sys" 15 "unsafe" 16 ) 17 18 // minPhysPageSize is a lower-bound on the physical page size. The 19 // true physical page size may be larger than this. In contrast, 20 // sys.PhysPageSize is an upper-bound on the physical page size. 21 const minPhysPageSize = 4096 22 23 // Main malloc heap. 24 // The heap itself is the "free[]" and "large" arrays, 25 // but all the other global data is here too. 26 // 27 // mheap must not be heap-allocated because it contains mSpanLists, 28 // which must not be heap-allocated. 29 // 30 //go:notinheap 31 type mheap struct { 32 lock mutex 33 free mTreap // free treap of spans 34 busy mSpanList // busy list of spans 35 sweepgen uint32 // sweep generation, see comment in mspan 36 sweepdone uint32 // all spans are swept 37 sweepers uint32 // number of active sweepone calls 38 39 // allspans is a slice of all mspans ever created. Each mspan 40 // appears exactly once. 41 // 42 // The memory for allspans is manually managed and can be 43 // reallocated and move as the heap grows. 44 // 45 // In general, allspans is protected by mheap_.lock, which 46 // prevents concurrent access as well as freeing the backing 47 // store. Accesses during STW might not hold the lock, but 48 // must ensure that allocation cannot happen around the 49 // access (since that may free the backing store). 50 allspans []*mspan // all spans out there 51 52 // sweepSpans contains two mspan stacks: one of swept in-use 53 // spans, and one of unswept in-use spans. These two trade 54 // roles on each GC cycle. Since the sweepgen increases by 2 55 // on each cycle, this means the swept spans are in 56 // sweepSpans[sweepgen/2%2] and the unswept spans are in 57 // sweepSpans[1-sweepgen/2%2]. Sweeping pops spans from the 58 // unswept stack and pushes spans that are still in-use on the 59 // swept stack. Likewise, allocating an in-use span pushes it 60 // on the swept stack. 61 sweepSpans [2]gcSweepBuf 62 63 //_ uint32 // align uint64 fields on 32-bit for atomics 64 65 // Proportional sweep 66 // 67 // These parameters represent a linear function from heap_live 68 // to page sweep count. The proportional sweep system works to 69 // stay in the black by keeping the current page sweep count 70 // above this line at the current heap_live. 71 // 72 // The line has slope sweepPagesPerByte and passes through a 73 // basis point at (sweepHeapLiveBasis, pagesSweptBasis). At 74 // any given time, the system is at (memstats.heap_live, 75 // pagesSwept) in this space. 76 // 77 // It's important that the line pass through a point we 78 // control rather than simply starting at a (0,0) origin 79 // because that lets us adjust sweep pacing at any time while 80 // accounting for current progress. If we could only adjust 81 // the slope, it would create a discontinuity in debt if any 82 // progress has already been made. 83 pagesInUse uint64 // pages of spans in stats mSpanInUse; R/W with mheap.lock 84 pagesSwept uint64 // pages swept this cycle; updated atomically 85 pagesSweptBasis uint64 // pagesSwept to use as the origin of the sweep ratio; updated atomically 86 sweepHeapLiveBasis uint64 // value of heap_live to use as the origin of sweep ratio; written with lock, read without 87 sweepPagesPerByte float64 // proportional sweep ratio; written with lock, read without 88 // TODO(austin): pagesInUse should be a uintptr, but the 386 89 // compiler can't 8-byte align fields. 90 91 // Malloc stats. 92 largealloc uint64 // bytes allocated for large objects 93 nlargealloc uint64 // number of large object allocations 94 largefree uint64 // bytes freed for large objects (>maxsmallsize) 95 nlargefree uint64 // number of frees for large objects (>maxsmallsize) 96 nsmallfree [_NumSizeClasses]uint64 // number of frees for small objects (<=maxsmallsize) 97 98 // arenas is the heap arena map. It points to the metadata for 99 // the heap for every arena frame of the entire usable virtual 100 // address space. 101 // 102 // Use arenaIndex to compute indexes into this array. 103 // 104 // For regions of the address space that are not backed by the 105 // Go heap, the arena map contains nil. 106 // 107 // Modifications are protected by mheap_.lock. Reads can be 108 // performed without locking; however, a given entry can 109 // transition from nil to non-nil at any time when the lock 110 // isn't held. (Entries never transitions back to nil.) 111 // 112 // In general, this is a two-level mapping consisting of an L1 113 // map and possibly many L2 maps. This saves space when there 114 // are a huge number of arena frames. However, on many 115 // platforms (even 64-bit), arenaL1Bits is 0, making this 116 // effectively a single-level map. In this case, arenas[0] 117 // will never be nil. 118 arenas [1 << arenaL1Bits]*[1 << arenaL2Bits]*heapArena 119 120 // heapArenaAlloc is pre-reserved space for allocating heapArena 121 // objects. This is only used on 32-bit, where we pre-reserve 122 // this space to avoid interleaving it with the heap itself. 123 heapArenaAlloc linearAlloc 124 125 // arenaHints is a list of addresses at which to attempt to 126 // add more heap arenas. This is initially populated with a 127 // set of general hint addresses, and grown with the bounds of 128 // actual heap arena ranges. 129 arenaHints *arenaHint 130 131 // arena is a pre-reserved space for allocating heap arenas 132 // (the actual arenas). This is only used on 32-bit. 133 arena linearAlloc 134 135 //_ uint32 // ensure 64-bit alignment of central 136 137 // central free lists for small size classes. 138 // the padding makes sure that the MCentrals are 139 // spaced CacheLinePadSize bytes apart, so that each MCentral.lock 140 // gets its own cache line. 141 // central is indexed by spanClass. 142 central [numSpanClasses]struct { 143 mcentral mcentral 144 pad [cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize]byte 145 } 146 147 spanalloc fixalloc // allocator for span* 148 cachealloc fixalloc // allocator for mcache* 149 treapalloc fixalloc // allocator for treapNodes* used by large objects 150 specialfinalizeralloc fixalloc // allocator for specialfinalizer* 151 specialprofilealloc fixalloc // allocator for specialprofile* 152 speciallock mutex // lock for special record allocators. 153 arenaHintAlloc fixalloc // allocator for arenaHints 154 155 unused *specialfinalizer // never set, just here to force the specialfinalizer type into DWARF 156 } 157 158 var mheap_ mheap 159 160 // A heapArena stores metadata for a heap arena. heapArenas are stored 161 // outside of the Go heap and accessed via the mheap_.arenas index. 162 // 163 // This gets allocated directly from the OS, so ideally it should be a 164 // multiple of the system page size. For example, avoid adding small 165 // fields. 166 // 167 //go:notinheap 168 type heapArena struct { 169 // bitmap stores the pointer/scalar bitmap for the words in 170 // this arena. See mbitmap.go for a description. Use the 171 // heapBits type to access this. 172 bitmap [heapArenaBitmapBytes]byte 173 174 // spans maps from virtual address page ID within this arena to *mspan. 175 // For allocated spans, their pages map to the span itself. 176 // For free spans, only the lowest and highest pages map to the span itself. 177 // Internal pages map to an arbitrary span. 178 // For pages that have never been allocated, spans entries are nil. 179 // 180 // Modifications are protected by mheap.lock. Reads can be 181 // performed without locking, but ONLY from indexes that are 182 // known to contain in-use or stack spans. This means there 183 // must not be a safe-point between establishing that an 184 // address is live and looking it up in the spans array. 185 spans [pagesPerArena]*mspan 186 } 187 188 // arenaHint is a hint for where to grow the heap arenas. See 189 // mheap_.arenaHints. 190 // 191 //go:notinheap 192 type arenaHint struct { 193 addr uintptr 194 down bool 195 next *arenaHint 196 } 197 198 // An MSpan is a run of pages. 199 // 200 // When a MSpan is in the heap free list, state == mSpanFree 201 // and heapmap(s->start) == span, heapmap(s->start+s->npages-1) == span. 202 // 203 // When a MSpan is allocated, state == mSpanInUse or mSpanManual 204 // and heapmap(i) == span for all s->start <= i < s->start+s->npages. 205 206 // Every MSpan is in one doubly-linked list, 207 // either one of the MHeap's free lists or one of the 208 // MCentral's span lists. 209 210 // An MSpan representing actual memory has state mSpanInUse, 211 // mSpanManual, or mSpanFree. Transitions between these states are 212 // constrained as follows: 213 // 214 // * A span may transition from free to in-use or manual during any GC 215 // phase. 216 // 217 // * During sweeping (gcphase == _GCoff), a span may transition from 218 // in-use to free (as a result of sweeping) or manual to free (as a 219 // result of stacks being freed). 220 // 221 // * During GC (gcphase != _GCoff), a span *must not* transition from 222 // manual or in-use to free. Because concurrent GC may read a pointer 223 // and then look up its span, the span state must be monotonic. 224 type mSpanState uint8 225 226 const ( 227 mSpanDead mSpanState = iota 228 mSpanInUse // allocated for garbage collected heap 229 mSpanManual // allocated for manual management (e.g., stack allocator) 230 mSpanFree 231 ) 232 233 // mSpanStateNames are the names of the span states, indexed by 234 // mSpanState. 235 var mSpanStateNames = []string{ 236 "mSpanDead", 237 "mSpanInUse", 238 "mSpanManual", 239 "mSpanFree", 240 } 241 242 // mSpanList heads a linked list of spans. 243 // 244 //go:notinheap 245 type mSpanList struct { 246 first *mspan // first span in list, or nil if none 247 last *mspan // last span in list, or nil if none 248 } 249 250 //go:notinheap 251 type mspan struct { 252 next *mspan // next span in list, or nil if none 253 prev *mspan // previous span in list, or nil if none 254 list *mSpanList // For debugging. TODO: Remove. 255 256 startAddr uintptr // address of first byte of span aka s.base() 257 npages uintptr // number of pages in span 258 259 manualFreeList gclinkptr // list of free objects in mSpanManual spans 260 261 // freeindex is the slot index between 0 and nelems at which to begin scanning 262 // for the next free object in this span. 263 // Each allocation scans allocBits starting at freeindex until it encounters a 0 264 // indicating a free object. freeindex is then adjusted so that subsequent scans begin 265 // just past the newly discovered free object. 266 // 267 // If freeindex == nelem, this span has no free objects. 268 // 269 // allocBits is a bitmap of objects in this span. 270 // If n >= freeindex and allocBits[n/8] & (1<<(n%8)) is 0 271 // then object n is free; 272 // otherwise, object n is allocated. Bits starting at nelem are 273 // undefined and should never be referenced. 274 // 275 // Object n starts at address n*elemsize + (start << pageShift). 276 freeindex uintptr 277 // TODO: Look up nelems from sizeclass and remove this field if it 278 // helps performance. 279 nelems uintptr // number of object in the span. 280 281 // Cache of the allocBits at freeindex. allocCache is shifted 282 // such that the lowest bit corresponds to the bit freeindex. 283 // allocCache holds the complement of allocBits, thus allowing 284 // ctz (count trailing zero) to use it directly. 285 // allocCache may contain bits beyond s.nelems; the caller must ignore 286 // these. 287 allocCache uint64 288 289 // allocBits and gcmarkBits hold pointers to a span's mark and 290 // allocation bits. The pointers are 8 byte aligned. 291 // There are three arenas where this data is held. 292 // free: Dirty arenas that are no longer accessed 293 // and can be reused. 294 // next: Holds information to be used in the next GC cycle. 295 // current: Information being used during this GC cycle. 296 // previous: Information being used during the last GC cycle. 297 // A new GC cycle starts with the call to finishsweep_m. 298 // finishsweep_m moves the previous arena to the free arena, 299 // the current arena to the previous arena, and 300 // the next arena to the current arena. 301 // The next arena is populated as the spans request 302 // memory to hold gcmarkBits for the next GC cycle as well 303 // as allocBits for newly allocated spans. 304 // 305 // The pointer arithmetic is done "by hand" instead of using 306 // arrays to avoid bounds checks along critical performance 307 // paths. 308 // The sweep will free the old allocBits and set allocBits to the 309 // gcmarkBits. The gcmarkBits are replaced with a fresh zeroed 310 // out memory. 311 allocBits *gcBits 312 gcmarkBits *gcBits 313 314 // sweep generation: 315 // if sweepgen == h->sweepgen - 2, the span needs sweeping 316 // if sweepgen == h->sweepgen - 1, the span is currently being swept 317 // if sweepgen == h->sweepgen, the span is swept and ready to use 318 // if sweepgen == h->sweepgen + 1, the span was cached before sweep began and is still cached, and needs sweeping 319 // if sweepgen == h->sweepgen + 3, the span was swept and then cached and is still cached 320 // h->sweepgen is incremented by 2 after every GC 321 322 sweepgen uint32 323 divMul uint16 // for divide by elemsize - divMagic.mul 324 baseMask uint16 // if non-0, elemsize is a power of 2, & this will get object allocation base 325 allocCount uint16 // number of allocated objects 326 spanclass spanClass // size class and noscan (uint8) 327 state mSpanState // mspaninuse etc 328 needzero uint8 // needs to be zeroed before allocation 329 divShift uint8 // for divide by elemsize - divMagic.shift 330 divShift2 uint8 // for divide by elemsize - divMagic.shift2 331 elemsize uintptr // computed from sizeclass or from npages 332 unusedsince int64 // first time spotted by gc in mspanfree state 333 npreleased uintptr // number of pages released to the os 334 limit uintptr // end of data in span 335 speciallock mutex // guards specials list 336 specials *special // linked list of special records sorted by offset. 337 } 338 339 func (s *mspan) base() uintptr { 340 return s.startAddr 341 } 342 343 func (s *mspan) layout() (size, n, total uintptr) { 344 total = s.npages << _PageShift 345 size = s.elemsize 346 if size > 0 { 347 n = total / size 348 } 349 return 350 } 351 352 func (s *mspan) scavenge() uintptr { 353 start := s.base() 354 end := start + s.npages<<_PageShift 355 if physPageSize > _PageSize { 356 // We can only release pages in 357 // physPageSize blocks, so round start 358 // and end in. (Otherwise, madvise 359 // will round them *out* and release 360 // more memory than we want.) 361 start = (start + physPageSize - 1) &^ (physPageSize - 1) 362 end &^= physPageSize - 1 363 if end <= start { 364 // start and end don't span a 365 // whole physical page. 366 return 0 367 } 368 } 369 len := end - start 370 released := len - (s.npreleased << _PageShift) 371 if physPageSize > _PageSize && released == 0 { 372 return 0 373 } 374 memstats.heap_released += uint64(released) 375 s.npreleased = len >> _PageShift 376 sysUnused(unsafe.Pointer(start), len) 377 return released 378 } 379 380 // recordspan adds a newly allocated span to h.allspans. 381 // 382 // This only happens the first time a span is allocated from 383 // mheap.spanalloc (it is not called when a span is reused). 384 // 385 // Write barriers are disallowed here because it can be called from 386 // gcWork when allocating new workbufs. However, because it's an 387 // indirect call from the fixalloc initializer, the compiler can't see 388 // this. 389 // 390 //go:nowritebarrierrec 391 func recordspan(vh unsafe.Pointer, p unsafe.Pointer) { 392 h := (*mheap)(vh) 393 s := (*mspan)(p) 394 if len(h.allspans) >= cap(h.allspans) { 395 n := 64 * 1024 / sys.PtrSize 396 if n < cap(h.allspans)*3/2 { 397 n = cap(h.allspans) * 3 / 2 398 } 399 var new []*mspan 400 sp := (*slice)(unsafe.Pointer(&new)) 401 sp.array = sysAlloc(uintptr(n)*sys.PtrSize, &memstats.other_sys) 402 if sp.array == nil { 403 throw("runtime: cannot allocate memory") 404 } 405 sp.len = len(h.allspans) 406 sp.cap = n 407 if len(h.allspans) > 0 { 408 copy(new, h.allspans) 409 } 410 oldAllspans := h.allspans 411 *(*notInHeapSlice)(unsafe.Pointer(&h.allspans)) = *(*notInHeapSlice)(unsafe.Pointer(&new)) 412 if len(oldAllspans) != 0 { 413 sysFree(unsafe.Pointer(&oldAllspans[0]), uintptr(cap(oldAllspans))*unsafe.Sizeof(oldAllspans[0]), &memstats.other_sys) 414 } 415 } 416 h.allspans = h.allspans[:len(h.allspans)+1] 417 h.allspans[len(h.allspans)-1] = s 418 } 419 420 // A spanClass represents the size class and noscan-ness of a span. 421 // 422 // Each size class has a noscan spanClass and a scan spanClass. The 423 // noscan spanClass contains only noscan objects, which do not contain 424 // pointers and thus do not need to be scanned by the garbage 425 // collector. 426 type spanClass uint8 427 428 const ( 429 numSpanClasses = _NumSizeClasses << 1 430 tinySpanClass = spanClass(tinySizeClass<<1 | 1) 431 ) 432 433 func makeSpanClass(sizeclass uint8, noscan bool) spanClass { 434 return spanClass(sizeclass<<1) | spanClass(bool2int(noscan)) 435 } 436 437 func (sc spanClass) sizeclass() int8 { 438 return int8(sc >> 1) 439 } 440 441 func (sc spanClass) noscan() bool { 442 return sc&1 != 0 443 } 444 445 // arenaIndex returns the index into mheap_.arenas of the arena 446 // containing metadata for p. This index combines of an index into the 447 // L1 map and an index into the L2 map and should be used as 448 // mheap_.arenas[ai.l1()][ai.l2()]. 449 // 450 // If p is outside the range of valid heap addresses, either l1() or 451 // l2() will be out of bounds. 452 // 453 // It is nosplit because it's called by spanOf and several other 454 // nosplit functions. 455 // 456 //go:nosplit 457 func arenaIndex(p uintptr) arenaIdx { 458 return arenaIdx((p + arenaBaseOffset) / heapArenaBytes) 459 } 460 461 // arenaBase returns the low address of the region covered by heap 462 // arena i. 463 func arenaBase(i arenaIdx) uintptr { 464 return uintptr(i)*heapArenaBytes - arenaBaseOffset 465 } 466 467 type arenaIdx uint 468 469 func (i arenaIdx) l1() uint { 470 if arenaL1Bits == 0 { 471 // Let the compiler optimize this away if there's no 472 // L1 map. 473 return 0 474 } else { 475 return uint(i) >> arenaL1Shift 476 } 477 } 478 479 func (i arenaIdx) l2() uint { 480 if arenaL1Bits == 0 { 481 return uint(i) 482 } else { 483 return uint(i) & (1<<arenaL2Bits - 1) 484 } 485 } 486 487 // inheap reports whether b is a pointer into a (potentially dead) heap object. 488 // It returns false for pointers into mSpanManual spans. 489 // Non-preemptible because it is used by write barriers. 490 //go:nowritebarrier 491 //go:nosplit 492 func inheap(b uintptr) bool { 493 return spanOfHeap(b) != nil 494 } 495 496 // inHeapOrStack is a variant of inheap that returns true for pointers 497 // into any allocated heap span. 498 // 499 //go:nowritebarrier 500 //go:nosplit 501 func inHeapOrStack(b uintptr) bool { 502 s := spanOf(b) 503 if s == nil || b < s.base() { 504 return false 505 } 506 switch s.state { 507 case mSpanInUse, mSpanManual: 508 return b < s.limit 509 default: 510 return false 511 } 512 } 513 514 // spanOf returns the span of p. If p does not point into the heap 515 // arena or no span has ever contained p, spanOf returns nil. 516 // 517 // If p does not point to allocated memory, this may return a non-nil 518 // span that does *not* contain p. If this is a possibility, the 519 // caller should either call spanOfHeap or check the span bounds 520 // explicitly. 521 // 522 // Must be nosplit because it has callers that are nosplit. 523 // 524 //go:nosplit 525 func spanOf(p uintptr) *mspan { 526 // This function looks big, but we use a lot of constant 527 // folding around arenaL1Bits to get it under the inlining 528 // budget. Also, many of the checks here are safety checks 529 // that Go needs to do anyway, so the generated code is quite 530 // short. 531 ri := arenaIndex(p) 532 if arenaL1Bits == 0 { 533 // If there's no L1, then ri.l1() can't be out of bounds but ri.l2() can. 534 if ri.l2() >= uint(len(mheap_.arenas[0])) { 535 return nil 536 } 537 } else { 538 // If there's an L1, then ri.l1() can be out of bounds but ri.l2() can't. 539 if ri.l1() >= uint(len(mheap_.arenas)) { 540 return nil 541 } 542 } 543 l2 := mheap_.arenas[ri.l1()] 544 if arenaL1Bits != 0 && l2 == nil { // Should never happen if there's no L1. 545 return nil 546 } 547 ha := l2[ri.l2()] 548 if ha == nil { 549 return nil 550 } 551 return ha.spans[(p/pageSize)%pagesPerArena] 552 } 553 554 // spanOfUnchecked is equivalent to spanOf, but the caller must ensure 555 // that p points into an allocated heap arena. 556 // 557 // Must be nosplit because it has callers that are nosplit. 558 // 559 //go:nosplit 560 func spanOfUnchecked(p uintptr) *mspan { 561 ai := arenaIndex(p) 562 return mheap_.arenas[ai.l1()][ai.l2()].spans[(p/pageSize)%pagesPerArena] 563 } 564 565 // spanOfHeap is like spanOf, but returns nil if p does not point to a 566 // heap object. 567 // 568 // Must be nosplit because it has callers that are nosplit. 569 // 570 //go:nosplit 571 func spanOfHeap(p uintptr) *mspan { 572 s := spanOf(p) 573 // If p is not allocated, it may point to a stale span, so we 574 // have to check the span's bounds and state. 575 if s == nil || p < s.base() || p >= s.limit || s.state != mSpanInUse { 576 return nil 577 } 578 return s 579 } 580 581 // Initialize the heap. 582 func (h *mheap) init() { 583 h.treapalloc.init(unsafe.Sizeof(treapNode{}), nil, nil, &memstats.other_sys) 584 h.spanalloc.init(unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &memstats.mspan_sys) 585 h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys) 586 h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys) 587 h.specialprofilealloc.init(unsafe.Sizeof(specialprofile{}), nil, nil, &memstats.other_sys) 588 h.arenaHintAlloc.init(unsafe.Sizeof(arenaHint{}), nil, nil, &memstats.other_sys) 589 590 // Don't zero mspan allocations. Background sweeping can 591 // inspect a span concurrently with allocating it, so it's 592 // important that the span's sweepgen survive across freeing 593 // and re-allocating a span to prevent background sweeping 594 // from improperly cas'ing it from 0. 595 // 596 // This is safe because mspan contains no heap pointers. 597 h.spanalloc.zero = false 598 599 // h->mapcache needs no init 600 h.busy.init() 601 for i := range h.central { 602 h.central[i].mcentral.init(spanClass(i)) 603 } 604 } 605 606 // Sweeps spans in list until reclaims at least npages into heap. 607 // Returns the actual number of pages reclaimed. 608 func (h *mheap) reclaimList(list *mSpanList, npages uintptr) uintptr { 609 n := uintptr(0) 610 sg := mheap_.sweepgen 611 retry: 612 for s := list.first; s != nil; s = s.next { 613 if s.sweepgen == sg-2 && atomic.Cas(&s.sweepgen, sg-2, sg-1) { 614 list.remove(s) 615 // swept spans are at the end of the list 616 list.insertBack(s) // Puts it back on a busy list. s is not in the treap at this point. 617 unlock(&h.lock) 618 snpages := s.npages 619 if s.sweep(false) { 620 n += snpages 621 } 622 lock(&h.lock) 623 if n >= npages { 624 return n 625 } 626 // the span could have been moved elsewhere 627 goto retry 628 } 629 if s.sweepgen == sg-1 { 630 // the span is being swept by background sweeper, skip 631 continue 632 } 633 // already swept empty span, 634 // all subsequent ones must also be either swept or in process of sweeping 635 break 636 } 637 return n 638 } 639 640 // Sweeps and reclaims at least npage pages into heap. 641 // Called before allocating npage pages. 642 func (h *mheap) reclaim(npage uintptr) { 643 if h.reclaimList(&h.busy, npage) != 0 { 644 return // Bingo! 645 } 646 647 // Now sweep everything that is not yet swept. 648 var reclaimed uintptr 649 unlock(&h.lock) 650 for { 651 n := sweepone() 652 if n == ^uintptr(0) { // all spans are swept 653 break 654 } 655 reclaimed += n 656 if reclaimed >= npage { 657 break 658 } 659 } 660 lock(&h.lock) 661 } 662 663 // alloc_m is the internal implementation of mheap.alloc. 664 // 665 // alloc_m must run on the system stack because it locks the heap, so 666 // any stack growth during alloc_m would self-deadlock. 667 // 668 //go:systemstack 669 func (h *mheap) alloc_m(npage uintptr, spanclass spanClass, large bool) *mspan { 670 _g_ := getg() 671 lock(&h.lock) 672 673 // To prevent excessive heap growth, before allocating n pages 674 // we need to sweep and reclaim at least n pages. 675 if h.sweepdone == 0 { 676 // TODO(austin): This tends to sweep a large number of 677 // spans in order to find a few completely free spans 678 // (for example, in the garbage benchmark, this sweeps 679 // ~30x the number of pages it's trying to allocate). 680 // If GC kept a bit for whether there were any marks 681 // in a span, we could release these free spans 682 // at the end of GC and eliminate this entirely. 683 if trace.enabled { 684 traceGCSweepStart() 685 } 686 h.reclaim(npage) 687 if trace.enabled { 688 traceGCSweepDone() 689 } 690 } 691 692 // transfer stats from cache to global 693 memstats.heap_scan += uint64(_g_.m.mcache.local_scan) 694 _g_.m.mcache.local_scan = 0 695 memstats.tinyallocs += uint64(_g_.m.mcache.local_tinyallocs) 696 _g_.m.mcache.local_tinyallocs = 0 697 698 s := h.allocSpanLocked(npage, &memstats.heap_inuse) 699 if s != nil { 700 // Record span info, because gc needs to be 701 // able to map interior pointer to containing span. 702 atomic.Store(&s.sweepgen, h.sweepgen) 703 h.sweepSpans[h.sweepgen/2%2].push(s) // Add to swept in-use list. 704 s.state = mSpanInUse 705 s.allocCount = 0 706 s.spanclass = spanclass 707 if sizeclass := spanclass.sizeclass(); sizeclass == 0 { 708 s.elemsize = s.npages << _PageShift 709 s.divShift = 0 710 s.divMul = 0 711 s.divShift2 = 0 712 s.baseMask = 0 713 } else { 714 s.elemsize = uintptr(class_to_size[sizeclass]) 715 m := &class_to_divmagic[sizeclass] 716 s.divShift = m.shift 717 s.divMul = m.mul 718 s.divShift2 = m.shift2 719 s.baseMask = m.baseMask 720 } 721 722 // update stats, sweep lists 723 h.pagesInUse += uint64(npage) 724 if large { 725 memstats.heap_objects++ 726 mheap_.largealloc += uint64(s.elemsize) 727 mheap_.nlargealloc++ 728 atomic.Xadd64(&memstats.heap_live, int64(npage<<_PageShift)) 729 // Swept spans are at the end of lists. 730 h.busy.insertBack(s) 731 } 732 } 733 // heap_scan and heap_live were updated. 734 if gcBlackenEnabled != 0 { 735 gcController.revise() 736 } 737 738 if trace.enabled { 739 traceHeapAlloc() 740 } 741 742 // h.spans is accessed concurrently without synchronization 743 // from other threads. Hence, there must be a store/store 744 // barrier here to ensure the writes to h.spans above happen 745 // before the caller can publish a pointer p to an object 746 // allocated from s. As soon as this happens, the garbage 747 // collector running on another processor could read p and 748 // look up s in h.spans. The unlock acts as the barrier to 749 // order these writes. On the read side, the data dependency 750 // between p and the index in h.spans orders the reads. 751 unlock(&h.lock) 752 return s 753 } 754 755 // alloc allocates a new span of npage pages from the GC'd heap. 756 // 757 // Either large must be true or spanclass must indicates the span's 758 // size class and scannability. 759 // 760 // If needzero is true, the memory for the returned span will be zeroed. 761 func (h *mheap) alloc(npage uintptr, spanclass spanClass, large bool, needzero bool) *mspan { 762 // Don't do any operations that lock the heap on the G stack. 763 // It might trigger stack growth, and the stack growth code needs 764 // to be able to allocate heap. 765 var s *mspan 766 systemstack(func() { 767 s = h.alloc_m(npage, spanclass, large) 768 }) 769 770 if s != nil { 771 if needzero && s.needzero != 0 { 772 memclrNoHeapPointers(unsafe.Pointer(s.base()), s.npages<<_PageShift) 773 } 774 s.needzero = 0 775 } 776 return s 777 } 778 779 // allocManual allocates a manually-managed span of npage pages. 780 // allocManual returns nil if allocation fails. 781 // 782 // allocManual adds the bytes used to *stat, which should be a 783 // memstats in-use field. Unlike allocations in the GC'd heap, the 784 // allocation does *not* count toward heap_inuse or heap_sys. 785 // 786 // The memory backing the returned span may not be zeroed if 787 // span.needzero is set. 788 // 789 // allocManual must be called on the system stack to prevent stack 790 // growth. Since this is used by the stack allocator, stack growth 791 // during allocManual would self-deadlock. 792 // 793 //go:systemstack 794 func (h *mheap) allocManual(npage uintptr, stat *uint64) *mspan { 795 lock(&h.lock) 796 s := h.allocSpanLocked(npage, stat) 797 if s != nil { 798 s.state = mSpanManual 799 s.manualFreeList = 0 800 s.allocCount = 0 801 s.spanclass = 0 802 s.nelems = 0 803 s.elemsize = 0 804 s.limit = s.base() + s.npages<<_PageShift 805 // Manually managed memory doesn't count toward heap_sys. 806 memstats.heap_sys -= uint64(s.npages << _PageShift) 807 } 808 809 // This unlock acts as a release barrier. See mheap.alloc_m. 810 unlock(&h.lock) 811 812 return s 813 } 814 815 // setSpan modifies the span map so spanOf(base) is s. 816 func (h *mheap) setSpan(base uintptr, s *mspan) { 817 ai := arenaIndex(base) 818 h.arenas[ai.l1()][ai.l2()].spans[(base/pageSize)%pagesPerArena] = s 819 } 820 821 // setSpans modifies the span map so [spanOf(base), spanOf(base+npage*pageSize)) 822 // is s. 823 func (h *mheap) setSpans(base, npage uintptr, s *mspan) { 824 p := base / pageSize 825 ai := arenaIndex(base) 826 ha := h.arenas[ai.l1()][ai.l2()] 827 for n := uintptr(0); n < npage; n++ { 828 i := (p + n) % pagesPerArena 829 if i == 0 { 830 ai = arenaIndex(base + n*pageSize) 831 ha = h.arenas[ai.l1()][ai.l2()] 832 } 833 ha.spans[i] = s 834 } 835 } 836 837 // Allocates a span of the given size. h must be locked. 838 // The returned span has been removed from the 839 // free list, but its state is still mSpanFree. 840 func (h *mheap) allocSpanLocked(npage uintptr, stat *uint64) *mspan { 841 var s *mspan 842 843 // Best fit in the treap of spans. 844 s = h.free.remove(npage) 845 if s == nil { 846 if !h.grow(npage) { 847 return nil 848 } 849 s = h.free.remove(npage) 850 if s == nil { 851 return nil 852 } 853 } 854 855 // Mark span in use. 856 if s.state != mSpanFree { 857 throw("MHeap_AllocLocked - MSpan not free") 858 } 859 if s.npages < npage { 860 throw("MHeap_AllocLocked - bad npages") 861 } 862 if s.npreleased > 0 { 863 sysUsed(unsafe.Pointer(s.base()), s.npages<<_PageShift) 864 memstats.heap_released -= uint64(s.npreleased << _PageShift) 865 s.npreleased = 0 866 } 867 868 if s.npages > npage { 869 // Trim extra and put it back in the heap. 870 t := (*mspan)(h.spanalloc.alloc()) 871 t.init(s.base()+npage<<_PageShift, s.npages-npage) 872 s.npages = npage 873 h.setSpan(t.base()-1, s) 874 h.setSpan(t.base(), t) 875 h.setSpan(t.base()+t.npages*pageSize-1, t) 876 t.needzero = s.needzero 877 s.state = mSpanManual // prevent coalescing with s 878 t.state = mSpanManual 879 h.freeSpanLocked(t, false, false, s.unusedsince) 880 s.state = mSpanFree 881 } 882 s.unusedsince = 0 883 884 h.setSpans(s.base(), npage, s) 885 886 *stat += uint64(npage << _PageShift) 887 memstats.heap_idle -= uint64(npage << _PageShift) 888 889 //println("spanalloc", hex(s.start<<_PageShift)) 890 if s.inList() { 891 throw("still in list") 892 } 893 return s 894 } 895 896 // Try to add at least npage pages of memory to the heap, 897 // returning whether it worked. 898 // 899 // h must be locked. 900 func (h *mheap) grow(npage uintptr) bool { 901 ask := npage << _PageShift 902 v, size := h.sysAlloc(ask) 903 if v == nil { 904 print("runtime: out of memory: cannot allocate ", ask, "-byte block (", memstats.heap_sys, " in use)\n") 905 return false 906 } 907 908 // Create a fake "in use" span and free it, so that the 909 // right coalescing happens. 910 s := (*mspan)(h.spanalloc.alloc()) 911 s.init(uintptr(v), size/pageSize) 912 h.setSpans(s.base(), s.npages, s) 913 atomic.Store(&s.sweepgen, h.sweepgen) 914 s.state = mSpanInUse 915 h.pagesInUse += uint64(s.npages) 916 h.freeSpanLocked(s, false, true, 0) 917 return true 918 } 919 920 // Free the span back into the heap. 921 // 922 // large must match the value of large passed to mheap.alloc. This is 923 // used for accounting. 924 func (h *mheap) freeSpan(s *mspan, large bool) { 925 systemstack(func() { 926 mp := getg().m 927 lock(&h.lock) 928 memstats.heap_scan += uint64(mp.mcache.local_scan) 929 mp.mcache.local_scan = 0 930 memstats.tinyallocs += uint64(mp.mcache.local_tinyallocs) 931 mp.mcache.local_tinyallocs = 0 932 if msanenabled { 933 // Tell msan that this entire span is no longer in use. 934 base := unsafe.Pointer(s.base()) 935 bytes := s.npages << _PageShift 936 msanfree(base, bytes) 937 } 938 if large { 939 // Match accounting done in mheap.alloc. 940 memstats.heap_objects-- 941 } 942 if gcBlackenEnabled != 0 { 943 // heap_scan changed. 944 gcController.revise() 945 } 946 h.freeSpanLocked(s, true, true, 0) 947 unlock(&h.lock) 948 }) 949 } 950 951 // freeManual frees a manually-managed span returned by allocManual. 952 // stat must be the same as the stat passed to the allocManual that 953 // allocated s. 954 // 955 // This must only be called when gcphase == _GCoff. See mSpanState for 956 // an explanation. 957 // 958 // freeManual must be called on the system stack to prevent stack 959 // growth, just like allocManual. 960 // 961 //go:systemstack 962 func (h *mheap) freeManual(s *mspan, stat *uint64) { 963 s.needzero = 1 964 lock(&h.lock) 965 *stat -= uint64(s.npages << _PageShift) 966 memstats.heap_sys += uint64(s.npages << _PageShift) 967 h.freeSpanLocked(s, false, true, 0) 968 unlock(&h.lock) 969 } 970 971 // s must be on the busy list or unlinked. 972 func (h *mheap) freeSpanLocked(s *mspan, acctinuse, acctidle bool, unusedsince int64) { 973 switch s.state { 974 case mSpanManual: 975 if s.allocCount != 0 { 976 throw("MHeap_FreeSpanLocked - invalid stack free") 977 } 978 case mSpanInUse: 979 if s.allocCount != 0 || s.sweepgen != h.sweepgen { 980 print("MHeap_FreeSpanLocked - span ", s, " ptr ", hex(s.base()), " allocCount ", s.allocCount, " sweepgen ", s.sweepgen, "/", h.sweepgen, "\n") 981 throw("MHeap_FreeSpanLocked - invalid free") 982 } 983 h.pagesInUse -= uint64(s.npages) 984 default: 985 throw("MHeap_FreeSpanLocked - invalid span state") 986 } 987 988 if acctinuse { 989 memstats.heap_inuse -= uint64(s.npages << _PageShift) 990 } 991 if acctidle { 992 memstats.heap_idle += uint64(s.npages << _PageShift) 993 } 994 s.state = mSpanFree 995 if s.inList() { 996 h.busy.remove(s) 997 } 998 999 // Stamp newly unused spans. The scavenger will use that 1000 // info to potentially give back some pages to the OS. 1001 s.unusedsince = unusedsince 1002 if unusedsince == 0 { 1003 s.unusedsince = nanotime() 1004 } 1005 s.npreleased = 0 1006 1007 // Coalesce with earlier, later spans. 1008 if before := spanOf(s.base() - 1); before != nil && before.state == mSpanFree { 1009 // Now adjust s. 1010 s.startAddr = before.startAddr 1011 s.npages += before.npages 1012 s.npreleased = before.npreleased // absorb released pages 1013 s.needzero |= before.needzero 1014 h.setSpan(before.base(), s) 1015 // The size is potentially changing so the treap needs to delete adjacent nodes and 1016 // insert back as a combined node. 1017 h.free.removeSpan(before) 1018 before.state = mSpanDead 1019 h.spanalloc.free(unsafe.Pointer(before)) 1020 } 1021 1022 // Now check to see if next (greater addresses) span is free and can be coalesced. 1023 if after := spanOf(s.base() + s.npages*pageSize); after != nil && after.state == mSpanFree { 1024 s.npages += after.npages 1025 s.npreleased += after.npreleased 1026 s.needzero |= after.needzero 1027 h.setSpan(s.base()+s.npages*pageSize-1, s) 1028 h.free.removeSpan(after) 1029 after.state = mSpanDead 1030 h.spanalloc.free(unsafe.Pointer(after)) 1031 } 1032 1033 // Insert s into the free treap. 1034 h.free.insert(s) 1035 } 1036 1037 func scavengeTreapNode(t *treapNode, now, limit uint64) uintptr { 1038 s := t.spanKey 1039 if (now-uint64(s.unusedsince)) > limit && s.npreleased != s.npages { 1040 if released := s.scavenge(); released != 0 { 1041 return released 1042 } 1043 } 1044 return 0 1045 } 1046 1047 func (h *mheap) scavenge(k int32, now, limit uint64) { 1048 // Disallow malloc or panic while holding the heap lock. We do 1049 // this here because this is an non-mallocgc entry-point to 1050 // the mheap API. 1051 gp := getg() 1052 gp.m.mallocing++ 1053 lock(&h.lock) 1054 sumreleased := scavengetreap(h.free.treap, now, limit) 1055 unlock(&h.lock) 1056 gp.m.mallocing-- 1057 1058 if debug.gctrace > 0 { 1059 if sumreleased > 0 { 1060 print("scvg", k, ": ", sumreleased>>20, " MB released\n") 1061 } 1062 print("scvg", k, ": inuse: ", memstats.heap_inuse>>20, ", idle: ", memstats.heap_idle>>20, ", sys: ", memstats.heap_sys>>20, ", released: ", memstats.heap_released>>20, ", consumed: ", (memstats.heap_sys-memstats.heap_released)>>20, " (MB)\n") 1063 } 1064 } 1065 1066 //go:linkname runtime_debug_freeOSMemory runtime/debug.freeOSMemory 1067 func runtime_debug_freeOSMemory() { 1068 GC() 1069 systemstack(func() { mheap_.scavenge(-1, ^uint64(0), 0) }) 1070 } 1071 1072 // Initialize a new span with the given start and npages. 1073 func (span *mspan) init(base uintptr, npages uintptr) { 1074 // span is *not* zeroed. 1075 span.next = nil 1076 span.prev = nil 1077 span.list = nil 1078 span.startAddr = base 1079 span.npages = npages 1080 span.allocCount = 0 1081 span.spanclass = 0 1082 span.elemsize = 0 1083 span.state = mSpanDead 1084 span.unusedsince = 0 1085 span.npreleased = 0 1086 span.speciallock.key = 0 1087 span.specials = nil 1088 span.needzero = 0 1089 span.freeindex = 0 1090 span.allocBits = nil 1091 span.gcmarkBits = nil 1092 } 1093 1094 func (span *mspan) inList() bool { 1095 return span.list != nil 1096 } 1097 1098 // Initialize an empty doubly-linked list. 1099 func (list *mSpanList) init() { 1100 list.first = nil 1101 list.last = nil 1102 } 1103 1104 func (list *mSpanList) remove(span *mspan) { 1105 if span.list != list { 1106 print("runtime: failed MSpanList_Remove span.npages=", span.npages, 1107 " span=", span, " prev=", span.prev, " span.list=", span.list, " list=", list, "\n") 1108 throw("MSpanList_Remove") 1109 } 1110 if list.first == span { 1111 list.first = span.next 1112 } else { 1113 span.prev.next = span.next 1114 } 1115 if list.last == span { 1116 list.last = span.prev 1117 } else { 1118 span.next.prev = span.prev 1119 } 1120 span.next = nil 1121 span.prev = nil 1122 span.list = nil 1123 } 1124 1125 func (list *mSpanList) isEmpty() bool { 1126 return list.first == nil 1127 } 1128 1129 func (list *mSpanList) insert(span *mspan) { 1130 if span.next != nil || span.prev != nil || span.list != nil { 1131 println("runtime: failed MSpanList_Insert", span, span.next, span.prev, span.list) 1132 throw("MSpanList_Insert") 1133 } 1134 span.next = list.first 1135 if list.first != nil { 1136 // The list contains at least one span; link it in. 1137 // The last span in the list doesn't change. 1138 list.first.prev = span 1139 } else { 1140 // The list contains no spans, so this is also the last span. 1141 list.last = span 1142 } 1143 list.first = span 1144 span.list = list 1145 } 1146 1147 func (list *mSpanList) insertBack(span *mspan) { 1148 if span.next != nil || span.prev != nil || span.list != nil { 1149 println("runtime: failed MSpanList_InsertBack", span, span.next, span.prev, span.list) 1150 throw("MSpanList_InsertBack") 1151 } 1152 span.prev = list.last 1153 if list.last != nil { 1154 // The list contains at least one span. 1155 list.last.next = span 1156 } else { 1157 // The list contains no spans, so this is also the first span. 1158 list.first = span 1159 } 1160 list.last = span 1161 span.list = list 1162 } 1163 1164 // takeAll removes all spans from other and inserts them at the front 1165 // of list. 1166 func (list *mSpanList) takeAll(other *mSpanList) { 1167 if other.isEmpty() { 1168 return 1169 } 1170 1171 // Reparent everything in other to list. 1172 for s := other.first; s != nil; s = s.next { 1173 s.list = list 1174 } 1175 1176 // Concatenate the lists. 1177 if list.isEmpty() { 1178 *list = *other 1179 } else { 1180 // Neither list is empty. Put other before list. 1181 other.last.next = list.first 1182 list.first.prev = other.last 1183 list.first = other.first 1184 } 1185 1186 other.first, other.last = nil, nil 1187 } 1188 1189 const ( 1190 _KindSpecialFinalizer = 1 1191 _KindSpecialProfile = 2 1192 // Note: The finalizer special must be first because if we're freeing 1193 // an object, a finalizer special will cause the freeing operation 1194 // to abort, and we want to keep the other special records around 1195 // if that happens. 1196 ) 1197 1198 //go:notinheap 1199 type special struct { 1200 next *special // linked list in span 1201 offset uint16 // span offset of object 1202 kind byte // kind of special 1203 } 1204 1205 // Adds the special record s to the list of special records for 1206 // the object p. All fields of s should be filled in except for 1207 // offset & next, which this routine will fill in. 1208 // Returns true if the special was successfully added, false otherwise. 1209 // (The add will fail only if a record with the same p and s->kind 1210 // already exists.) 1211 func addspecial(p unsafe.Pointer, s *special) bool { 1212 span := spanOfHeap(uintptr(p)) 1213 if span == nil { 1214 throw("addspecial on invalid pointer") 1215 } 1216 1217 // Ensure that the span is swept. 1218 // Sweeping accesses the specials list w/o locks, so we have 1219 // to synchronize with it. And it's just much safer. 1220 mp := acquirem() 1221 span.ensureSwept() 1222 1223 offset := uintptr(p) - span.base() 1224 kind := s.kind 1225 1226 lock(&span.speciallock) 1227 1228 // Find splice point, check for existing record. 1229 t := &span.specials 1230 for { 1231 x := *t 1232 if x == nil { 1233 break 1234 } 1235 if offset == uintptr(x.offset) && kind == x.kind { 1236 unlock(&span.speciallock) 1237 releasem(mp) 1238 return false // already exists 1239 } 1240 if offset < uintptr(x.offset) || (offset == uintptr(x.offset) && kind < x.kind) { 1241 break 1242 } 1243 t = &x.next 1244 } 1245 1246 // Splice in record, fill in offset. 1247 s.offset = uint16(offset) 1248 s.next = *t 1249 *t = s 1250 unlock(&span.speciallock) 1251 releasem(mp) 1252 1253 return true 1254 } 1255 1256 // Removes the Special record of the given kind for the object p. 1257 // Returns the record if the record existed, nil otherwise. 1258 // The caller must FixAlloc_Free the result. 1259 func removespecial(p unsafe.Pointer, kind uint8) *special { 1260 span := spanOfHeap(uintptr(p)) 1261 if span == nil { 1262 throw("removespecial on invalid pointer") 1263 } 1264 1265 // Ensure that the span is swept. 1266 // Sweeping accesses the specials list w/o locks, so we have 1267 // to synchronize with it. And it's just much safer. 1268 mp := acquirem() 1269 span.ensureSwept() 1270 1271 offset := uintptr(p) - span.base() 1272 1273 lock(&span.speciallock) 1274 t := &span.specials 1275 for { 1276 s := *t 1277 if s == nil { 1278 break 1279 } 1280 // This function is used for finalizers only, so we don't check for 1281 // "interior" specials (p must be exactly equal to s->offset). 1282 if offset == uintptr(s.offset) && kind == s.kind { 1283 *t = s.next 1284 unlock(&span.speciallock) 1285 releasem(mp) 1286 return s 1287 } 1288 t = &s.next 1289 } 1290 unlock(&span.speciallock) 1291 releasem(mp) 1292 return nil 1293 } 1294 1295 // The described object has a finalizer set for it. 1296 // 1297 // specialfinalizer is allocated from non-GC'd memory, so any heap 1298 // pointers must be specially handled. 1299 // 1300 //go:notinheap 1301 type specialfinalizer struct { 1302 special special 1303 fn *funcval // May be a heap pointer. 1304 nret uintptr 1305 fint *_type // May be a heap pointer, but always live. 1306 ot *ptrtype // May be a heap pointer, but always live. 1307 } 1308 1309 // Adds a finalizer to the object p. Returns true if it succeeded. 1310 func addfinalizer(p unsafe.Pointer, f *funcval, nret uintptr, fint *_type, ot *ptrtype) bool { 1311 lock(&mheap_.speciallock) 1312 s := (*specialfinalizer)(mheap_.specialfinalizeralloc.alloc()) 1313 unlock(&mheap_.speciallock) 1314 s.special.kind = _KindSpecialFinalizer 1315 s.fn = f 1316 s.nret = nret 1317 s.fint = fint 1318 s.ot = ot 1319 if addspecial(p, &s.special) { 1320 // This is responsible for maintaining the same 1321 // GC-related invariants as markrootSpans in any 1322 // situation where it's possible that markrootSpans 1323 // has already run but mark termination hasn't yet. 1324 if gcphase != _GCoff { 1325 base, _, _ := findObject(uintptr(p), 0, 0) 1326 mp := acquirem() 1327 gcw := &mp.p.ptr().gcw 1328 // Mark everything reachable from the object 1329 // so it's retained for the finalizer. 1330 scanobject(base, gcw) 1331 // Mark the finalizer itself, since the 1332 // special isn't part of the GC'd heap. 1333 scanblock(uintptr(unsafe.Pointer(&s.fn)), sys.PtrSize, &oneptrmask[0], gcw, nil) 1334 releasem(mp) 1335 } 1336 return true 1337 } 1338 1339 // There was an old finalizer 1340 lock(&mheap_.speciallock) 1341 mheap_.specialfinalizeralloc.free(unsafe.Pointer(s)) 1342 unlock(&mheap_.speciallock) 1343 return false 1344 } 1345 1346 // Removes the finalizer (if any) from the object p. 1347 func removefinalizer(p unsafe.Pointer) { 1348 s := (*specialfinalizer)(unsafe.Pointer(removespecial(p, _KindSpecialFinalizer))) 1349 if s == nil { 1350 return // there wasn't a finalizer to remove 1351 } 1352 lock(&mheap_.speciallock) 1353 mheap_.specialfinalizeralloc.free(unsafe.Pointer(s)) 1354 unlock(&mheap_.speciallock) 1355 } 1356 1357 // The described object is being heap profiled. 1358 // 1359 //go:notinheap 1360 type specialprofile struct { 1361 special special 1362 b *bucket 1363 } 1364 1365 // Set the heap profile bucket associated with addr to b. 1366 func setprofilebucket(p unsafe.Pointer, b *bucket) { 1367 lock(&mheap_.speciallock) 1368 s := (*specialprofile)(mheap_.specialprofilealloc.alloc()) 1369 unlock(&mheap_.speciallock) 1370 s.special.kind = _KindSpecialProfile 1371 s.b = b 1372 if !addspecial(p, &s.special) { 1373 throw("setprofilebucket: profile already set") 1374 } 1375 } 1376 1377 // Do whatever cleanup needs to be done to deallocate s. It has 1378 // already been unlinked from the MSpan specials list. 1379 func freespecial(s *special, p unsafe.Pointer, size uintptr) { 1380 switch s.kind { 1381 case _KindSpecialFinalizer: 1382 sf := (*specialfinalizer)(unsafe.Pointer(s)) 1383 queuefinalizer(p, sf.fn, sf.nret, sf.fint, sf.ot) 1384 lock(&mheap_.speciallock) 1385 mheap_.specialfinalizeralloc.free(unsafe.Pointer(sf)) 1386 unlock(&mheap_.speciallock) 1387 case _KindSpecialProfile: 1388 sp := (*specialprofile)(unsafe.Pointer(s)) 1389 mProf_Free(sp.b, size) 1390 lock(&mheap_.speciallock) 1391 mheap_.specialprofilealloc.free(unsafe.Pointer(sp)) 1392 unlock(&mheap_.speciallock) 1393 default: 1394 throw("bad special kind") 1395 panic("not reached") 1396 } 1397 } 1398 1399 // gcBits is an alloc/mark bitmap. This is always used as *gcBits. 1400 // 1401 //go:notinheap 1402 type gcBits uint8 1403 1404 // bytep returns a pointer to the n'th byte of b. 1405 func (b *gcBits) bytep(n uintptr) *uint8 { 1406 return addb((*uint8)(b), n) 1407 } 1408 1409 // bitp returns a pointer to the byte containing bit n and a mask for 1410 // selecting that bit from *bytep. 1411 func (b *gcBits) bitp(n uintptr) (bytep *uint8, mask uint8) { 1412 return b.bytep(n / 8), 1 << (n % 8) 1413 } 1414 1415 const gcBitsChunkBytes = uintptr(64 << 10) 1416 const gcBitsHeaderBytes = unsafe.Sizeof(gcBitsHeader{}) 1417 1418 type gcBitsHeader struct { 1419 free uintptr // free is the index into bits of the next free byte. 1420 next uintptr // *gcBits triggers recursive type bug. (issue 14620) 1421 } 1422 1423 //go:notinheap 1424 type gcBitsArena struct { 1425 // gcBitsHeader // side step recursive type bug (issue 14620) by including fields by hand. 1426 free uintptr // free is the index into bits of the next free byte; read/write atomically 1427 next *gcBitsArena 1428 bits [gcBitsChunkBytes - gcBitsHeaderBytes]gcBits 1429 } 1430 1431 var gcBitsArenas struct { 1432 lock mutex 1433 free *gcBitsArena 1434 next *gcBitsArena // Read atomically. Write atomically under lock. 1435 current *gcBitsArena 1436 previous *gcBitsArena 1437 } 1438 1439 // tryAlloc allocates from b or returns nil if b does not have enough room. 1440 // This is safe to call concurrently. 1441 func (b *gcBitsArena) tryAlloc(bytes uintptr) *gcBits { 1442 if b == nil || atomic.Loaduintptr(&b.free)+bytes > uintptr(len(b.bits)) { 1443 return nil 1444 } 1445 // Try to allocate from this block. 1446 end := atomic.Xadduintptr(&b.free, bytes) 1447 if end > uintptr(len(b.bits)) { 1448 return nil 1449 } 1450 // There was enough room. 1451 start := end - bytes 1452 return &b.bits[start] 1453 } 1454 1455 // newMarkBits returns a pointer to 8 byte aligned bytes 1456 // to be used for a span's mark bits. 1457 func newMarkBits(nelems uintptr) *gcBits { 1458 blocksNeeded := uintptr((nelems + 63) / 64) 1459 bytesNeeded := blocksNeeded * 8 1460 1461 // Try directly allocating from the current head arena. 1462 head := (*gcBitsArena)(atomic.Loadp(unsafe.Pointer(&gcBitsArenas.next))) 1463 if p := head.tryAlloc(bytesNeeded); p != nil { 1464 return p 1465 } 1466 1467 // There's not enough room in the head arena. We may need to 1468 // allocate a new arena. 1469 lock(&gcBitsArenas.lock) 1470 // Try the head arena again, since it may have changed. Now 1471 // that we hold the lock, the list head can't change, but its 1472 // free position still can. 1473 if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil { 1474 unlock(&gcBitsArenas.lock) 1475 return p 1476 } 1477 1478 // Allocate a new arena. This may temporarily drop the lock. 1479 fresh := newArenaMayUnlock() 1480 // If newArenaMayUnlock dropped the lock, another thread may 1481 // have put a fresh arena on the "next" list. Try allocating 1482 // from next again. 1483 if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil { 1484 // Put fresh back on the free list. 1485 // TODO: Mark it "already zeroed" 1486 fresh.next = gcBitsArenas.free 1487 gcBitsArenas.free = fresh 1488 unlock(&gcBitsArenas.lock) 1489 return p 1490 } 1491 1492 // Allocate from the fresh arena. We haven't linked it in yet, so 1493 // this cannot race and is guaranteed to succeed. 1494 p := fresh.tryAlloc(bytesNeeded) 1495 if p == nil { 1496 throw("markBits overflow") 1497 } 1498 1499 // Add the fresh arena to the "next" list. 1500 fresh.next = gcBitsArenas.next 1501 atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), unsafe.Pointer(fresh)) 1502 1503 unlock(&gcBitsArenas.lock) 1504 return p 1505 } 1506 1507 // newAllocBits returns a pointer to 8 byte aligned bytes 1508 // to be used for this span's alloc bits. 1509 // newAllocBits is used to provide newly initialized spans 1510 // allocation bits. For spans not being initialized the 1511 // mark bits are repurposed as allocation bits when 1512 // the span is swept. 1513 func newAllocBits(nelems uintptr) *gcBits { 1514 return newMarkBits(nelems) 1515 } 1516 1517 // nextMarkBitArenaEpoch establishes a new epoch for the arenas 1518 // holding the mark bits. The arenas are named relative to the 1519 // current GC cycle which is demarcated by the call to finishweep_m. 1520 // 1521 // All current spans have been swept. 1522 // During that sweep each span allocated room for its gcmarkBits in 1523 // gcBitsArenas.next block. gcBitsArenas.next becomes the gcBitsArenas.current 1524 // where the GC will mark objects and after each span is swept these bits 1525 // will be used to allocate objects. 1526 // gcBitsArenas.current becomes gcBitsArenas.previous where the span's 1527 // gcAllocBits live until all the spans have been swept during this GC cycle. 1528 // The span's sweep extinguishes all the references to gcBitsArenas.previous 1529 // by pointing gcAllocBits into the gcBitsArenas.current. 1530 // The gcBitsArenas.previous is released to the gcBitsArenas.free list. 1531 func nextMarkBitArenaEpoch() { 1532 lock(&gcBitsArenas.lock) 1533 if gcBitsArenas.previous != nil { 1534 if gcBitsArenas.free == nil { 1535 gcBitsArenas.free = gcBitsArenas.previous 1536 } else { 1537 // Find end of previous arenas. 1538 last := gcBitsArenas.previous 1539 for last = gcBitsArenas.previous; last.next != nil; last = last.next { 1540 } 1541 last.next = gcBitsArenas.free 1542 gcBitsArenas.free = gcBitsArenas.previous 1543 } 1544 } 1545 gcBitsArenas.previous = gcBitsArenas.current 1546 gcBitsArenas.current = gcBitsArenas.next 1547 atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), nil) // newMarkBits calls newArena when needed 1548 unlock(&gcBitsArenas.lock) 1549 } 1550 1551 // newArenaMayUnlock allocates and zeroes a gcBits arena. 1552 // The caller must hold gcBitsArena.lock. This may temporarily release it. 1553 func newArenaMayUnlock() *gcBitsArena { 1554 var result *gcBitsArena 1555 if gcBitsArenas.free == nil { 1556 unlock(&gcBitsArenas.lock) 1557 result = (*gcBitsArena)(sysAlloc(gcBitsChunkBytes, &memstats.gc_sys)) 1558 if result == nil { 1559 throw("runtime: cannot allocate memory") 1560 } 1561 lock(&gcBitsArenas.lock) 1562 } else { 1563 result = gcBitsArenas.free 1564 gcBitsArenas.free = gcBitsArenas.free.next 1565 memclrNoHeapPointers(unsafe.Pointer(result), gcBitsChunkBytes) 1566 } 1567 result.next = nil 1568 // If result.bits is not 8 byte aligned adjust index so 1569 // that &result.bits[result.free] is 8 byte aligned. 1570 if uintptr(unsafe.Offsetof(gcBitsArena{}.bits))&7 == 0 { 1571 result.free = 0 1572 } else { 1573 result.free = 8 - (uintptr(unsafe.Pointer(&result.bits[0])) & 7) 1574 } 1575 return result 1576 }