summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 01:29:34 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 01:29:34 +0000
commit3dec92a6d04c67f7fb15981dc9c6e3f881663fef (patch)
treec99e42ea26464192473cf26e9bc898c595a5737e /third_party
parent04999e660bef3b6df5518acea9749878af736b8e (diff)
downloadchromium_src-3dec92a6d04c67f7fb15981dc9c6e3f881663fef.zip
chromium_src-3dec92a6d04c67f7fb15981dc9c6e3f881663fef.tar.gz
chromium_src-3dec92a6d04c67f7fb15981dc9c6e3f881663fef.tar.bz2
Rounds up VirtualAlloc calls on windows to dwAllocationGranularity to prevent fragmentation
Actually on Windows VirtualAlloc'ated address might have bigger alignment than reported by SYSTEM_INFO.dwPageSize, see SYSTEM_INFO.dwAllocationGranularity. As coalescing of spans in tcmalloc requires that those spans are physically adjacent, using smaller alignment inhibited coalescing. Additional benefit is we now require ways less memory at least in some case. Also adds assert()s for alignment values that would lead to pathological virtual address space waste. No current callers pass in alignment values other than kPageSize and it's unlikely anyone will. Original patch and discussion was at http://codereview.chromium.org/235003 Patch by: antonm@chromium.org BUG=22701 TEST=Manually checked test page that did 10m XHR. Memory use goes from >2GB and a crash to 102MB. Membuster shows the change is roughly within noise and possibly a very slight regression ( <<5% ). Review URL: http://codereview.chromium.org/222028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27162 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/tcmalloc/port.cc39
1 files changed, 20 insertions, 19 deletions
diff --git a/third_party/tcmalloc/port.cc b/third_party/tcmalloc/port.cc
index 578c8ba..4a22dda 100644
--- a/third_party/tcmalloc/port.cc
+++ b/third_party/tcmalloc/port.cc
@@ -71,7 +71,8 @@ int getpagesize() {
if (pagesize == 0) {
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
- pagesize = system_info.dwPageSize;
+ pagesize = std::max(system_info.dwPageSize,
+ system_info.dwAllocationGranularity);
}
return pagesize;
}
@@ -188,37 +189,37 @@ static SpinLock alloc_lock(SpinLock::LINKER_INITIALIZED);
// munmap's in the middle of the page, which is forbidden in windows.
extern void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
size_t alignment) {
- // Safest is to make actual_size same as input-size.
- if (actual_size) {
- *actual_size = size;
- }
-
SpinLockHolder sh(&alloc_lock);
// Align on the pagesize boundary
const int pagesize = getpagesize();
if (alignment < pagesize) alignment = pagesize;
size = ((size + alignment - 1) / alignment) * alignment;
- // Ask for extra memory if alignment > pagesize
- size_t extra = 0;
- if (alignment > pagesize) {
- extra = alignment - pagesize;
+ // Report the total number of bytes the OS actually delivered. This might be
+ // greater than |size| because of alignment concerns. The full size is
+ // necessary so that adjacent spans can be coalesced.
+ // TODO(antonm): proper processing of alignments
+ // in actual_size and decommitting.
+ if (actual_size) {
+ *actual_size = size;
}
- void* result = VirtualAlloc(0, size + extra,
+ // We currently do not support alignments larger than the pagesize or
+ // alignments that are not multiples of the pagesize after being floored.
+ // If this ability is needed it can be done by the caller (assuming it knows
+ // the page size).
+ assert(alignment <= pagesize);
+
+ void* result = VirtualAlloc(0, size,
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
if (result == NULL)
return NULL;
- // Adjust the return memory so it is aligned
- uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
- size_t adjust = 0;
- if ((ptr & (alignment - 1)) != 0) {
- adjust = alignment - (ptr & (alignment - 1));
- }
+ // If the result is not aligned memory fragmentation will result which can
+ // lead to pathological memory use.
+ assert((reinterpret_cast<uintptr_t>(result) & (alignment - 1)) == 0);
- ptr += adjust;
- return reinterpret_cast<void*>(ptr);
+ return result;
}
void TCMalloc_SystemRelease(void* start, size_t length) {