Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: Source/wtf/PartitionAllocTest.cpp

Issue 645223007: PartitionAlloc: Leave bucket in valid state when allocation fails (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: avoid integer overflow on 32-bit systems Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/wtf/PartitionAlloc.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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)
OLDNEW
« no previous file with comments | « Source/wtf/PartitionAlloc.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698