384
void TCMalloc_SystemRelease(void* start, size_t length)
387
UNUSED_PARAM(length);
388
#if HAVE(MADV_DONTNEED)
390
#if HAVE(MADV_FREE_REUSE)
392
void TCMalloc_SystemRelease(void* start, size_t length)
394
while (madvise(start, length, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
397
#elif HAVE(MADV_FREE) || HAVE(MADV_DONTNEED)
399
void TCMalloc_SystemRelease(void* start, size_t length)
401
// MADV_FREE clears the modified bit on pages, which allows
402
// them to be discarded immediately.
404
const int advice = MADV_FREE;
406
const int advice = MADV_DONTNEED;
389
408
if (FLAGS_malloc_devmem_start) {
390
409
// It's not safe to use MADV_DONTNEED if we've been mapping
391
410
// /dev/mem for heap memory
412
431
// Note -- ignoring most return codes, because if this fails it
413
432
// doesn't matter...
414
433
while (madvise(reinterpret_cast<char*>(new_start), new_end - new_start,
415
MADV_DONTNEED) == -1 &&
416
435
errno == EAGAIN) {
443
void TCMalloc_SystemRelease(void* start, size_t length)
424
445
void* newAddress = mmap(start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
425
446
// If the mmap failed then that's ok, we just won't return the memory to the system.
426
447
ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED));
450
#elif HAVE(VIRTUALALLOC)
452
void TCMalloc_SystemRelease(void* start, size_t length)
454
if (VirtualFree(start, length, MEM_DECOMMIT))
457
// The decommit may fail if the memory region consists of allocations
458
// from more than one call to VirtualAlloc. In this case, fall back to
459
// using VirtualQuery to retrieve the allocation boundaries and decommit
460
// them each individually.
462
char* ptr = static_cast<char*>(start);
463
char* end = ptr + length;
464
MEMORY_BASIC_INFORMATION info;
466
size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
467
ASSERT_UNUSED(resultSize, resultSize == sizeof(info));
469
size_t decommitSize = min<size_t>(info.RegionSize, end - ptr);
470
BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT);
471
ASSERT_UNUSED(success, success);
478
// Platforms that don't support returning memory use an empty inline version of TCMalloc_SystemRelease
479
// declared in TCSystemAlloc.h
431
#if HAVE(VIRTUALALLOC)
432
void TCMalloc_SystemCommit(void* start, size_t length)
435
UNUSED_PARAM(length);
483
#if HAVE(MADV_FREE_REUSE)
485
void TCMalloc_SystemCommit(void* start, size_t length)
487
while (madvise(start, length, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
490
#elif HAVE(VIRTUALALLOC)
492
void TCMalloc_SystemCommit(void* start, size_t length)
494
if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start)
497
// The commit may fail if the memory region consists of allocations
498
// from more than one call to VirtualAlloc. In this case, fall back to
499
// using VirtualQuery to retrieve the allocation boundaries and commit them
500
// each individually.
502
char* ptr = static_cast<char*>(start);
503
char* end = ptr + length;
504
MEMORY_BASIC_INFORMATION info;
506
size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
507
ASSERT_UNUSED(resultSize, resultSize == sizeof(info));
509
size_t commitSize = min<size_t>(info.RegionSize, end - ptr);
510
void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT, PAGE_READWRITE);
511
ASSERT_UNUSED(newAddress, newAddress == ptr);
518
// Platforms that don't need to explicitly commit memory use an empty inline version of TCMalloc_SystemCommit
519
// declared in TCSystemAlloc.h