Skip to content

Commit 01d1372

Browse files
committed
runtime: use uintptr instead of int32 for counting to next heap profile sample
Overflow of the comparison caused very large (>=1<<32) allocations to sometimes not get sampled at all. Use uintptr so the comparison will never overflow. Fixes #33342 Tested on the example in 33342. I don't want to check a test in that needs that much memory, however. Change-Id: I51fe77a9117affed8094da93c0bc5f445ac2d3d3 Reviewed-on: https://go-review.googlesource.com/c/go/+/188017 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Austin Clements <[email protected]>
1 parent 7b8234b commit 01d1372

File tree

2 files changed

+7
-7
lines changed

2 files changed

+7
-7
lines changed

src/runtime/malloc.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -1075,8 +1075,8 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
10751075
}
10761076

10771077
if rate := MemProfileRate; rate > 0 {
1078-
if rate != 1 && int32(size) < c.next_sample {
1079-
c.next_sample -= int32(size)
1078+
if rate != 1 && size < c.next_sample {
1079+
c.next_sample -= size
10801080
} else {
10811081
mp := acquirem()
10821082
profilealloc(mp, x, size)
@@ -1170,15 +1170,15 @@ func profilealloc(mp *m, x unsafe.Pointer, size uintptr) {
11701170
// processes, the distance between two samples follows the exponential
11711171
// distribution (exp(MemProfileRate)), so the best return value is a random
11721172
// number taken from an exponential distribution whose mean is MemProfileRate.
1173-
func nextSample() int32 {
1173+
func nextSample() uintptr {
11741174
if GOOS == "plan9" {
11751175
// Plan 9 doesn't support floating point in note handler.
11761176
if g := getg(); g == g.m.gsignal {
11771177
return nextSampleNoFP()
11781178
}
11791179
}
11801180

1181-
return fastexprand(MemProfileRate)
1181+
return uintptr(fastexprand(MemProfileRate))
11821182
}
11831183

11841184
// fastexprand returns a random number from an exponential distribution with
@@ -1213,14 +1213,14 @@ func fastexprand(mean int) int32 {
12131213

12141214
// nextSampleNoFP is similar to nextSample, but uses older,
12151215
// simpler code to avoid floating point.
1216-
func nextSampleNoFP() int32 {
1216+
func nextSampleNoFP() uintptr {
12171217
// Set first allocation sample size.
12181218
rate := MemProfileRate
12191219
if rate > 0x3fffffff { // make 2*rate not overflow
12201220
rate = 0x3fffffff
12211221
}
12221222
if rate != 0 {
1223-
return int32(fastrand() % uint32(2*rate))
1223+
return uintptr(fastrand() % uint32(2*rate))
12241224
}
12251225
return 0
12261226
}

src/runtime/mcache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
type mcache struct {
2020
// The following members are accessed on every malloc,
2121
// so they are grouped here for better caching.
22-
next_sample int32 // trigger heap sample after allocating this many bytes
22+
next_sample uintptr // trigger heap sample after allocating this many bytes
2323
local_scan uintptr // bytes of scannable heap allocated
2424

2525
// Allocator cache for tiny objects w/o pointers.

0 commit comments

Comments
 (0)