| 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 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 page->nextPage = 0; | 519 page->nextPage = 0; |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 | 522 |
| 523 bucket->activePagesHead = 0; | 523 bucket->activePagesHead = 0; |
| 524 return false; | 524 return false; |
| 525 } | 525 } |
| 526 | 526 |
| 527 static ALWAYS_INLINE void* partitionDirectMap(PartitionRootBase* root, int flags
, size_t size) | 527 static ALWAYS_INLINE void* partitionDirectMap(PartitionRootBase* root, int flags
, size_t size) |
| 528 { | 528 { |
| 529 size += kSystemPageOffsetMask; | 529 size = partitionDirectMapSize(size); |
| 530 size &= kSystemPageBaseMask; | 530 |
| 531 // Because we need to fake looking like a super page, We need to allocate | 531 // Because we need to fake looking like a super page, We need to allocate |
| 532 // a bunch of system pages more than "size": | 532 // a bunch of system pages more than "size": |
| 533 // - The first few system pages are the partition page in which the super | 533 // - The first few system pages are the partition page in which the super |
| 534 // page metadata is stored. We fault just one system page out of a partition | 534 // page metadata is stored. We fault just one system page out of a partition |
| 535 // page sized clump. | 535 // page sized clump. |
| 536 // - We add a trailing guard page. | 536 // - We add a trailing guard page. |
| 537 size_t mapSize = size + kPartitionPageSize + kSystemPageSize; | 537 size_t mapSize = size + kPartitionPageSize + kSystemPageSize; |
| 538 // Round up to the allocation granularity. | 538 // Round up to the allocation granularity. |
| 539 mapSize += kPageAllocationGranularityOffsetMask; | 539 mapSize += kPageAllocationGranularityOffsetMask; |
| 540 mapSize &= kPageAllocationGranularityBaseMask; | 540 mapSize &= kPageAllocationGranularityBaseMask; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 void* partitionAllocSlowPath(PartitionRootBase* root, int flags, size_t size, Pa
rtitionBucket* bucket) | 604 void* partitionAllocSlowPath(PartitionRootBase* root, int flags, size_t size, Pa
rtitionBucket* bucket) |
| 605 { | 605 { |
| 606 // The slow path is called when the freelist is empty. | 606 // The slow path is called when the freelist is empty. |
| 607 ASSERT(!bucket->activePagesHead->freelistHead); | 607 ASSERT(!bucket->activePagesHead->freelistHead); |
| 608 | 608 |
| 609 // For the partitionAllocGeneric API, we have a bunch of buckets marked | 609 // For the partitionAllocGeneric API, we have a bunch of buckets marked |
| 610 // as special cases. We bounce them through to the slow path so that we | 610 // as special cases. We bounce them through to the slow path so that we |
| 611 // can still have a blazing fast hot path due to lack of corner-case | 611 // can still have a blazing fast hot path due to lack of corner-case |
| 612 // branches. | 612 // branches. |
| 613 bool returnNull = flags & PartitionAllocReturnNull; | 613 bool returnNull = flags & PartitionAllocReturnNull; |
| 614 if (UNLIKELY(!bucket->numSystemPagesPerSlotSpan)) { | 614 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { |
| 615 ASSERT(size > kGenericMaxBucketed); | 615 ASSERT(size > kGenericMaxBucketed); |
| 616 ASSERT(bucket == &PartitionRootBase::gPagedBucket); | 616 ASSERT(bucket == &PartitionRootBase::gPagedBucket); |
| 617 if (size > INT_MAX - kSystemPageSize) { | 617 if (size > kGenericMaxDirectMapped) { |
| 618 if (returnNull) | 618 if (returnNull) |
| 619 return 0; | 619 return 0; |
| 620 RELEASE_ASSERT(false); | 620 RELEASE_ASSERT(false); |
| 621 } | 621 } |
| 622 return partitionDirectMap(root, flags, size); | 622 return partitionDirectMap(root, flags, size); |
| 623 } | 623 } |
| 624 | 624 |
| 625 // First, look for a usable page in the existing active pages list. | 625 // First, look for a usable page in the existing active pages list. |
| 626 // Change active page, accepting the current page as a candidate. | 626 // Change active page, accepting the current page as a candidate. |
| 627 if (LIKELY(partitionSetNewActivePage(bucket->activePagesHead))) { | 627 if (LIKELY(partitionSetNewActivePage(bucket->activePagesHead))) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 root->globalEmptyPageRingIndex = currentIndex; | 711 root->globalEmptyPageRingIndex = currentIndex; |
| 712 } | 712 } |
| 713 | 713 |
| 714 void partitionFreeSlowPath(PartitionPage* page) | 714 void partitionFreeSlowPath(PartitionPage* page) |
| 715 { | 715 { |
| 716 PartitionBucket* bucket = page->bucket; | 716 PartitionBucket* bucket = page->bucket; |
| 717 ASSERT(page != &PartitionRootGeneric::gSeedPage); | 717 ASSERT(page != &PartitionRootGeneric::gSeedPage); |
| 718 ASSERT(bucket->activePagesHead != &PartitionRootGeneric::gSeedPage); | 718 ASSERT(bucket->activePagesHead != &PartitionRootGeneric::gSeedPage); |
| 719 if (LIKELY(page->numAllocatedSlots == 0)) { | 719 if (LIKELY(page->numAllocatedSlots == 0)) { |
| 720 // Page became fully unused. | 720 // Page became fully unused. |
| 721 if (UNLIKELY(!bucket->numSystemPagesPerSlotSpan)) { | 721 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { |
| 722 partitionDirectUnmap(page); | 722 partitionDirectUnmap(page); |
| 723 return; | 723 return; |
| 724 } | 724 } |
| 725 // If it's the current page, attempt to change it. We'd prefer to leave | 725 // If it's the current page, attempt to change it. We'd prefer to leave |
| 726 // the page empty as a gentle force towards defragmentation. | 726 // the page empty as a gentle force towards defragmentation. |
| 727 if (LIKELY(page == bucket->activePagesHead) && page->nextPage) { | 727 if (LIKELY(page == bucket->activePagesHead) && page->nextPage) { |
| 728 if (partitionSetNewActivePage(page->nextPage)) { | 728 if (partitionSetNewActivePage(page->nextPage)) { |
| 729 ASSERT(bucket->activePagesHead != page); | 729 ASSERT(bucket->activePagesHead != page); |
| 730 // Link the empty page back in after the new current page, to | 730 // Link the empty page back in after the new current page, to |
| 731 // avoid losing a reference to it. | 731 // avoid losing a reference to it. |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 printf("total live: %zu bytes\n", totalLive); | 855 printf("total live: %zu bytes\n", totalLive); |
| 856 printf("total resident: %zu bytes\n", totalResident); | 856 printf("total resident: %zu bytes\n", totalResident); |
| 857 printf("total freeable: %zu bytes\n", totalFreeable); | 857 printf("total freeable: %zu bytes\n", totalFreeable); |
| 858 fflush(stdout); | 858 fflush(stdout); |
| 859 } | 859 } |
| 860 | 860 |
| 861 #endif // !NDEBUG | 861 #endif // !NDEBUG |
| 862 | 862 |
| 863 } // namespace WTF | 863 } // namespace WTF |
| 864 | 864 |
| OLD | NEW |