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

Side by Side 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, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/tcmalloc/chromium/src/windows/nm-pdb.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2007, Google Inc. 1 /* Copyright (c) 2007, Google Inc.
2 * All rights reserved. 2 * All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 26 matching lines...) Expand all
37 37
38 #define NOMINMAX // so std::max, below, compiles correctly 38 #define NOMINMAX // so std::max, below, compiles correctly
39 #include <config.h> 39 #include <config.h>
40 #include <string.h> // for strlen(), memset(), memcmp() 40 #include <string.h> // for strlen(), memset(), memcmp()
41 #include <assert.h> 41 #include <assert.h>
42 #include <stdarg.h> // for va_list, va_start, va_end 42 #include <stdarg.h> // for va_list, va_start, va_end
43 #include <windows.h> 43 #include <windows.h>
44 #include "port.h" 44 #include "port.h"
45 #include "base/logging.h" 45 #include "base/logging.h"
46 #include "base/spinlock.h" 46 #include "base/spinlock.h"
47 #include "internal_logging.h"
47 #include "system-alloc.h" 48 #include "system-alloc.h"
48 49
49 // ----------------------------------------------------------------------- 50 // -----------------------------------------------------------------------
50 // Basic libraries 51 // Basic libraries
51 52
52 int getpagesize() { 53 int getpagesize() {
53 static int pagesize = 0; 54 static int pagesize = 0;
54 if (pagesize == 0) { 55 if (pagesize == 0) {
55 SYSTEM_INFO system_info; 56 SYSTEM_INFO system_info;
56 GetSystemInfo(&system_info); 57 GetSystemInfo(&system_info);
57 pagesize = std::max(system_info.dwPageSize, 58 pagesize = std::max(system_info.dwPageSize,
58 system_info.dwAllocationGranularity); 59 system_info.dwAllocationGranularity);
59 } 60 }
60 return pagesize; 61 return pagesize;
61 } 62 }
62 63
63 extern "C" PERFTOOLS_DLL_DECL void* __sbrk(ptrdiff_t increment) { 64 extern "C" PERFTOOLS_DLL_DECL void* __sbrk(std::ptrdiff_t increment) {
64 LOG(FATAL, "Windows doesn't implement sbrk!\n"); 65 LOG(FATAL, "Windows doesn't implement sbrk!\n");
65 return NULL; 66 return NULL;
66 } 67 }
67 68
68 // We need to write to 'stderr' without having windows allocate memory. 69 // We need to write to 'stderr' without having windows allocate memory.
69 // The safest way is via a low-level call like WriteConsoleA(). But 70 // The safest way is via a low-level call like WriteConsoleA(). But
70 // even then we need to be sure to print in small bursts so as to not 71 // even then we need to be sure to print in small bursts so as to not
71 // require memory allocation. 72 // require memory allocation.
72 extern "C" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len) { 73 extern "C" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len) {
73 // Looks like windows allocates for writes of >80 bytes 74 // Looks like windows allocates for writes of >80 bytes
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 } 142 }
142 143
143 static void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv) { 144 static void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv) {
144 if (dwReason == DLL_THREAD_DETACH) { // thread is being destroyed! 145 if (dwReason == DLL_THREAD_DETACH) { // thread is being destroyed!
145 on_process_term(); 146 on_process_term();
146 } 147 }
147 } 148 }
148 149
149 #ifdef _MSC_VER 150 #ifdef _MSC_VER
150 151
151 // extern "C" suppresses C++ name mangling so we know the symbol names 152 // extern "C" suppresses C++ name mangling so we know the symbol names for the
152 // for the linker /INCLUDE:symbol pragmas above. 153 // linker /INCLUDE:symbol pragmas above.
153 extern "C" { 154 extern "C" {
154 // This tells the linker to run these functions. 155 // This tells the linker to run these functions.
155 #pragma data_seg(push, old_seg) 156 #pragma data_seg(push, old_seg)
156 #pragma data_seg(".CRT$XLB") 157 // Use CRT$XLY instead of CRT$XLB to ensure we're called LATER in sequence.
158 #pragma data_seg(".CRT$XLY")
157 void (NTAPI *p_thread_callback_tcmalloc)( 159 void (NTAPI *p_thread_callback_tcmalloc)(
158 HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback; 160 HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback;
159 #pragma data_seg(".CRT$XTU") 161 #pragma data_seg(".CRT$XTU")
160 int (*p_process_term_tcmalloc)(void) = on_process_term; 162 int (*p_process_term_tcmalloc)(void) = on_process_term;
161 #pragma data_seg(pop, old_seg) 163 #pragma data_seg(pop, old_seg)
162 } // extern "C" 164 } // extern "C"
163 165
164 #else // #ifdef _MSC_VER [probably msys/mingw] 166 #else // #ifdef _MSC_VER [probably msys/mingw]
165 167
166 // We have to try the DllMain solution here, because we can't use the 168 // We have to try the DllMain solution here, because we can't use the
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 212 }
211 } 213 }
212 } 214 }
213 return 0; 215 return 0;
214 } 216 }
215 217
216 218
217 // ----------------------------------------------------------------------- 219 // -----------------------------------------------------------------------
218 // These functions replace system-alloc.cc 220 // These functions replace system-alloc.cc
219 221
222 // The current system allocator. Because we don't link with system-alloc.cc,
223 // we need to define our own.
224 SysAllocator* sys_alloc = NULL;
225
220 // This is mostly like MmapSysAllocator::Alloc, except it does these weird 226 // This is mostly like MmapSysAllocator::Alloc, except it does these weird
221 // munmap's in the middle of the page, which is forbidden in windows. 227 // munmap's in the middle of the page, which is forbidden in windows.
222 extern void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, 228 extern void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
223 size_t alignment) { 229 size_t alignment) {
224 // Align on the pagesize boundary 230 // Align on the pagesize boundary
225 const int pagesize = getpagesize(); 231 const int pagesize = getpagesize();
226 if (alignment < pagesize) alignment = pagesize; 232 if (alignment < pagesize) alignment = pagesize;
227 size = ((size + alignment - 1) / alignment) * alignment; 233 size = ((size + alignment - 1) / alignment) * alignment;
228 234
229 // Safest is to make actual_size same as input-size. 235 // Report the total number of bytes the OS actually delivered. This might be
236 // greater than |size| because of alignment concerns. The full size is
237 // necessary so that adjacent spans can be coalesced.
238 // TODO(antonm): proper processing of alignments
239 // in actual_size and decommitting.
230 if (actual_size) { 240 if (actual_size) {
231 *actual_size = size; 241 *actual_size = size;
232 } 242 }
233 243
234 // Ask for extra memory if alignment > pagesize 244 // We currently do not support alignments larger than the pagesize or
235 size_t extra = 0; 245 // alignments that are not multiples of the pagesize after being floored.
236 if (alignment > pagesize) { 246 // If this ability is needed it can be done by the caller (assuming it knows
237 extra = alignment - pagesize; 247 // the page size).
238 } 248 assert(alignment <= pagesize);
239 249
240 void* result = VirtualAlloc(0, size + extra, 250 void* result = VirtualAlloc(0, size,
241 MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); 251 MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
242 if (result == NULL) 252 if (result == NULL)
243 return NULL; 253 return NULL;
244 254
245 // Adjust the return memory so it is aligned 255 // If the result is not aligned memory fragmentation will result which can
246 uintptr_t ptr = reinterpret_cast<uintptr_t>(result); 256 // lead to pathological memory use.
247 size_t adjust = 0; 257 assert((reinterpret_cast<uintptr_t>(result) & (alignment - 1)) == 0);
248 if ((ptr & (alignment - 1)) != 0) { 258
249 adjust = alignment - (ptr & (alignment - 1)); 259 return result;
260 }
261
262 size_t TCMalloc_SystemAddGuard(void* start, size_t size) {
263 static size_t pagesize = 0;
264 if (pagesize == 0) {
265 SYSTEM_INFO system_info;
266 GetSystemInfo(&system_info);
267 pagesize = system_info.dwPageSize;
250 } 268 }
251 269
252 ptr += adjust; 270 // We know that TCMalloc_SystemAlloc will give us a correct page alignment
253 return reinterpret_cast<void*>(ptr); 271 // regardless, so we can just assert to detect erroneous callers.
272 assert(reinterpret_cast<size_t>(start) % pagesize == 0);
273
274 // Add a guard page to catch metadata corruption. We're using the
275 // PAGE_GUARD flag rather than NO_ACCESS because we want the unique
276 // exception in crash reports.
277 DWORD permissions = 0;
278 if (size > pagesize &&
279 VirtualProtect(start, pagesize, PAGE_READONLY | PAGE_GUARD,
280 &permissions)) {
281 return pagesize;
282 }
283
284 return 0;
254 } 285 }
255 286
256 void TCMalloc_SystemRelease(void* start, size_t length) { 287 void TCMalloc_SystemRelease(void* start, size_t length) {
257 // TODO(csilvers): should I be calling VirtualFree here? 288 if (VirtualFree(start, length, MEM_DECOMMIT))
289 return;
290
291 // The decommit may fail if the memory region consists of allocations
292 // from more than one call to VirtualAlloc. In this case, fall back to
293 // using VirtualQuery to retrieve the allocation boundaries and decommit
294 // them each individually.
295
296 char* ptr = static_cast<char*>(start);
297 char* end = ptr + length;
298 MEMORY_BASIC_INFORMATION info;
299 while (ptr < end) {
300 size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
301 assert(resultSize == sizeof(info));
302 size_t decommitSize = std::min<size_t>(info.RegionSize, end - ptr);
303 BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT);
304 assert(success == TRUE);
305 ptr += decommitSize;
306 }
307 }
308
309 void TCMalloc_SystemCommit(void* start, size_t length) {
310 if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start)
311 return;
312
313 // The commit may fail if the memory region consists of allocations
314 // from more than one call to VirtualAlloc. In this case, fall back to
315 // using VirtualQuery to retrieve the allocation boundaries and commit them
316 // each individually.
317
318 char* ptr = static_cast<char*>(start);
319 char* end = ptr + length;
320 MEMORY_BASIC_INFORMATION info;
321 while (ptr < end) {
322 size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
323 assert(resultSize == sizeof(info));
324
325 size_t commitSize = std::min<size_t>(info.RegionSize, end - ptr);
326 void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT,
327 PAGE_READWRITE);
328 assert(newAddress == ptr);
329 ptr += commitSize;
330 }
258 } 331 }
259 332
260 bool RegisterSystemAllocator(SysAllocator *allocator, int priority) { 333 bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
261 return false; // we don't allow registration on windows, right now 334 return false; // we don't allow registration on windows, right now
262 } 335 }
263 336
264 void DumpSystemAllocatorStats(TCMalloc_Printer* printer) { 337 void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
265 // We don't dump stats on windows, right now 338 // We don't dump stats on windows, right now
266 } 339 }
267 340
(...skipping 13 matching lines...) Expand all
281 if ((strlen(fname) >= prefix_length) && 354 if ((strlen(fname) >= prefix_length) &&
282 (memcmp(fname, prefix, prefix_length) == 0)) { 355 (memcmp(fname, prefix, prefix_length) == 0)) {
283 RAW_VLOG(0, "Removing old heap profile %s\n", fname); 356 RAW_VLOG(0, "Removing old heap profile %s\n", fname);
284 // TODO(csilvers): we really need to unlink dirname + fname 357 // TODO(csilvers): we really need to unlink dirname + fname
285 _unlink(fname); 358 _unlink(fname);
286 } 359 }
287 } while (FindNextFileA(hFind, &found) != FALSE); // A is for Ansi 360 } while (FindNextFileA(hFind, &found) != FALSE); // A is for Ansi
288 FindClose(hFind); 361 FindClose(hFind);
289 } 362 }
290 } 363 }
OLDNEW
« 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