mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: add safe arena support to the runtime
This change adds an API to the runtime for arenas. A later CL can potentially export it as an experimental API, but for now, just the runtime implementation will suffice. The purpose of arenas is to improve efficiency, primarily by allowing for an application to manually free memory, thereby delaying garbage collection. It comes with other potential performance benefits, such as better locality, a better allocation strategy, and better handling of interior pointers by the GC. This implementation is based on one by danscales@google.com with a few significant differences: * The implementation lives entirely in the runtime (all layers). * Arena chunks are the minimum of 8 MiB or the heap arena size. This choice is made because in practice 64 MiB appears to be way too large of an area for most real-world use-cases. * Arena chunks are not unmapped, instead they're placed on an evacuation list and when there are no pointers left pointing into them, they're allowed to be reused. * Reusing partially-used arena chunks no longer tries to find one used by the same P first; it just takes the first one available. * In order to ensure worst-case fragmentation is never worse than 25%, only types and slice backing stores whose sizes are 1/4th the size of a chunk or less may be used. Previously larger sizes, up to the size of the chunk, were allowed. * ASAN, MSAN, and the race detector are fully supported. * Sets arena chunks to fault that were deferred at the end of mark termination (a non-public patch once did this; I don't see a reason not to continue that). For #51317. Change-Id: I83b1693a17302554cb36b6daa4e9249a81b1644f Reviewed-on: https://go-review.googlesource.com/c/go/+/423359 Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
4c383951b9
commit
7866538d25
16 changed files with 1595 additions and 104 deletions
|
|
@ -840,7 +840,14 @@ func sigpanic() {
|
|||
if gp.paniconfault {
|
||||
panicmemAddr(gp.sigcode1)
|
||||
}
|
||||
print("unexpected fault address ", hex(gp.sigcode1), "\n")
|
||||
if inUserArenaChunk(gp.sigcode1) {
|
||||
// We could check that the arena chunk is explicitly set to fault,
|
||||
// but the fact that we faulted on accessing it is enough to prove
|
||||
// that it is.
|
||||
print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
|
||||
} else {
|
||||
print("unexpected fault address ", hex(gp.sigcode1), "\n")
|
||||
}
|
||||
throw("fault")
|
||||
case _SIGFPE:
|
||||
switch gp.sigcode0 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue