aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mheap.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/mheap.go')
-rw-r--r--src/runtime/mheap.go52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index 737161dfee..eb9418f0db 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -114,9 +114,6 @@ type mheap struct {
nsmallfree [_NumSizeClasses]uint64 // number of frees for small objects (<=maxsmallsize)
// range of addresses we might see in the heap
- bitmap_start uintptr // Points to first byte of bitmap
- bitmap_mapped uintptr
- bitmap_delta uintptr // Used to map heap address to bitmap address
// The arena_* fields indicate the addresses of the Go heap.
//
@@ -143,6 +140,21 @@ type mheap struct {
// here and *must* clobber it to use it.
arena_reserved bool
+ // arenas is the heap arena index. arenas[va/heapArenaBytes]
+ // points to the metadata for the heap arena containing va.
+ //
+ // For regions of the address space that are not backed by the
+ // Go heap, the arena index contains nil.
+ //
+ // Modifications are protected by mheap_.lock. Reads can be
+ // performed without locking; however, a given entry can
+ // transition from nil to non-nil at any time when the lock
+ // isn't held. (Entries never transitions back to nil.)
+ //
+ // This structure is fully mapped by mallocinit, so it's safe
+ // to probe any index.
+ arenas *[memLimit / heapArenaBytes]*heapArena
+
//_ uint32 // ensure 64-bit alignment
// central free lists for small size classes.
@@ -167,6 +179,23 @@ type mheap struct {
var mheap_ mheap
+// A heapArena stores metadata for a heap arena. heapArenas are stored
+// outside of the Go heap and accessed via the mheap_.arenas index.
+//
+// This gets allocated directly from the OS, so ideally it should be a
+// multiple of the system page size. For example, avoid adding small
+// fields.
+//
+//go:notinheap
+type heapArena struct {
+ // bitmap stores the pointer/scalar bitmap for the words in
+ // this arena. See mbitmap.go for a description. Use the
+ // heapBits type to access this.
+ bitmap [heapArenaBitmapBytes]byte
+
+ // TODO: Also store the spans map here.
+}
+
// An MSpan is a run of pages.
//
// When a MSpan is in the heap free list, state == MSpanFree
@@ -507,8 +536,21 @@ func (h *mheap) setArenaUsed(arena_used uintptr, racemap bool) {
// avoids faults when other threads try access these regions immediately
// after observing the change to arena_used.
- // Map the bitmap.
- h.mapBits(arena_used)
+ // Allocate heap arena metadata.
+ for ri := h.arena_used / heapArenaBytes; ri < (arena_used+heapArenaBytes-1)/heapArenaBytes; ri++ {
+ if h.arenas[ri] != nil {
+ continue
+ }
+ r := (*heapArena)(persistentalloc(unsafe.Sizeof(heapArena{}), sys.PtrSize, &memstats.gc_sys))
+ if r == nil {
+ throw("runtime: out of memory allocating heap arena metadata")
+ }
+ // Store atomically just in case an object from the
+ // new heap arena becomes visible before the heap lock
+ // is released (which shouldn't happen, but there's
+ // little downside to this).
+ atomic.StorepNoWB(unsafe.Pointer(&h.arenas[ri]), unsafe.Pointer(r))
+ }
// Map spans array.
h.mapSpans(arena_used)