aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/malloc.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2018-09-26 14:20:58 -0400
committerAustin Clements <austin@google.com>2018-11-15 19:14:10 +0000
commite500ffd88cb906014320607c6a03a5fd05ee84cf (patch)
treef88b8f4372037b1e89608faaf91a6e8eab2a6453 /src/runtime/malloc.go
parentb2df0bd5f53e599fef9fcb808304dd0e5ea3ba0b (diff)
downloadgo-e500ffd88cb906014320607c6a03a5fd05ee84cf.tar.xz
runtime: track all heap arenas in a slice
Currently, there's no efficient way to iterate over the Go heap. We're going to need this for fast free page sweeping, so this CL adds a slice of all allocated heap arenas. This will also be useful for generational GC. For #18155. Change-Id: I58d126cfb9c3f61b3125d80b74ccb1b2169efbcc Reviewed-on: https://go-review.googlesource.com/c/138076 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
Diffstat (limited to 'src/runtime/malloc.go')
-rw-r--r--src/runtime/malloc.go21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 12fa744052..e827dbae93 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -641,6 +641,27 @@ mapped:
}
}
+ // Add the arena to the arenas list.
+ if len(h.allArenas) == cap(h.allArenas) {
+ size := 2 * uintptr(cap(h.allArenas)) * sys.PtrSize
+ if size == 0 {
+ size = physPageSize
+ }
+ newArray := (*notInHeap)(persistentalloc(size, sys.PtrSize, &memstats.gc_sys))
+ if newArray == nil {
+ throw("out of memory allocating allArenas")
+ }
+ oldSlice := h.allArenas
+ *(*notInHeapSlice)(unsafe.Pointer(&h.allArenas)) = notInHeapSlice{newArray, len(h.allArenas), int(size / sys.PtrSize)}
+ copy(h.allArenas, oldSlice)
+ // Do not free the old backing array because
+ // there may be concurrent readers. Since we
+ // double the array each time, this can lead
+ // to at most 2x waste.
+ }
+ h.allArenas = h.allArenas[:len(h.allArenas)+1]
+ h.allArenas[len(h.allArenas)-1] = ri
+
// 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