| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 #if !CPU(64BIT) | 321 #if !CPU(64BIT) |
| 322 // Check whether this OOM is due to a lot of super pages that are allocated | 322 // Check whether this OOM is due to a lot of super pages that are allocated |
| 323 // but not committed, probably due to http://crbug.com/421387. | 323 // but not committed, probably due to http://crbug.com/421387. |
| 324 if (root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages - root-
>totalSizeOfCommittedPages > kReasonableSizeOfUnusedPages) { | 324 if (root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages - root-
>totalSizeOfCommittedPages > kReasonableSizeOfUnusedPages) { |
| 325 partitionOutOfMemoryWithLotsOfUncommitedPages(); | 325 partitionOutOfMemoryWithLotsOfUncommitedPages(); |
| 326 } | 326 } |
| 327 #endif | 327 #endif |
| 328 IMMEDIATE_CRASH(); | 328 IMMEDIATE_CRASH(); |
| 329 } | 329 } |
| 330 | 330 |
| 331 static void partitionIncreaseCommittedPages(PartitionRootBase* root, size_t len) |
| 332 { |
| 333 root->totalSizeOfCommittedPages += len; |
| 334 ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root
->totalSizeOfDirectMappedPages); |
| 335 } |
| 336 |
| 337 static void partitionDecreaseCommittedPages(PartitionRootBase* root, size_t len) |
| 338 { |
| 339 root->totalSizeOfCommittedPages -= len; |
| 340 ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root
->totalSizeOfDirectMappedPages); |
| 341 } |
| 342 |
| 331 static ALWAYS_INLINE void partitionDecommitSystemPages(PartitionRootBase* root,
void* addr, size_t len) | 343 static ALWAYS_INLINE void partitionDecommitSystemPages(PartitionRootBase* root,
void* addr, size_t len) |
| 332 { | 344 { |
| 333 decommitSystemPages(addr, len); | 345 decommitSystemPages(addr, len); |
| 334 ASSERT(root->totalSizeOfCommittedPages >= len); | 346 partitionDecreaseCommittedPages(root, len); |
| 335 root->totalSizeOfCommittedPages -= len; | |
| 336 } | 347 } |
| 337 | 348 |
| 338 static ALWAYS_INLINE void partitionRecommitSystemPages(PartitionRootBase* root,
void* addr, size_t len) | 349 static ALWAYS_INLINE void partitionRecommitSystemPages(PartitionRootBase* root,
void* addr, size_t len) |
| 339 { | 350 { |
| 340 recommitSystemPages(addr, len); | 351 recommitSystemPages(addr, len); |
| 341 root->totalSizeOfCommittedPages += len; | 352 partitionIncreaseCommittedPages(root, len); |
| 342 ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root
->totalSizeOfDirectMappedPages); | |
| 343 } | 353 } |
| 344 | 354 |
| 345 static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root,
int flags, uint16_t numPartitionPages) | 355 static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root,
int flags, uint16_t numPartitionPages) |
| 346 { | 356 { |
| 347 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) % kPartitionPa
geSize)); | 357 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) % kPartitionPa
geSize)); |
| 348 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) % kPartitio
nPageSize)); | 358 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) % kPartitio
nPageSize)); |
| 349 RELEASE_ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage); | 359 RELEASE_ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage); |
| 350 size_t totalSize = kPartitionPageSize * numPartitionPages; | 360 size_t totalSize = kPartitionPageSize * numPartitionPages; |
| 351 size_t numPartitionPagesLeft = (root->nextPartitionPageEnd - root->nextParti
tionPage) >> kPartitionPageShift; | 361 size_t numPartitionPagesLeft = (root->nextPartitionPageEnd - root->nextParti
tionPage) >> kPartitionPageShift; |
| 352 if (LIKELY(numPartitionPagesLeft >= numPartitionPages)) { | 362 if (LIKELY(numPartitionPagesLeft >= numPartitionPages)) { |
| 353 // In this case, we can still hand out pages from the current super page | 363 // In this case, we can still hand out pages from the current super page |
| 354 // allocation. | 364 // allocation. |
| 355 char* ret = root->nextPartitionPage; | 365 char* ret = root->nextPartitionPage; |
| 356 root->nextPartitionPage += totalSize; | 366 root->nextPartitionPage += totalSize; |
| 357 root->totalSizeOfCommittedPages += totalSize; | 367 partitionIncreaseCommittedPages(root, totalSize); |
| 358 ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages +
root->totalSizeOfDirectMappedPages); | |
| 359 return ret; | 368 return ret; |
| 360 } | 369 } |
| 361 | 370 |
| 362 // Need a new super page. We want to allocate super pages in a continguous | 371 // Need a new super page. We want to allocate super pages in a continguous |
| 363 // address region as much as possible. This is important for not causing | 372 // address region as much as possible. This is important for not causing |
| 364 // page table bloat and not fragmenting address spaces in 32 bit architectur
es. | 373 // page table bloat and not fragmenting address spaces in 32 bit architectur
es. |
| 365 char* requestedAddress = root->nextSuperPage; | 374 char* requestedAddress = root->nextSuperPage; |
| 366 char* superPage = reinterpret_cast<char*>(allocPages(requestedAddress, kSupe
rPageSize, kSuperPageSize, PageAccessible)); | 375 char* superPage = reinterpret_cast<char*>(allocPages(requestedAddress, kSupe
rPageSize, kSuperPageSize, PageAccessible)); |
| 367 if (UNLIKELY(!superPage)) | 376 if (UNLIKELY(!superPage)) |
| 368 return 0; | 377 return 0; |
| 369 | 378 |
| 370 root->totalSizeOfSuperPages += kSuperPageSize; | 379 root->totalSizeOfSuperPages += kSuperPageSize; |
| 371 root->totalSizeOfCommittedPages += totalSize; | 380 partitionIncreaseCommittedPages(root, totalSize); |
| 372 ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root
->totalSizeOfDirectMappedPages); | |
| 373 | 381 |
| 374 root->nextSuperPage = superPage + kSuperPageSize; | 382 root->nextSuperPage = superPage + kSuperPageSize; |
| 375 char* ret = superPage + kPartitionPageSize; | 383 char* ret = superPage + kPartitionPageSize; |
| 376 root->nextPartitionPage = ret + totalSize; | 384 root->nextPartitionPage = ret + totalSize; |
| 377 root->nextPartitionPageEnd = root->nextSuperPage - kPartitionPageSize; | 385 root->nextPartitionPageEnd = root->nextSuperPage - kPartitionPageSize; |
| 378 // Make the first partition page in the super page a guard page, but leave a | 386 // Make the first partition page in the super page a guard page, but leave a |
| 379 // hole in the middle. | 387 // hole in the middle. |
| 380 // This is where we put page metadata and also a tiny amount of extent | 388 // This is where we put page metadata and also a tiny amount of extent |
| 381 // metadata. | 389 // metadata. |
| 382 setSystemPagesInaccessible(superPage, kSystemPageSize); | 390 setSystemPagesInaccessible(superPage, kSystemPageSize); |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 // - The first few system pages are the partition page in which the super | 613 // - The first few system pages are the partition page in which the super |
| 606 // page metadata is stored. We fault just one system page out of a partition | 614 // page metadata is stored. We fault just one system page out of a partition |
| 607 // page sized clump. | 615 // page sized clump. |
| 608 // - We add a trailing guard page. | 616 // - We add a trailing guard page. |
| 609 size_t mapSize = size + kPartitionPageSize + kSystemPageSize; | 617 size_t mapSize = size + kPartitionPageSize + kSystemPageSize; |
| 610 // Round up to the allocation granularity. | 618 // Round up to the allocation granularity. |
| 611 mapSize += kPageAllocationGranularityOffsetMask; | 619 mapSize += kPageAllocationGranularityOffsetMask; |
| 612 mapSize &= kPageAllocationGranularityBaseMask; | 620 mapSize &= kPageAllocationGranularityBaseMask; |
| 613 | 621 |
| 614 size_t committedPageSize = size + kSystemPageSize; | 622 size_t committedPageSize = size + kSystemPageSize; |
| 615 root->totalSizeOfCommittedPages += committedPageSize; | |
| 616 root->totalSizeOfDirectMappedPages += committedPageSize; | 623 root->totalSizeOfDirectMappedPages += committedPageSize; |
| 617 ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root
->totalSizeOfDirectMappedPages); | 624 partitionIncreaseCommittedPages(root, committedPageSize); |
| 618 | 625 |
| 619 // TODO: we may want to let the operating system place these allocations | 626 // TODO: we may want to let the operating system place these allocations |
| 620 // where it pleases. On 32-bit, this might limit address space | 627 // where it pleases. On 32-bit, this might limit address space |
| 621 // fragmentation and on 64-bit, this might have useful savings for TLB | 628 // fragmentation and on 64-bit, this might have useful savings for TLB |
| 622 // and page table overhead. | 629 // and page table overhead. |
| 623 // TODO: if upsizing realloc()s are common on large sizes, we could | 630 // TODO: if upsizing realloc()s are common on large sizes, we could |
| 624 // consider over-allocating address space on 64-bit, "just in case". | 631 // consider over-allocating address space on 64-bit, "just in case". |
| 625 // TODO: consider pre-populating page tables (e.g. MAP_POPULATE on Linux, | 632 // TODO: consider pre-populating page tables (e.g. MAP_POPULATE on Linux, |
| 626 // MADV_WILLNEED on POSIX). | 633 // MADV_WILLNEED on POSIX). |
| 627 // TODO: these pages will be zero-filled. Consider internalizing an | 634 // TODO: these pages will be zero-filled. Consider internalizing an |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 static ALWAYS_INLINE void partitionDirectUnmap(PartitionPage* page) | 677 static ALWAYS_INLINE void partitionDirectUnmap(PartitionPage* page) |
| 671 { | 678 { |
| 672 size_t unmapSize = partitionPageToDirectMapExtent(page)->mapSize; | 679 size_t unmapSize = partitionPageToDirectMapExtent(page)->mapSize; |
| 673 | 680 |
| 674 // Add on the size of the trailing guard page and preceeding partition | 681 // Add on the size of the trailing guard page and preceeding partition |
| 675 // page. | 682 // page. |
| 676 unmapSize += kPartitionPageSize + kSystemPageSize; | 683 unmapSize += kPartitionPageSize + kSystemPageSize; |
| 677 | 684 |
| 678 PartitionRootBase* root = partitionPageToRoot(page); | 685 PartitionRootBase* root = partitionPageToRoot(page); |
| 679 size_t uncommittedPageSize = page->bucket->slotSize + kSystemPageSize; | 686 size_t uncommittedPageSize = page->bucket->slotSize + kSystemPageSize; |
| 680 ASSERT(root->totalSizeOfCommittedPages >= uncommittedPageSize); | 687 partitionDecreaseCommittedPages(root, uncommittedPageSize); |
| 681 root->totalSizeOfCommittedPages -= uncommittedPageSize; | |
| 682 ASSERT(root->totalSizeOfDirectMappedPages >= uncommittedPageSize); | 688 ASSERT(root->totalSizeOfDirectMappedPages >= uncommittedPageSize); |
| 683 root->totalSizeOfDirectMappedPages -= uncommittedPageSize; | 689 root->totalSizeOfDirectMappedPages -= uncommittedPageSize; |
| 684 | 690 |
| 685 ASSERT(!(unmapSize & kPageAllocationGranularityOffsetMask)); | 691 ASSERT(!(unmapSize & kPageAllocationGranularityOffsetMask)); |
| 686 | 692 |
| 687 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page)); | 693 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page)); |
| 688 // Account for the mapping starting a partition page before the actual | 694 // Account for the mapping starting a partition page before the actual |
| 689 // allocation address. | 695 // allocation address. |
| 690 ptr -= kPartitionPageSize; | 696 ptr -= kPartitionPageSize; |
| 691 | 697 |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 printf("total live: %zu bytes\n", totalLive); | 1047 printf("total live: %zu bytes\n", totalLive); |
| 1042 printf("total resident: %zu bytes\n", totalResident); | 1048 printf("total resident: %zu bytes\n", totalResident); |
| 1043 printf("total freeable: %zu bytes\n", totalFreeable); | 1049 printf("total freeable: %zu bytes\n", totalFreeable); |
| 1044 fflush(stdout); | 1050 fflush(stdout); |
| 1045 } | 1051 } |
| 1046 | 1052 |
| 1047 #endif // !NDEBUG | 1053 #endif // !NDEBUG |
| 1048 | 1054 |
| 1049 } // namespace WTF | 1055 } // namespace WTF |
| 1050 | 1056 |
| OLD | NEW |