Changeset 208690 in webkit
- Timestamp:
- Nov 14, 2016, 10:04:06 AM (9 years ago)
- Location:
- trunk/Source
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r208643 r208690 1 2016-11-13 Mark Lam <mark.lam@apple.com> 2 3 Add debugging facility to limit the max single allocation size. 4 https://bugs.webkit.org/show_bug.cgi?id=164681 5 6 Reviewed by Keith Miller. 7 8 Added JSC option to set FastMalloc's maxSingleAllocationSize for testing purposes. 9 This option is only available on Debug builds. 10 11 * runtime/Options.cpp: 12 (JSC::Options::isAvailable): 13 (JSC::recomputeDependentOptions): 14 * runtime/Options.h: 15 1 16 2016-11-12 Joseph Pecoraro <pecoraro@apple.com> 2 17 -
trunk/Source/JavaScriptCore/runtime/Options.cpp
r207491 r208690 137 137 return true; 138 138 #endif 139 #if !defined(NDEBUG) 140 if (id == maxSingleAllocationSizeID) 141 return true; 142 #endif 139 143 return false; 140 144 } … … 396 400 #if ENABLE(LLINT_STATS) 397 401 LLInt::Data::loadStats(); 402 #endif 403 #if !defined(NDEBUG) 404 if (Options::maxSingleAllocationSize()) 405 fastSetMaxSingleAllocationSize(Options::maxSingleAllocationSize()); 406 else 407 fastSetMaxSingleAllocationSize(std::numeric_limits<size_t>::max()); 398 408 #endif 399 409 } -
trunk/Source/JavaScriptCore/runtime/Options.h
r208563 r208690 324 324 v(bool, useImmortalObjects, false, Normal, "debugging option to keep all objects alive forever") \ 325 325 v(bool, dumpObjectStatistics, false, Normal, nullptr) \ 326 v(unsigned, maxSingleAllocationSize, 0, Configurable, "debugging option to limit individual allocations to a max size (0 = limit not set, N = limit size in bytes)") \ 326 327 \ 327 328 v(gcLogLevel, logGC, GCLogging::None, Normal, "debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)") \ -
trunk/Source/WTF/ChangeLog
r208670 r208690 1 2016-11-13 Mark Lam <mark.lam@apple.com> 2 3 Add debugging facility to limit the max single allocation size. 4 https://bugs.webkit.org/show_bug.cgi?id=164681 5 6 Reviewed by Keith Miller. 7 8 This is useful for simulating memory allocation failures on resource constraint 9 devices for testing purposes. 10 11 This facility is only conditionally compiled in on debug builds. It does not 12 have any burden on release builds at all. When in use, the max single allocation 13 size limit applies to individual allocations. For malloc (and similar), the 14 allocation will crash in FastMalloc if the requested size exceeds the set max 15 single allocation size. For tryMalloc (and similar), the allocation returns 16 nullptr if the requested size exceeds the set max single allocation size. The 17 max single allocation size is set to std::numeric_limit<size_t>::max() by default 18 (i.e. when not set and no limit is in effect). 19 20 Also fixed non-bmalloc versions of fastAlignedMalloc() to crash when allocation 21 fails. 22 23 * wtf/FastMalloc.cpp: 24 (WTF::fastSetMaxSingleAllocationSize): 25 (WTF::fastAlignedMalloc): 26 (WTF::tryFastAlignedMalloc): 27 (WTF::tryFastMalloc): 28 (WTF::fastMalloc): 29 (WTF::tryFastCalloc): 30 (WTF::fastCalloc): 31 (WTF::fastRealloc): 32 * wtf/FastMalloc.h: 33 1 34 2016-11-13 JF Bastien <jfbastien@apple.com> 2 35 -
trunk/Source/WTF/wtf/FastMalloc.cpp
r205462 r208690 47 47 namespace WTF { 48 48 49 #if !defined(NDEBUG) 50 namespace { 51 size_t maxSingleAllocationSize = std::numeric_limits<size_t>::max(); 52 }; 53 54 void fastSetMaxSingleAllocationSize(size_t size) 55 { 56 maxSingleAllocationSize = size; 57 } 58 59 #define ASSERT_IS_WITHIN_LIMIT(size) do { \ 60 size_t size__ = (size); \ 61 ASSERT_WITH_MESSAGE((size__) <= maxSingleAllocationSize, "Requested size (%zu) exceeds max single allocation size set for testing (%zu)", (size__), maxSingleAllocationSize); \ 62 } while (false) 63 64 #define FAIL_IF_EXCEEDS_LIMIT(size) do { \ 65 if (UNLIKELY((size) > maxSingleAllocationSize)) \ 66 return nullptr; \ 67 } while (false) 68 69 #else // !defined(NDEBUG) 70 71 #define ASSERT_IS_WITHIN_LIMIT(size) 72 #define FAIL_IF_EXCEEDS_LIMIT(size) 73 74 #endif // !defined(NDEBUG) 75 49 76 void* fastZeroedMalloc(size_t n) 50 77 { … … 99 126 void* fastAlignedMalloc(size_t alignment, size_t size) 100 127 { 128 ASSERT_IS_WITHIN_LIMIT(size); 129 void* p = _aligned_malloc(size, alignment); 130 if (UNLIKELY(!p)) 131 CRASH(); 132 return p; 133 } 134 135 void* tryFastAlignedMalloc(size_t alignment, size_t size) 136 { 137 FAIL_IF_EXCEEDS_LIMIT(size); 101 138 return _aligned_malloc(size, alignment); 102 139 } 103 140 141 void fastAlignedFree(void* p) 142 { 143 _aligned_free(p); 144 } 145 146 #else 147 148 void* fastAlignedMalloc(size_t alignment, size_t size) 149 { 150 ASSERT_IS_WITHIN_LIMIT(size); 151 void* p = nullptr; 152 posix_memalign(&p, alignment, size); 153 if (UNLIKELY(!p)) 154 CRASH(); 155 return p; 156 } 157 104 158 void* tryFastAlignedMalloc(size_t alignment, size_t size) 105 159 { 106 return _aligned_malloc(size, alignment); 107 } 108 109 void fastAlignedFree(void* p) 110 { 111 _aligned_free(p); 112 } 113 114 #else 115 116 void* fastAlignedMalloc(size_t alignment, size_t size) 117 { 160 FAIL_IF_EXCEEDS_LIMIT(size); 118 161 void* p = nullptr; 119 162 posix_memalign(&p, alignment, size); … … 121 164 } 122 165 123 void* tryFastAlignedMalloc(size_t alignment, size_t size)124 {125 void* p = nullptr;126 posix_memalign(&p, alignment, size);127 return p;128 }129 130 166 void fastAlignedFree(void* p) 131 167 { … … 137 173 TryMallocReturnValue tryFastMalloc(size_t n) 138 174 { 175 FAIL_IF_EXCEEDS_LIMIT(n); 139 176 return malloc(n); 140 177 } … … 142 179 void* fastMalloc(size_t n) 143 180 { 181 ASSERT_IS_WITHIN_LIMIT(n); 144 182 void* result = malloc(n); 145 183 if (!result) … … 151 189 TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size) 152 190 { 191 FAIL_IF_EXCEEDS_LIMIT(n_elements * element_size); 153 192 return calloc(n_elements, element_size); 154 193 } … … 156 195 void* fastCalloc(size_t n_elements, size_t element_size) 157 196 { 197 ASSERT_IS_WITHIN_LIMIT(n_elements * element_size); 158 198 void* result = calloc(n_elements, element_size); 159 199 if (!result) … … 170 210 void* fastRealloc(void* p, size_t n) 171 211 { 212 ASSERT_IS_WITHIN_LIMIT(n); 172 213 void* result = realloc(p, n); 173 214 if (!result) … … 212 253 void* fastMalloc(size_t size) 213 254 { 255 ASSERT_IS_WITHIN_LIMIT(size); 214 256 return bmalloc::api::malloc(size); 215 257 } … … 217 259 void* fastCalloc(size_t numElements, size_t elementSize) 218 260 { 261 ASSERT_IS_WITHIN_LIMIT(numElements * elementSize); 219 262 Checked<size_t> checkedSize = elementSize; 220 263 checkedSize *= numElements; … … 227 270 void* fastRealloc(void* object, size_t size) 228 271 { 272 ASSERT_IS_WITHIN_LIMIT(size); 229 273 return bmalloc::api::realloc(object, size); 230 274 } … … 250 294 void* fastAlignedMalloc(size_t alignment, size_t size) 251 295 { 296 ASSERT_IS_WITHIN_LIMIT(size); 252 297 return bmalloc::api::memalign(alignment, size); 253 298 } … … 255 300 void* tryFastAlignedMalloc(size_t alignment, size_t size) 256 301 { 302 FAIL_IF_EXCEEDS_LIMIT(size); 257 303 return bmalloc::api::tryMemalign(alignment, size); 258 304 } … … 265 311 TryMallocReturnValue tryFastMalloc(size_t size) 266 312 { 313 FAIL_IF_EXCEEDS_LIMIT(size); 267 314 return bmalloc::api::tryMalloc(size); 268 315 } … … 270 317 TryMallocReturnValue tryFastCalloc(size_t numElements, size_t elementSize) 271 318 { 319 FAIL_IF_EXCEEDS_LIMIT(numElements * elementSize); 272 320 Checked<size_t, RecordOverflow> checkedSize = elementSize; 273 321 checkedSize *= numElements; -
trunk/Source/WTF/wtf/FastMalloc.h
r205462 r208690 27 27 28 28 namespace WTF { 29 30 #if !defined(NDEBUG) 31 void fastSetMaxSingleAllocationSize(size_t); 32 #endif 29 33 30 34 class TryMallocReturnValue { … … 103 107 } // namespace WTF 104 108 109 #if !defined(NDEBUG) 110 using WTF::fastSetMaxSingleAllocationSize; 111 #endif 112 105 113 using WTF::isFastMallocEnabled; 106 114 using WTF::fastCalloc;
Note:
See TracChangeset
for help on using the changeset viewer.