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 14 matching lines...) Expand all Loading... | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "wtf/PartitionAlloc.h" | 32 #include "wtf/PartitionAlloc.h" |
33 | 33 |
34 #include "wtf/BitwiseOperations.h" | 34 #include "wtf/BitwiseOperations.h" |
35 #include "wtf/CPU.h" | |
35 #include "wtf/OwnPtr.h" | 36 #include "wtf/OwnPtr.h" |
36 #include "wtf/PassOwnPtr.h" | 37 #include "wtf/PassOwnPtr.h" |
37 #include <gtest/gtest.h> | 38 #include <gtest/gtest.h> |
38 #include <stdlib.h> | 39 #include <stdlib.h> |
39 #include <string.h> | 40 #include <string.h> |
40 | 41 |
41 #if OS(POSIX) | 42 #if OS(POSIX) |
42 #include <sys/mman.h> | 43 #include <sys/mman.h> |
44 #include <sys/resource.h> | |
45 #include <sys/time.h> | |
43 | 46 |
44 #ifndef MAP_ANONYMOUS | 47 #ifndef MAP_ANONYMOUS |
45 #define MAP_ANONYMOUS MAP_ANON | 48 #define MAP_ANONYMOUS MAP_ANON |
46 #endif | 49 #endif |
47 #endif // OS(POSIX) | 50 #endif // OS(POSIX) |
48 | 51 |
49 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 52 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
50 | 53 |
51 namespace { | 54 namespace { |
52 | 55 |
(...skipping 25 matching lines...) Expand all Loading... | |
78 // bitrotted because no test calls it. | 81 // bitrotted because no test calls it. |
79 partitionDumpStats(*allocator.root()); | 82 partitionDumpStats(*allocator.root()); |
80 #endif | 83 #endif |
81 | 84 |
82 // We expect no leaks in the general case. We have a test for leak | 85 // We expect no leaks in the general case. We have a test for leak |
83 // detection. | 86 // detection. |
84 EXPECT_TRUE(allocator.shutdown()); | 87 EXPECT_TRUE(allocator.shutdown()); |
85 EXPECT_TRUE(genericAllocator.shutdown()); | 88 EXPECT_TRUE(genericAllocator.shutdown()); |
86 } | 89 } |
87 | 90 |
91 static bool SetAddressSpaceLimit() | |
92 { | |
93 #if !CPU(64BIT) | |
94 // 32 bits => address space is limited already. | |
95 return true; | |
96 #elif OS(POSIX) | |
97 const size_t kAddressSpaceLimit = static_cast<size_t>(4096) * 1024 * 1024; | |
98 struct rlimit limit; | |
99 if (getrlimit(RLIMIT_AS, &limit) != 0) | |
100 return false; | |
101 if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > kAddressSpaceLimit) { | |
102 limit.rlim_cur = kAddressSpaceLimit; | |
103 if (setrlimit(RLIMIT_AS, &limit) != 0) | |
104 return false; | |
105 } | |
106 return true; | |
107 #else | |
108 return false; | |
Nico
2015/08/08 19:46:50
cevans: I found this pretty confusing – DoReturnNu
| |
109 #endif | |
110 } | |
111 | |
112 static bool ClearAddressSpaceLimit() | |
113 { | |
114 #if !CPU(64BIT) | |
115 return true; | |
116 #elif OS(POSIX) | |
117 struct rlimit limit; | |
118 if (getrlimit(RLIMIT_AS, &limit) != 0) | |
119 return false; | |
120 limit.rlim_cur = limit.rlim_max; | |
121 if (setrlimit(RLIMIT_AS, &limit) != 0) | |
122 return false; | |
123 return true; | |
124 #else | |
125 return false; | |
126 #endif | |
127 } | |
128 | |
88 static WTF::PartitionPage* GetFullPage(size_t size) | 129 static WTF::PartitionPage* GetFullPage(size_t size) |
89 { | 130 { |
90 size_t realSize = size + kExtraAllocSize; | 131 size_t realSize = size + kExtraAllocSize; |
91 size_t bucketIdx = realSize >> WTF::kBucketShift; | 132 size_t bucketIdx = realSize >> WTF::kBucketShift; |
92 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; | 133 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; |
93 size_t numSlots = (bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize) / realSize; | 134 size_t numSlots = (bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize) / realSize; |
94 void* first = 0; | 135 void* first = 0; |
95 void* last = 0; | 136 void* last = 0; |
96 size_t i; | 137 size_t i; |
97 for (i = 0; i < numSlots; ++i) { | 138 for (i = 0; i < numSlots; ++i) { |
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1090 ptr = partitionAllocGeneric(genericAllocator.root(), size); | 1131 ptr = partitionAllocGeneric(genericAllocator.root(), size); |
1091 EXPECT_TRUE(ptr); | 1132 EXPECT_TRUE(ptr); |
1092 partitionFreeGeneric(genericAllocator.root(), ptr); | 1133 partitionFreeGeneric(genericAllocator.root(), ptr); |
1093 | 1134 |
1094 EXPECT_TRUE(bucket->activePagesHead); | 1135 EXPECT_TRUE(bucket->activePagesHead); |
1095 EXPECT_TRUE(bucket->freePagesHead); | 1136 EXPECT_TRUE(bucket->freePagesHead); |
1096 | 1137 |
1097 TestShutdown(); | 1138 TestShutdown(); |
1098 } | 1139 } |
1099 | 1140 |
1141 #if !CPU(64BIT) || OS(POSIX) | |
1142 | |
1143 // Tests that if an allocation fails in "return null" mode, repeating it doesn't | |
1144 // crash, and still returns null. The test tries to allocate 6 GB of memory in | |
1145 // 512 kB blocks. On 64-bit POSIX systems, the address space is limited to 4 GB | |
1146 // using setrlimit() first. | |
1147 TEST(PartitionAllocTest, RepeatedReturnNull) | |
1148 { | |
1149 TestSetup(); | |
1150 | |
1151 EXPECT_TRUE(SetAddressSpaceLimit()); | |
1152 | |
1153 // 512 kB x 12288 == 6 GB | |
1154 const size_t blockSize = 512 * 1024; | |
1155 const int numAllocations = 12288; | |
1156 | |
1157 void* ptrs[numAllocations]; | |
1158 int i; | |
1159 | |
1160 for (i = 0; i < numAllocations; ++i) { | |
1161 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), WTF::Parti tionAllocReturnNull, blockSize); | |
1162 if (!ptrs[i]) { | |
1163 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), WTF::P artitionAllocReturnNull, blockSize); | |
1164 EXPECT_FALSE(ptrs[i]); | |
1165 break; | |
1166 } | |
1167 } | |
1168 | |
1169 // We shouldn't succeed in allocating all 6 GB of memory. If we do, then | |
1170 // we're not actually testing anything here. | |
1171 EXPECT_LT(i, numAllocations); | |
1172 | |
1173 // Free, reallocate and free again each block we allocated. We do this to | |
1174 // check that freeing memory also works correctly after a failed allocation. | |
1175 for (--i; i >= 0; --i) { | |
1176 partitionFreeGeneric(genericAllocator.root(), ptrs[i]); | |
1177 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), WTF::Parti tionAllocReturnNull, blockSize); | |
1178 EXPECT_TRUE(ptrs[i]); | |
1179 partitionFreeGeneric(genericAllocator.root(), ptrs[i]); | |
1180 } | |
1181 | |
1182 EXPECT_TRUE(ClearAddressSpaceLimit()); | |
1183 | |
1184 TestShutdown(); | |
1185 } | |
1186 | |
1187 #endif // !CPU(64BIT) || OS(POSIX) | |
1188 | |
1100 #if !OS(ANDROID) | 1189 #if !OS(ANDROID) |
1101 | 1190 |
1102 // Make sure that malloc(-1) dies. | 1191 // Make sure that malloc(-1) dies. |
1103 // In the past, we had an integer overflow that would alias malloc(-1) to | 1192 // In the past, we had an integer overflow that would alias malloc(-1) to |
1104 // malloc(0), which is not good. | 1193 // malloc(0), which is not good. |
1105 TEST(PartitionAllocDeathTest, LargeAllocs) | 1194 TEST(PartitionAllocDeathTest, LargeAllocs) |
1106 { | 1195 { |
1107 TestSetup(); | 1196 TestSetup(); |
1108 // Largest alloc. | 1197 // Largest alloc. |
1109 EXPECT_DEATH(partitionAllocGeneric(genericAllocator.root(), static_cast<size _t>(-1)), ""); | 1198 EXPECT_DEATH(partitionAllocGeneric(genericAllocator.root(), static_cast<size _t>(-1)), ""); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1189 EXPECT_EQ(32u, WTF::countLeadingZerosSizet(0u)); | 1278 EXPECT_EQ(32u, WTF::countLeadingZerosSizet(0u)); |
1190 EXPECT_EQ(31u, WTF::countLeadingZerosSizet(1u)); | 1279 EXPECT_EQ(31u, WTF::countLeadingZerosSizet(1u)); |
1191 EXPECT_EQ(1u, WTF::countLeadingZerosSizet(1u << 30)); | 1280 EXPECT_EQ(1u, WTF::countLeadingZerosSizet(1u << 30)); |
1192 EXPECT_EQ(0u, WTF::countLeadingZerosSizet(1u << 31)); | 1281 EXPECT_EQ(0u, WTF::countLeadingZerosSizet(1u << 31)); |
1193 #endif | 1282 #endif |
1194 } | 1283 } |
1195 | 1284 |
1196 } // namespace | 1285 } // namespace |
1197 | 1286 |
1198 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 1287 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
OLD | NEW |