Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Unified Diff: third_party/tcmalloc/chromium/src/windows/port.cc

Issue 9323026: [NOT TO COMMIT!] r109: Diff of the current tcmalloc from the original google-perftools r109. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/tcmalloc/chromium/src/windows/nm-pdb.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/tcmalloc/chromium/src/windows/port.cc
diff --git a/third_party/tcmalloc/chromium/src/windows/port.cc b/third_party/tcmalloc/chromium/src/windows/port.cc
index 1ecdacec527e066a16dae0e68c89260bda0754c9..ec01fd60c9583a74249fe5faf459aca03995758e 100644
--- a/third_party/tcmalloc/chromium/src/windows/port.cc
+++ b/third_party/tcmalloc/chromium/src/windows/port.cc
@@ -44,6 +44,7 @@
#include "port.h"
#include "base/logging.h"
#include "base/spinlock.h"
+#include "internal_logging.h"
#include "system-alloc.h"
// -----------------------------------------------------------------------
@@ -60,7 +61,7 @@ int getpagesize() {
return pagesize;
}
-extern "C" PERFTOOLS_DLL_DECL void* __sbrk(ptrdiff_t increment) {
+extern "C" PERFTOOLS_DLL_DECL void* __sbrk(std::ptrdiff_t increment) {
LOG(FATAL, "Windows doesn't implement sbrk!\n");
return NULL;
}
@@ -148,12 +149,13 @@ static void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv) {
#ifdef _MSC_VER
-// extern "C" suppresses C++ name mangling so we know the symbol names
-// for the linker /INCLUDE:symbol pragmas above.
+// extern "C" suppresses C++ name mangling so we know the symbol names for the
+// linker /INCLUDE:symbol pragmas above.
extern "C" {
// This tells the linker to run these functions.
#pragma data_seg(push, old_seg)
-#pragma data_seg(".CRT$XLB")
+ // Use CRT$XLY instead of CRT$XLB to ensure we're called LATER in sequence.
+#pragma data_seg(".CRT$XLY")
void (NTAPI *p_thread_callback_tcmalloc)(
HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback;
#pragma data_seg(".CRT$XTU")
@@ -217,6 +219,10 @@ extern "C" int perftools_pthread_once(pthread_once_t *once_control,
// -----------------------------------------------------------------------
// These functions replace system-alloc.cc
+// The current system allocator. Because we don't link with system-alloc.cc,
+// we need to define our own.
+SysAllocator* sys_alloc = NULL;
+
// This is mostly like MmapSysAllocator::Alloc, except it does these weird
// munmap's in the middle of the page, which is forbidden in windows.
extern void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
@@ -226,35 +232,102 @@ extern void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
if (alignment < pagesize) alignment = pagesize;
size = ((size + alignment - 1) / alignment) * alignment;
- // Safest is to make actual_size same as input-size.
+ // 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;
}
- // Ask for extra memory if alignment > pagesize
- size_t extra = 0;
- if (alignment > pagesize) {
- extra = alignment - pagesize;
- }
+ // 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 + extra,
+ 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);
+
+ return result;
+}
+
+size_t TCMalloc_SystemAddGuard(void* start, size_t size) {
+ static size_t pagesize = 0;
+ if (pagesize == 0) {
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ pagesize = system_info.dwPageSize;
}
- ptr += adjust;
- return reinterpret_cast<void*>(ptr);
+ // We know that TCMalloc_SystemAlloc will give us a correct page alignment
+ // regardless, so we can just assert to detect erroneous callers.
+ assert(reinterpret_cast<size_t>(start) % pagesize == 0);
+
+ // Add a guard page to catch metadata corruption. We're using the
+ // PAGE_GUARD flag rather than NO_ACCESS because we want the unique
+ // exception in crash reports.
+ DWORD permissions = 0;
+ if (size > pagesize &&
+ VirtualProtect(start, pagesize, PAGE_READONLY | PAGE_GUARD,
+ &permissions)) {
+ return pagesize;
+ }
+
+ return 0;
}
void TCMalloc_SystemRelease(void* start, size_t length) {
- // TODO(csilvers): should I be calling VirtualFree here?
+ if (VirtualFree(start, length, MEM_DECOMMIT))
+ return;
+
+ // The decommit may fail if the memory region consists of allocations
+ // from more than one call to VirtualAlloc. In this case, fall back to
+ // using VirtualQuery to retrieve the allocation boundaries and decommit
+ // them each individually.
+
+ char* ptr = static_cast<char*>(start);
+ char* end = ptr + length;
+ MEMORY_BASIC_INFORMATION info;
+ while (ptr < end) {
+ size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
+ assert(resultSize == sizeof(info));
+ size_t decommitSize = std::min<size_t>(info.RegionSize, end - ptr);
+ BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT);
+ assert(success == TRUE);
+ ptr += decommitSize;
+ }
+}
+
+void TCMalloc_SystemCommit(void* start, size_t length) {
+ if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start)
+ return;
+
+ // The commit may fail if the memory region consists of allocations
+ // from more than one call to VirtualAlloc. In this case, fall back to
+ // using VirtualQuery to retrieve the allocation boundaries and commit them
+ // each individually.
+
+ char* ptr = static_cast<char*>(start);
+ char* end = ptr + length;
+ MEMORY_BASIC_INFORMATION info;
+ while (ptr < end) {
+ size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
+ assert(resultSize == sizeof(info));
+
+ size_t commitSize = std::min<size_t>(info.RegionSize, end - ptr);
+ void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT,
+ PAGE_READWRITE);
+ assert(newAddress == ptr);
+ ptr += commitSize;
+ }
}
bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
« no previous file with comments | « third_party/tcmalloc/chromium/src/windows/nm-pdb.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698