Skip to content

Commit 959442d

Browse files
aykevldeadprogram
authored andcommitted
unix: use conservative GC by default
This commit does two things: 1. It makes it possible to grow the heap on Linux and MacOS by allocating 1GB of virtual memory on startup and then slowly using it as necessary, when running out of available heap space. 2. It switches the default GC to be the conservative GC (previously extalloc). This is good for consistency with other platforms that all use this same GC. This makes the extalloc GC unused by default.
1 parent c1aa152 commit 959442d

File tree

5 files changed

+39
-12
lines changed

5 files changed

+39
-12
lines changed

compileopts/config.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,7 @@ func (c *Config) GC() string {
8080
if c.Target.GC != "" {
8181
return c.Target.GC
8282
}
83-
for _, tag := range c.Target.BuildTags {
84-
if tag == "baremetal" || tag == "wasm" {
85-
return "conservative"
86-
}
87-
}
88-
return "extalloc"
83+
return "conservative"
8984
}
9085

9186
// NeedsStackObjects returns true if the compiler should insert stack objects

src/runtime/os_darwin.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@
33
package runtime
44

55
const GOOS = "darwin"
6+
7+
const (
8+
// See https://github.com/golang/go/blob/master/src/syscall/zerrors_darwin_amd64.go
9+
flag_PROT_READ = 0x1
10+
flag_PROT_WRITE = 0x2
11+
flag_MAP_PRIVATE = 0x2
12+
flag_MAP_ANONYMOUS = 0x1000 // MAP_ANON
13+
)

src/runtime/os_linux.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@
33
package runtime
44

55
const GOOS = "linux"
6+
7+
const (
8+
// See https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/mman-common.h
9+
flag_PROT_READ = 0x1
10+
flag_PROT_WRITE = 0x2
11+
flag_MAP_PRIVATE = 0x2
12+
flag_MAP_ANONYMOUS = 0x20
13+
)

src/runtime/runtime_unix.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ func usleep(usec uint) int
1616
//export malloc
1717
func malloc(size uintptr) unsafe.Pointer
1818

19+
//export mmap
20+
func mmap(addr unsafe.Pointer, length, prot, flags, fd int, offset int) unsafe.Pointer
21+
1922
//export abort
2023
func abort()
2124

src/runtime/runtime_unix_heap.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,33 @@
55

66
package runtime
77

8-
const heapSize = 1 * 1024 * 1024 // 1MB to start
8+
var heapSize uintptr = 128 * 1024 // small amount to start
9+
const heapMaxSize = 1 * 1024 * 1024 * 1024 // 1GB for the entire heap
910

1011
var heapStart, heapEnd uintptr
1112

1213
func preinit() {
13-
heapStart = uintptr(malloc(heapSize))
14+
// Allocate a large chunk of virtual memory. Because it is virtual, it won't
15+
// really be allocated in RAM. Memory will only be allocated when it is
16+
// first touched.
17+
addr := mmap(nil, heapMaxSize, flag_PROT_READ|flag_PROT_WRITE, flag_MAP_PRIVATE|flag_MAP_ANONYMOUS, -1, 0)
18+
heapStart = uintptr(addr)
1419
heapEnd = heapStart + heapSize
1520
}
1621

1722
// growHeap tries to grow the heap size. It returns true if it succeeds, false
1823
// otherwise.
1924
func growHeap() bool {
20-
// At the moment, this is not possible. However it shouldn't be too
21-
// difficult (at least on Linux) to allocate a large amount of virtual
22-
// memory at startup that is then slowly used.
23-
return false
25+
if heapSize == heapMaxSize {
26+
// Already at the max. If we run out of memory, we should consider
27+
// increasing heapMaxSize on 64-bit systems.
28+
return false
29+
}
30+
// Grow the heap size used by the program.
31+
heapSize = (heapSize * 4 / 3) &^ 4095 // grow by around 33%
32+
if heapSize > heapMaxSize {
33+
heapSize = heapMaxSize
34+
}
35+
setHeapEnd(heapStart + heapSize)
36+
return true
2437
}

0 commit comments

Comments
 (0)