Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 * | 3 // found in the LICENSE file. |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | 4 |
| 31 #include "wtf/allocator/PartitionAlloc.h" | 5 #include "base/allocator/partition_allocator/partition_alloc.h" |
| 32 | 6 |
| 33 #include "testing/gtest/include/gtest/gtest.h" | |
| 34 #include "wtf/BitwiseOperations.h" | |
| 35 #include "wtf/CPU.h" | |
| 36 #include "wtf/PtrUtil.h" | |
| 37 #include "wtf/Vector.h" | |
| 38 #include <memory> | |
| 39 #include <stdlib.h> | 7 #include <stdlib.h> |
| 40 #include <string.h> | 8 #include <string.h> |
| 41 | 9 |
| 42 #if OS(POSIX) | 10 #include <memory> |
| 11 | |
| 12 #include "base/bits.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 #if defined(OS_POSIX) | |
| 43 #include <sys/mman.h> | 16 #include <sys/mman.h> |
| 44 #include <sys/resource.h> | 17 #include <sys/resource.h> |
| 45 #include <sys/time.h> | 18 #include <sys/time.h> |
| 46 | 19 |
| 47 #ifndef MAP_ANONYMOUS | 20 #ifndef MAP_ANONYMOUS |
| 48 #define MAP_ANONYMOUS MAP_ANON | 21 #define MAP_ANONYMOUS MAP_ANON |
| 49 #endif | 22 #endif |
| 50 #endif // OS(POSIX) | 23 #endif // defined(OSPOSIX) |
| 51 | 24 |
| 52 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 25 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| 53 | 26 |
| 54 namespace WTF { | 27 namespace base { |
| 55 | 28 |
| 56 namespace { | 29 namespace { |
| 57 | 30 |
| 58 const size_t kTestMaxAllocation = 4096; | 31 const size_t kTestMaxAllocation = 4096; |
| 59 SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator; | 32 SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator; |
| 60 PartitionAllocatorGeneric genericAllocator; | 33 PartitionAllocatorGeneric genericAllocator; |
| 61 | 34 |
| 62 const size_t kTestAllocSize = 16; | 35 const size_t kTestAllocSize = 16; |
| 63 #if !ENABLE(ASSERT) | 36 #if !DCHECK_IS_ON() |
| 64 const size_t kPointerOffset = 0; | 37 const size_t kPointerOffset = 0; |
| 65 const size_t kExtraAllocSize = 0; | 38 const size_t kExtraAllocSize = 0; |
| 66 #else | 39 #else |
| 67 const size_t kPointerOffset = WTF::kCookieSize; | 40 const size_t kPointerOffset = base::kCookieSize; |
|
Primiano Tucci (use gerrit)
2016/11/22 14:28:33
base:: here and below, already in base.
palmer
2016/11/24 01:05:56
Done.
| |
| 68 const size_t kExtraAllocSize = WTF::kCookieSize * 2; | 41 const size_t kExtraAllocSize = base::kCookieSize * 2; |
| 69 #endif | 42 #endif |
| 70 const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize; | 43 const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize; |
| 71 const size_t kTestBucketIndex = kRealAllocSize >> WTF::kBucketShift; | 44 const size_t kTestBucketIndex = kRealAllocSize >> base::kBucketShift; |
| 72 | 45 |
| 73 const char* typeName = nullptr; | 46 const char* typeName = nullptr; |
| 74 | 47 |
| 75 void TestSetup() { | 48 void TestSetup() { |
| 76 allocator.init(); | 49 allocator.init(); |
| 77 genericAllocator.init(); | 50 genericAllocator.init(); |
| 78 } | 51 } |
| 79 | 52 |
| 80 void TestShutdown() { | 53 void TestShutdown() { |
| 81 // We expect no leaks in the general case. We have a test for leak | 54 // We expect no leaks in the general case. We have a test for leak |
| 82 // detection. | 55 // detection. |
| 83 EXPECT_TRUE(allocator.shutdown()); | 56 EXPECT_TRUE(allocator.shutdown()); |
| 84 EXPECT_TRUE(genericAllocator.shutdown()); | 57 EXPECT_TRUE(genericAllocator.shutdown()); |
| 85 } | 58 } |
| 86 | 59 |
| 87 #if !CPU(64BIT) || OS(POSIX) | 60 #if !CPU(64BIT) || defined(OS_POSIX) |
|
Primiano Tucci (use gerrit)
2016/11/22 14:28:33
defined(ARCH_CPU_64_BITS) and below in this file
palmer
2016/11/24 01:05:56
Done.
| |
| 88 bool SetAddressSpaceLimit() { | 61 bool SetAddressSpaceLimit() { |
| 89 #if !CPU(64BIT) | 62 #if !CPU(64BIT) |
| 90 // 32 bits => address space is limited already. | 63 // 32 bits => address space is limited already. |
| 91 return true; | 64 return true; |
| 92 #elif OS(POSIX) && !OS(MACOSX) | 65 #elif defined(OS_POSIX) && !defined(OS_MACOSX) |
| 93 // Mac will accept RLIMIT_AS changes but it is not enforced. | 66 // Mac will accept RLIMIT_AS changes but it is not enforced. |
| 94 // See https://crbug.com/435269 and rdar://17576114. | 67 // See https://crbug.com/435269 and rdar://17576114. |
| 95 const size_t kAddressSpaceLimit = static_cast<size_t>(4096) * 1024 * 1024; | 68 const size_t kAddressSpaceLimit = static_cast<size_t>(4096) * 1024 * 1024; |
| 96 struct rlimit limit; | 69 struct rlimit limit; |
| 97 if (getrlimit(RLIMIT_AS, &limit) != 0) | 70 if (getrlimit(RLIMIT_AS, &limit) != 0) |
| 98 return false; | 71 return false; |
| 99 if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > kAddressSpaceLimit) { | 72 if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > kAddressSpaceLimit) { |
| 100 limit.rlim_cur = kAddressSpaceLimit; | 73 limit.rlim_cur = kAddressSpaceLimit; |
| 101 if (setrlimit(RLIMIT_AS, &limit) != 0) | 74 if (setrlimit(RLIMIT_AS, &limit) != 0) |
| 102 return false; | 75 return false; |
| 103 } | 76 } |
| 104 return true; | 77 return true; |
| 105 #else | 78 #else |
| 106 return false; | 79 return false; |
| 107 #endif | 80 #endif |
| 108 } | 81 } |
| 109 | 82 |
| 110 bool ClearAddressSpaceLimit() { | 83 bool ClearAddressSpaceLimit() { |
| 111 #if !CPU(64BIT) | 84 #if !CPU(64BIT) |
| 112 return true; | 85 return true; |
| 113 #elif OS(POSIX) | 86 #elif defined(OS_POSIX) |
| 114 struct rlimit limit; | 87 struct rlimit limit; |
| 115 if (getrlimit(RLIMIT_AS, &limit) != 0) | 88 if (getrlimit(RLIMIT_AS, &limit) != 0) |
| 116 return false; | 89 return false; |
| 117 limit.rlim_cur = limit.rlim_max; | 90 limit.rlim_cur = limit.rlim_max; |
| 118 if (setrlimit(RLIMIT_AS, &limit) != 0) | 91 if (setrlimit(RLIMIT_AS, &limit) != 0) |
| 119 return false; | 92 return false; |
| 120 return true; | 93 return true; |
| 121 #else | 94 #else |
| 122 return false; | 95 return false; |
| 123 #endif | 96 #endif |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 for (i = 0; i < numSlots; ++i) { | 136 for (i = 0; i < numSlots; ++i) { |
| 164 partitionFree(ptr + kPointerOffset); | 137 partitionFree(ptr + kPointerOffset); |
| 165 ptr += size; | 138 ptr += size; |
| 166 } | 139 } |
| 167 } | 140 } |
| 168 | 141 |
| 169 void CycleFreeCache(size_t size) { | 142 void CycleFreeCache(size_t size) { |
| 170 size_t realSize = size + kExtraAllocSize; | 143 size_t realSize = size + kExtraAllocSize; |
| 171 size_t bucketIdx = realSize >> kBucketShift; | 144 size_t bucketIdx = realSize >> kBucketShift; |
| 172 PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; | 145 PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; |
| 173 ASSERT(!bucket->activePagesHead->numAllocatedSlots); | 146 DCHECK(!bucket->activePagesHead->numAllocatedSlots); |
| 174 | 147 |
| 175 for (size_t i = 0; i < kMaxFreeableSpans; ++i) { | 148 for (size_t i = 0; i < kMaxFreeableSpans; ++i) { |
| 176 void* ptr = partitionAlloc(allocator.root(), size, typeName); | 149 void* ptr = partitionAlloc(allocator.root(), size, typeName); |
| 177 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots); | 150 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots); |
| 178 partitionFree(ptr); | 151 partitionFree(ptr); |
| 179 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots); | 152 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots); |
| 180 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex); | 153 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex); |
| 181 } | 154 } |
| 182 } | 155 } |
| 183 | 156 |
| 184 void CycleGenericFreeCache(size_t size) { | 157 void CycleGenericFreeCache(size_t size) { |
| 185 for (size_t i = 0; i < kMaxFreeableSpans; ++i) { | 158 for (size_t i = 0; i < kMaxFreeableSpans; ++i) { |
| 186 void* ptr = partitionAllocGeneric(genericAllocator.root(), size, typeName); | 159 void* ptr = partitionAllocGeneric(genericAllocator.root(), size, typeName); |
| 187 PartitionPage* page = | 160 PartitionPage* page = |
| 188 partitionPointerToPage(partitionCookieFreePointerAdjust(ptr)); | 161 partitionPointerToPage(partitionCookieFreePointerAdjust(ptr)); |
| 189 PartitionBucket* bucket = page->bucket; | 162 PartitionBucket* bucket = page->bucket; |
| 190 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots); | 163 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots); |
| 191 partitionFreeGeneric(genericAllocator.root(), ptr); | 164 partitionFreeGeneric(genericAllocator.root(), ptr); |
| 192 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots); | 165 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots); |
| 193 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex); | 166 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex); |
| 194 } | 167 } |
| 195 } | 168 } |
| 196 | 169 |
| 197 void CheckPageInCore(void* ptr, bool inCore) { | 170 void CheckPageInCore(void* ptr, bool inCore) { |
| 198 #if OS(LINUX) | 171 #if defined(OS_LINUX) |
| 199 unsigned char ret; | 172 unsigned char ret; |
| 200 EXPECT_EQ(0, mincore(ptr, kSystemPageSize, &ret)); | 173 EXPECT_EQ(0, mincore(ptr, kSystemPageSize, &ret)); |
| 201 EXPECT_EQ(inCore, ret); | 174 EXPECT_EQ(inCore, ret); |
| 202 #endif | 175 #endif |
| 203 } | 176 } |
| 204 | 177 |
| 205 class MockPartitionStatsDumper : public PartitionStatsDumper { | 178 class MockPartitionStatsDumper : public PartitionStatsDumper { |
| 206 public: | 179 public: |
| 207 MockPartitionStatsDumper() | 180 MockPartitionStatsDumper() |
| 208 : m_totalResidentBytes(0), | 181 : m_totalResidentBytes(0), |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 kGenericSmallestBucket, typeName); | 526 kGenericSmallestBucket, typeName); |
| 554 EXPECT_EQ(ptr, newPtr); | 527 EXPECT_EQ(ptr, newPtr); |
| 555 | 528 |
| 556 // Change the size of the realloc, switching buckets. | 529 // Change the size of the realloc, switching buckets. |
| 557 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, | 530 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, |
| 558 kGenericSmallestBucket + 1, typeName); | 531 kGenericSmallestBucket + 1, typeName); |
| 559 EXPECT_NE(newPtr, ptr); | 532 EXPECT_NE(newPtr, ptr); |
| 560 // Check that the realloc copied correctly. | 533 // Check that the realloc copied correctly. |
| 561 char* newCharPtr = static_cast<char*>(newPtr); | 534 char* newCharPtr = static_cast<char*>(newPtr); |
| 562 EXPECT_EQ(*newCharPtr, 'A'); | 535 EXPECT_EQ(*newCharPtr, 'A'); |
| 563 #if ENABLE(ASSERT) | 536 #if DCHECK_IS_ON() |
| 564 // Subtle: this checks for an old bug where we copied too much from the | 537 // Subtle: this checks for an old bug where we copied too much from the |
| 565 // source of the realloc. The condition can be detected by a trashing of | 538 // source of the realloc. The condition can be detected by a trashing of |
| 566 // the uninitialized value in the space of the upsized allocation. | 539 // the uninitialized value in the space of the upsized allocation. |
| 567 EXPECT_EQ(kUninitializedByte, | 540 EXPECT_EQ(kUninitializedByte, |
| 568 static_cast<unsigned char>(*(newCharPtr + kGenericSmallestBucket))); | 541 static_cast<unsigned char>(*(newCharPtr + kGenericSmallestBucket))); |
| 569 #endif | 542 #endif |
| 570 *newCharPtr = 'B'; | 543 *newCharPtr = 'B'; |
| 571 // The realloc moved. To check that the old allocation was freed, we can | 544 // The realloc moved. To check that the old allocation was freed, we can |
| 572 // do an alloc of the old allocation size and check that the old allocation | 545 // do an alloc of the old allocation size and check that the old allocation |
| 573 // address is at the head of the freelist and reused. | 546 // address is at the head of the freelist and reused. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 partitionFreeGeneric(genericAllocator.root(), ptr3); | 637 partitionFreeGeneric(genericAllocator.root(), ptr3); |
| 665 partitionFreeGeneric(genericAllocator.root(), ptr2); | 638 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 666 // Should be freeable at this point. | 639 // Should be freeable at this point. |
| 667 EXPECT_NE(-1, page->emptyCacheIndex); | 640 EXPECT_NE(-1, page->emptyCacheIndex); |
| 668 EXPECT_EQ(0, page->numAllocatedSlots); | 641 EXPECT_EQ(0, page->numAllocatedSlots); |
| 669 EXPECT_EQ(0, page->numUnprovisionedSlots); | 642 EXPECT_EQ(0, page->numUnprovisionedSlots); |
| 670 void* newPtr = partitionAllocGeneric(genericAllocator.root(), size, typeName); | 643 void* newPtr = partitionAllocGeneric(genericAllocator.root(), size, typeName); |
| 671 EXPECT_EQ(ptr3, newPtr); | 644 EXPECT_EQ(ptr3, newPtr); |
| 672 newPtr = partitionAllocGeneric(genericAllocator.root(), size, typeName); | 645 newPtr = partitionAllocGeneric(genericAllocator.root(), size, typeName); |
| 673 EXPECT_EQ(ptr2, newPtr); | 646 EXPECT_EQ(ptr2, newPtr); |
| 674 #if OS(LINUX) && !ENABLE(ASSERT) | 647 #if defined(OS_LINUX) && !DCHECK_IS_ON() |
| 675 // On Linux, we have a guarantee that freelisting a page should cause its | 648 // On Linux, we have a guarantee that freelisting a page should cause its |
| 676 // contents to be nulled out. We check for null here to detect an bug we | 649 // contents to be nulled out. We check for null here to detect an bug we |
| 677 // had where a large slot size was causing us to not properly free all | 650 // had where a large slot size was causing us to not properly free all |
| 678 // resources back to the system. | 651 // resources back to the system. |
| 679 // We only run the check when asserts are disabled because when they are | 652 // We only run the check when asserts are disabled because when they are |
| 680 // enabled, the allocated area is overwritten with an "uninitialized" | 653 // enabled, the allocated area is overwritten with an "uninitialized" |
| 681 // byte pattern. | 654 // byte pattern. |
| 682 EXPECT_EQ(0, *(reinterpret_cast<char*>(newPtr) + (size - 1))); | 655 EXPECT_EQ(0, *(reinterpret_cast<char*>(newPtr) + (size - 1))); |
| 683 #endif | 656 #endif |
| 684 partitionFreeGeneric(genericAllocator.root(), newPtr); | 657 partitionFreeGeneric(genericAllocator.root(), newPtr); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 800 size_t size = kSystemPageSize - kExtraAllocSize; | 773 size_t size = kSystemPageSize - kExtraAllocSize; |
| 801 EXPECT_EQ(size, partitionAllocActualSize(genericAllocator.root(), size)); | 774 EXPECT_EQ(size, partitionAllocActualSize(genericAllocator.root(), size)); |
| 802 ptr = partitionAllocGeneric(genericAllocator.root(), size, typeName); | 775 ptr = partitionAllocGeneric(genericAllocator.root(), size, typeName); |
| 803 memset(ptr, 'A', size); | 776 memset(ptr, 'A', size); |
| 804 ptr2 = | 777 ptr2 = |
| 805 partitionReallocGeneric(genericAllocator.root(), ptr, size + 1, typeName); | 778 partitionReallocGeneric(genericAllocator.root(), ptr, size + 1, typeName); |
| 806 EXPECT_NE(ptr, ptr2); | 779 EXPECT_NE(ptr, ptr2); |
| 807 char* charPtr2 = static_cast<char*>(ptr2); | 780 char* charPtr2 = static_cast<char*>(ptr2); |
| 808 EXPECT_EQ('A', charPtr2[0]); | 781 EXPECT_EQ('A', charPtr2[0]); |
| 809 EXPECT_EQ('A', charPtr2[size - 1]); | 782 EXPECT_EQ('A', charPtr2[size - 1]); |
| 810 #if ENABLE(ASSERT) | 783 #if DCHECK_IS_ON() |
| 811 EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr2[size])); | 784 EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr2[size])); |
| 812 #endif | 785 #endif |
| 813 | 786 |
| 814 // Test that shrinking an allocation with realloc() also copies everything | 787 // Test that shrinking an allocation with realloc() also copies everything |
| 815 // from the old allocation. | 788 // from the old allocation. |
| 816 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - 1, | 789 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - 1, |
| 817 typeName); | 790 typeName); |
| 818 EXPECT_NE(ptr2, ptr); | 791 EXPECT_NE(ptr2, ptr); |
| 819 char* charPtr = static_cast<char*>(ptr); | 792 char* charPtr = static_cast<char*>(ptr); |
| 820 EXPECT_EQ('A', charPtr[0]); | 793 EXPECT_EQ('A', charPtr[0]); |
| 821 EXPECT_EQ('A', charPtr[size - 2]); | 794 EXPECT_EQ('A', charPtr[size - 2]); |
| 822 #if ENABLE(ASSERT) | 795 #if DCHECK_IS_ON() |
| 823 EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr[size - 1])); | 796 EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr[size - 1])); |
| 824 #endif | 797 #endif |
| 825 | 798 |
| 826 partitionFreeGeneric(genericAllocator.root(), ptr); | 799 partitionFreeGeneric(genericAllocator.root(), ptr); |
| 827 | 800 |
| 828 // Test that shrinking a direct mapped allocation happens in-place. | 801 // Test that shrinking a direct mapped allocation happens in-place. |
| 829 size = kGenericMaxBucketed + 16 * kSystemPageSize; | 802 size = kGenericMaxBucketed + 16 * kSystemPageSize; |
| 830 ptr = partitionAllocGeneric(genericAllocator.root(), size, typeName); | 803 ptr = partitionAllocGeneric(genericAllocator.root(), size, typeName); |
| 831 size_t actualSize = partitionAllocGetSize(ptr); | 804 size_t actualSize = partitionAllocGetSize(ptr); |
| 832 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, | 805 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1259 EXPECT_TRUE(ptr); | 1232 EXPECT_TRUE(ptr); |
| 1260 partitionFreeGeneric(genericAllocator.root(), ptr); | 1233 partitionFreeGeneric(genericAllocator.root(), ptr); |
| 1261 | 1234 |
| 1262 EXPECT_TRUE(bucket->activePagesHead); | 1235 EXPECT_TRUE(bucket->activePagesHead); |
| 1263 EXPECT_TRUE(bucket->emptyPagesHead); | 1236 EXPECT_TRUE(bucket->emptyPagesHead); |
| 1264 EXPECT_TRUE(bucket->decommittedPagesHead); | 1237 EXPECT_TRUE(bucket->decommittedPagesHead); |
| 1265 | 1238 |
| 1266 TestShutdown(); | 1239 TestShutdown(); |
| 1267 } | 1240 } |
| 1268 | 1241 |
| 1269 #if !CPU(64BIT) || OS(POSIX) | 1242 #if !CPU(64BIT) || defined(OS_POSIX) |
| 1270 | 1243 |
| 1271 static void DoReturnNullTest(size_t allocSize) { | 1244 static void DoReturnNullTest(size_t allocSize) { |
| 1272 TestSetup(); | 1245 TestSetup(); |
| 1273 | 1246 |
| 1274 EXPECT_TRUE(SetAddressSpaceLimit()); | 1247 EXPECT_TRUE(SetAddressSpaceLimit()); |
| 1275 | 1248 |
| 1276 // Work out the number of allocations for 6 GB of memory. | 1249 // Work out the number of allocations for 6 GB of memory. |
| 1277 const int numAllocations = (6 * 1024 * 1024) / (allocSize / 1024); | 1250 const int numAllocations = (6 * 1024 * 1024) / (allocSize / 1024); |
| 1278 | 1251 |
| 1279 void** ptrs = reinterpret_cast<void**>(partitionAllocGeneric( | 1252 void** ptrs = reinterpret_cast<void**>(partitionAllocGeneric( |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1312 | 1285 |
| 1313 EXPECT_TRUE(ClearAddressSpaceLimit()); | 1286 EXPECT_TRUE(ClearAddressSpaceLimit()); |
| 1314 | 1287 |
| 1315 TestShutdown(); | 1288 TestShutdown(); |
| 1316 } | 1289 } |
| 1317 | 1290 |
| 1318 // Tests that if an allocation fails in "return null" mode, repeating it doesn't | 1291 // Tests that if an allocation fails in "return null" mode, repeating it doesn't |
| 1319 // crash, and still returns null. The test tries to allocate 6 GB of memory in | 1292 // crash, and still returns null. The test tries to allocate 6 GB of memory in |
| 1320 // 512 kB blocks. On 64-bit POSIX systems, the address space is limited to 4 GB | 1293 // 512 kB blocks. On 64-bit POSIX systems, the address space is limited to 4 GB |
| 1321 // using setrlimit() first. | 1294 // using setrlimit() first. |
| 1322 #if OS(MACOSX) | 1295 #if defined(OS_MACOSX) |
| 1323 #define MAYBE_RepeatedReturnNull DISABLED_RepeatedReturnNull | 1296 #define MAYBE_RepeatedReturnNull DISABLED_RepeatedReturnNull |
| 1324 #else | 1297 #else |
| 1325 #define MAYBE_RepeatedReturnNull RepeatedReturnNull | 1298 #define MAYBE_RepeatedReturnNull RepeatedReturnNull |
| 1326 #endif | 1299 #endif |
| 1327 TEST(PartitionAllocTest, MAYBE_RepeatedReturnNull) { | 1300 TEST(PartitionAllocTest, MAYBE_RepeatedReturnNull) { |
| 1328 // A single-slot but non-direct-mapped allocation size. | 1301 // A single-slot but non-direct-mapped allocation size. |
| 1329 DoReturnNullTest(512 * 1024); | 1302 DoReturnNullTest(512 * 1024); |
| 1330 } | 1303 } |
| 1331 | 1304 |
| 1332 // Another "return null" test but for larger, direct-mapped allocations. | 1305 // Another "return null" test but for larger, direct-mapped allocations. |
| 1333 #if OS(MACOSX) | 1306 #if defined(OS_MACOSX) |
| 1334 #define MAYBE_RepeatedReturnNullDirect DISABLED_RepeatedReturnNullDirect | 1307 #define MAYBE_RepeatedReturnNullDirect DISABLED_RepeatedReturnNullDirect |
| 1335 #else | 1308 #else |
| 1336 #define MAYBE_RepeatedReturnNullDirect RepeatedReturnNullDirect | 1309 #define MAYBE_RepeatedReturnNullDirect RepeatedReturnNullDirect |
| 1337 #endif | 1310 #endif |
| 1338 TEST(PartitionAllocTest, MAYBE_RepeatedReturnNullDirect) { | 1311 TEST(PartitionAllocTest, MAYBE_RepeatedReturnNullDirect) { |
| 1339 // A direct-mapped allocation size. | 1312 // A direct-mapped allocation size. |
| 1340 DoReturnNullTest(256 * 1024 * 1024); | 1313 DoReturnNullTest(256 * 1024 * 1024); |
| 1341 } | 1314 } |
| 1342 | 1315 |
| 1343 #endif // !CPU(64BIT) || OS(POSIX) | 1316 #endif // !CPU(64BIT) || defined(OS_POSIX) |
| 1344 | 1317 |
| 1345 #if !OS(ANDROID) | 1318 #if !defined(OS_ANDROID) |
| 1346 | 1319 |
| 1347 // Make sure that malloc(-1) dies. | 1320 // Make sure that malloc(-1) dies. |
| 1348 // In the past, we had an integer overflow that would alias malloc(-1) to | 1321 // In the past, we had an integer overflow that would alias malloc(-1) to |
| 1349 // malloc(0), which is not good. | 1322 // malloc(0), which is not good. |
| 1350 TEST(PartitionAllocDeathTest, LargeAllocs) { | 1323 TEST(PartitionAllocDeathTest, LargeAllocs) { |
| 1351 TestSetup(); | 1324 TestSetup(); |
| 1352 // Largest alloc. | 1325 // Largest alloc. |
| 1353 EXPECT_DEATH(partitionAllocGeneric(genericAllocator.root(), | 1326 EXPECT_DEATH(partitionAllocGeneric(genericAllocator.root(), |
| 1354 static_cast<size_t>(-1), typeName), | 1327 static_cast<size_t>(-1), typeName), |
| 1355 ""); | 1328 ""); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1445 EXPECT_TRUE(ptr); | 1418 EXPECT_TRUE(ptr); |
| 1446 char* badPtr = reinterpret_cast<char*>(ptr) + kPartitionPageSize; | 1419 char* badPtr = reinterpret_cast<char*>(ptr) + kPartitionPageSize; |
| 1447 | 1420 |
| 1448 EXPECT_DEATH(partitionFreeGeneric(genericAllocator.root(), badPtr), ""); | 1421 EXPECT_DEATH(partitionFreeGeneric(genericAllocator.root(), badPtr), ""); |
| 1449 | 1422 |
| 1450 partitionFreeGeneric(genericAllocator.root(), ptr); | 1423 partitionFreeGeneric(genericAllocator.root(), ptr); |
| 1451 | 1424 |
| 1452 TestShutdown(); | 1425 TestShutdown(); |
| 1453 } | 1426 } |
| 1454 | 1427 |
| 1455 #endif // !OS(ANDROID) | 1428 #endif // !defined(OS_ANDROID) |
| 1456 | 1429 |
| 1457 // Tests that partitionDumpStatsGeneric and partitionDumpStats runs without | 1430 // Tests that partitionDumpStatsGeneric and partitionDumpStats runs without |
| 1458 // crashing and returns non zero values when memory is allocated. | 1431 // crashing and returns non zero values when memory is allocated. |
| 1459 TEST(PartitionAllocTest, DumpMemoryStats) { | 1432 TEST(PartitionAllocTest, DumpMemoryStats) { |
| 1460 TestSetup(); | 1433 TestSetup(); |
| 1461 { | 1434 { |
| 1462 void* ptr = partitionAlloc(allocator.root(), kTestAllocSize, typeName); | 1435 void* ptr = partitionAlloc(allocator.root(), kTestAllocSize, typeName); |
| 1463 MockPartitionStatsDumper mockStatsDumper; | 1436 MockPartitionStatsDumper mockStatsDumper; |
| 1464 partitionDumpStats(allocator.root(), "mock_allocator", | 1437 partitionDumpStats(allocator.root(), "mock_allocator", |
| 1465 false /* detailed dump */, &mockStatsDumper); | 1438 false /* detailed dump */, &mockStatsDumper); |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2106 | 2079 |
| 2107 EXPECT_FALSE(page->freelistHead); | 2080 EXPECT_FALSE(page->freelistHead); |
| 2108 | 2081 |
| 2109 partitionFreeGeneric(genericAllocator.root(), ptr1); | 2082 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 2110 partitionFreeGeneric(genericAllocator.root(), ptr2); | 2083 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 2111 } | 2084 } |
| 2112 | 2085 |
| 2113 TestShutdown(); | 2086 TestShutdown(); |
| 2114 } | 2087 } |
| 2115 | 2088 |
| 2116 } // namespace WTF | 2089 TEST(PartitionAllocTest, CLZWorks) { |
| 2090 EXPECT_EQ(32u, countLeadingZeros32(0u)); | |
| 2091 EXPECT_EQ(31u, countLeadingZeros32(1u)); | |
| 2092 EXPECT_EQ(1u, countLeadingZeros32(1u << 30)); | |
| 2093 EXPECT_EQ(0u, countLeadingZeros32(1u << 31)); | |
| 2094 | |
| 2095 #if CPU(64BIT) | |
| 2096 EXPECT_EQ(64u, countLeadingZerosSizet(0ull)); | |
| 2097 EXPECT_EQ(63u, countLeadingZerosSizet(1ull)); | |
| 2098 EXPECT_EQ(32u, countLeadingZerosSizet(1ull << 31)); | |
| 2099 EXPECT_EQ(1u, countLeadingZerosSizet(1ull << 62)); | |
| 2100 EXPECT_EQ(0u, countLeadingZerosSizet(1ull << 63)); | |
| 2101 #else | |
| 2102 EXPECT_EQ(32u, countLeadingZerosSizet(0u)); | |
| 2103 EXPECT_EQ(31u, countLeadingZerosSizet(1u)); | |
| 2104 EXPECT_EQ(1u, countLeadingZerosSizet(1u << 30)); | |
| 2105 EXPECT_EQ(0u, countLeadingZerosSizet(1u << 31)); | |
| 2106 #endif | |
| 2107 } | |
| 2108 | |
| 2109 } // namespace base | |
| 2117 | 2110 |
| 2118 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 2111 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| OLD | NEW |