Skip to content

Commit 54bb94c

Browse files
authored
Improve WithMemoryCapacityFromMax (#317).
1 parent 07fec78 commit 54bb94c

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

internal/alloc/alloc_unix.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,31 @@ import (
99
"golang.org/x/sys/unix"
1010
)
1111

12-
func NewMemory(_, max uint64) experimental.LinearMemory {
12+
func NewMemory(cap, max uint64) experimental.LinearMemory {
1313
// Round up to the page size.
1414
rnd := uint64(unix.Getpagesize() - 1)
15-
max = (max + rnd) &^ rnd
15+
res := (max + rnd) &^ rnd
1616

17-
if max > math.MaxInt {
18-
// This ensures int(max) overflows to a negative value,
17+
if res > math.MaxInt {
18+
// This ensures int(res) overflows to a negative value,
1919
// and unix.Mmap returns EINVAL.
20-
max = math.MaxUint64
20+
res = math.MaxUint64
2121
}
2222

23-
// Reserve max bytes of address space, to ensure we won't need to move it.
23+
com := res
24+
prot := unix.PROT_READ | unix.PROT_WRITE
25+
if cap < max { // Commit memory only if cap=max.
26+
com = 0
27+
prot = unix.PROT_NONE
28+
}
29+
30+
// Reserve res bytes of address space, to ensure we won't need to move it.
2431
// A protected, private, anonymous mapping should not commit memory.
25-
b, err := unix.Mmap(-1, 0, int(max), unix.PROT_NONE, unix.MAP_PRIVATE|unix.MAP_ANON)
32+
b, err := unix.Mmap(-1, 0, int(res), prot, unix.MAP_PRIVATE|unix.MAP_ANON)
2633
if err != nil {
2734
panic(err)
2835
}
29-
return &mmappedMemory{buf: b[:0]}
36+
return &mmappedMemory{buf: b[:com]}
3037
}
3138

3239
// The slice covers the entire mmapped memory:
@@ -52,8 +59,7 @@ func (m *mmappedMemory) Reallocate(size uint64) []byte {
5259
return nil
5360
}
5461

55-
// Update committed memory.
56-
m.buf = m.buf[:new]
62+
m.buf = m.buf[:new] // Update committed memory.
5763
}
5864
// Limit returned capacity because bytes beyond
5965
// len(m.buf) have not yet been committed.

internal/alloc/alloc_windows.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,36 @@ import (
99
"golang.org/x/sys/windows"
1010
)
1111

12-
func NewMemory(_, max uint64) experimental.LinearMemory {
12+
func NewMemory(cap, max uint64) experimental.LinearMemory {
1313
// Round up to the page size.
1414
rnd := uint64(windows.Getpagesize() - 1)
15-
max = (max + rnd) &^ rnd
15+
res := (max + rnd) &^ rnd
1616

17-
if max > math.MaxInt {
18-
// This ensures uintptr(max) overflows to a large value,
17+
if res > math.MaxInt {
18+
// This ensures uintptr(res) overflows to a large value,
1919
// and windows.VirtualAlloc returns an error.
20-
max = math.MaxUint64
20+
res = math.MaxUint64
2121
}
2222

23-
// Reserve max bytes of address space, to ensure we won't need to move it.
24-
// This does not commit memory.
25-
r, err := windows.VirtualAlloc(0, uintptr(max), windows.MEM_RESERVE, windows.PAGE_READWRITE)
23+
com := res
24+
kind := windows.MEM_COMMIT
25+
if cap < max { // Commit memory only if cap=max.
26+
com = 0
27+
kind = windows.MEM_RESERVE
28+
}
29+
30+
// Reserve res bytes of address space, to ensure we won't need to move it.
31+
r, err := windows.VirtualAlloc(0, uintptr(res), uint32(kind), windows.PAGE_READWRITE)
2632
if err != nil {
2733
panic(err)
2834
}
2935

3036
mem := virtualMemory{addr: r}
3137
// SliceHeader, although deprecated, avoids a go vet warning.
3238
sh := (*reflect.SliceHeader)(unsafe.Pointer(&mem.buf))
33-
sh.Cap = int(max)
3439
sh.Data = r
40+
sh.Len = int(com)
41+
sh.Cap = int(res)
3542
return &mem
3643
}
3744

@@ -59,8 +66,7 @@ func (m *virtualMemory) Reallocate(size uint64) []byte {
5966
return nil
6067
}
6168

62-
// Update committed memory.
63-
m.buf = m.buf[:new]
69+
m.buf = m.buf[:new] // Update committed memory.
6470
}
6571
// Limit returned capacity because bytes beyond
6672
// len(m.buf) have not yet been committed.

0 commit comments

Comments
 (0)