From 1475b9709013db2c1bb25583729529db1e549312 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Thu, 12 Dec 2019 16:41:24 -0500 Subject: [PATCH] runtime: fix off-by-1 error on address ranges When growing the address ranges, the new length is the old length + 1. Fixes #36113. Change-Id: I1b425f78e473cfa3cbdfe6113e166663f41fc9f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/211157 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: Michael Knyszek --- src/runtime/mpagealloc_test.go | 49 ++++++++++++++++++++++++++++++++++ src/runtime/mranges.go | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/runtime/mpagealloc_test.go b/src/runtime/mpagealloc_test.go index 3625d45c4c..6c48296487 100644 --- a/src/runtime/mpagealloc_test.go +++ b/src/runtime/mpagealloc_test.go @@ -112,6 +112,55 @@ func TestPageAllocGrow(t *testing.T) { {PageBase(BaseChunkIdx+0x21, 0), PageBase(BaseChunkIdx+0x22, 0)}, }, }, + "ManyDiscontiguous": { + // The initial cap is 16. Test 33 ranges, to exercise the growth path (twice). + chunks: []ChunkIdx{ + BaseChunkIdx, BaseChunkIdx + 2, BaseChunkIdx + 4, BaseChunkIdx + 6, + BaseChunkIdx + 8, BaseChunkIdx + 10, BaseChunkIdx + 12, BaseChunkIdx + 14, + BaseChunkIdx + 16, BaseChunkIdx + 18, BaseChunkIdx + 20, BaseChunkIdx + 22, + BaseChunkIdx + 24, BaseChunkIdx + 26, BaseChunkIdx + 28, BaseChunkIdx + 30, + BaseChunkIdx + 32, BaseChunkIdx + 34, BaseChunkIdx + 36, BaseChunkIdx + 38, + BaseChunkIdx + 40, BaseChunkIdx + 42, BaseChunkIdx + 44, BaseChunkIdx + 46, + BaseChunkIdx + 48, BaseChunkIdx + 50, BaseChunkIdx + 52, BaseChunkIdx + 54, + BaseChunkIdx + 56, BaseChunkIdx + 58, BaseChunkIdx + 60, BaseChunkIdx + 62, + BaseChunkIdx + 64, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+1, 0)}, + {PageBase(BaseChunkIdx+2, 0), PageBase(BaseChunkIdx+3, 0)}, + {PageBase(BaseChunkIdx+4, 0), PageBase(BaseChunkIdx+5, 0)}, + {PageBase(BaseChunkIdx+6, 0), PageBase(BaseChunkIdx+7, 0)}, + {PageBase(BaseChunkIdx+8, 0), PageBase(BaseChunkIdx+9, 0)}, + {PageBase(BaseChunkIdx+10, 0), PageBase(BaseChunkIdx+11, 0)}, + {PageBase(BaseChunkIdx+12, 0), PageBase(BaseChunkIdx+13, 0)}, + {PageBase(BaseChunkIdx+14, 0), PageBase(BaseChunkIdx+15, 0)}, + {PageBase(BaseChunkIdx+16, 0), PageBase(BaseChunkIdx+17, 0)}, + {PageBase(BaseChunkIdx+18, 0), PageBase(BaseChunkIdx+19, 0)}, + {PageBase(BaseChunkIdx+20, 0), PageBase(BaseChunkIdx+21, 0)}, + {PageBase(BaseChunkIdx+22, 0), PageBase(BaseChunkIdx+23, 0)}, + {PageBase(BaseChunkIdx+24, 0), PageBase(BaseChunkIdx+25, 0)}, + {PageBase(BaseChunkIdx+26, 0), PageBase(BaseChunkIdx+27, 0)}, + {PageBase(BaseChunkIdx+28, 0), PageBase(BaseChunkIdx+29, 0)}, + {PageBase(BaseChunkIdx+30, 0), PageBase(BaseChunkIdx+31, 0)}, + {PageBase(BaseChunkIdx+32, 0), PageBase(BaseChunkIdx+33, 0)}, + {PageBase(BaseChunkIdx+34, 0), PageBase(BaseChunkIdx+35, 0)}, + {PageBase(BaseChunkIdx+36, 0), PageBase(BaseChunkIdx+37, 0)}, + {PageBase(BaseChunkIdx+38, 0), PageBase(BaseChunkIdx+39, 0)}, + {PageBase(BaseChunkIdx+40, 0), PageBase(BaseChunkIdx+41, 0)}, + {PageBase(BaseChunkIdx+42, 0), PageBase(BaseChunkIdx+43, 0)}, + {PageBase(BaseChunkIdx+44, 0), PageBase(BaseChunkIdx+45, 0)}, + {PageBase(BaseChunkIdx+46, 0), PageBase(BaseChunkIdx+47, 0)}, + {PageBase(BaseChunkIdx+48, 0), PageBase(BaseChunkIdx+49, 0)}, + {PageBase(BaseChunkIdx+50, 0), PageBase(BaseChunkIdx+51, 0)}, + {PageBase(BaseChunkIdx+52, 0), PageBase(BaseChunkIdx+53, 0)}, + {PageBase(BaseChunkIdx+54, 0), PageBase(BaseChunkIdx+55, 0)}, + {PageBase(BaseChunkIdx+56, 0), PageBase(BaseChunkIdx+57, 0)}, + {PageBase(BaseChunkIdx+58, 0), PageBase(BaseChunkIdx+59, 0)}, + {PageBase(BaseChunkIdx+60, 0), PageBase(BaseChunkIdx+61, 0)}, + {PageBase(BaseChunkIdx+62, 0), PageBase(BaseChunkIdx+63, 0)}, + {PageBase(BaseChunkIdx+64, 0), PageBase(BaseChunkIdx+65, 0)}, + }, + }, } if PageAlloc64Bit != 0 { tests["ExtremelyDiscontiguous"] = test{ diff --git a/src/runtime/mranges.go b/src/runtime/mranges.go index c1132aa727..c14e5c7efd 100644 --- a/src/runtime/mranges.go +++ b/src/runtime/mranges.go @@ -131,7 +131,7 @@ func (a *addrRanges) add(r addrRange) { // assumptions), this would waste at most 4 MiB of memory. oldRanges := a.ranges ranges := (*notInHeapSlice)(unsafe.Pointer(&a.ranges)) - ranges.len = len(oldRanges) + ranges.len = len(oldRanges) + 1 ranges.cap = cap(oldRanges) * 2 ranges.array = (*notInHeap)(persistentalloc(unsafe.Sizeof(addrRange{})*uintptr(ranges.cap), sys.PtrSize, a.sysStat)) -- 2.48.1