| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 // Double precision floats are more efficient when 8 byte aligned, so we 8 byte | 60 // Double precision floats are more efficient when 8 byte aligned, so we 8 byte |
| 61 // align all allocations even on 32 bit. | 61 // align all allocations even on 32 bit. |
| 62 const size_t allocationGranularity = 8; | 62 const size_t allocationGranularity = 8; |
| 63 const size_t allocationMask = allocationGranularity - 1; | 63 const size_t allocationMask = allocationGranularity - 1; |
| 64 const size_t objectStartBitMapSize = (blinkPageSize + ((8 * allocationGranularit
y) - 1)) / (8 * allocationGranularity); | 64 const size_t objectStartBitMapSize = (blinkPageSize + ((8 * allocationGranularit
y) - 1)) / (8 * allocationGranularity); |
| 65 const size_t reservedForObjectBitMap = ((objectStartBitMapSize + allocationMask)
& ~allocationMask); | 65 const size_t reservedForObjectBitMap = ((objectStartBitMapSize + allocationMask)
& ~allocationMask); |
| 66 const size_t maxHeapObjectSizeLog2 = 27; | 66 const size_t maxHeapObjectSizeLog2 = 27; |
| 67 const size_t maxHeapObjectSize = 1 << maxHeapObjectSizeLog2; | 67 const size_t maxHeapObjectSize = 1 << maxHeapObjectSizeLog2; |
| 68 const size_t largeObjectSizeThreshold = blinkPageSize / 2; | 68 const size_t largeObjectSizeThreshold = blinkPageSize / 2; |
| 69 | 69 |
| 70 // A zap value used for freed memory that is allowed to be added to the free | 70 const uint8_t freelistZapValue = 42; |
| 71 // list in the next addToFreeList(). | 71 const uint8_t finalizedZapValue = 24; |
| 72 const uint8_t reuseAllowedZapValue = 0x2a; | |
| 73 // A zap value used for freed memory that is forbidden to be added to the free | |
| 74 // list in the next addToFreeList(). | |
| 75 const uint8_t reuseForbiddenZapValue = 0x2c; | |
| 76 // The orphaned zap value must be zero in the lowest bits to allow for using | 72 // The orphaned zap value must be zero in the lowest bits to allow for using |
| 77 // the mark bit when tracing. | 73 // the mark bit when tracing. |
| 78 const uint8_t orphanedZapValue = 240; | 74 const uint8_t orphanedZapValue = 240; |
| 75 // A zap value for vtables should be < 4K to ensure it cannot be |
| 76 // used for dispatch. |
| 77 static const intptr_t zappedVTable = 0xd0d; |
| 79 | 78 |
| 80 // In non-production builds, memory is zapped when it's freed. The zapped | 79 #if defined(ADDRESS_SANITIZER) |
| 81 // memory is zeroed out when the memory is reused in Heap::allocateObject(). | 80 const size_t asanMagic = 0xabefeed0; |
| 82 // In production builds, memory is not zapped (for performance). The memory | 81 const size_t asanDeferMemoryReuseCount = 2; |
| 83 // is just zeroed out when it is added to the free list. | 82 const size_t asanDeferMemoryReuseMask = 0x3; |
| 83 #endif |
| 84 |
| 84 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) | 85 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
| 85 #define FILL_ZERO_IF_PRODUCTION(address, size) FreeList::zapFreedMemory(address,
size) | 86 #define FILL_ZERO_IF_PRODUCTION(address, size) do { } while (false) |
| 86 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) memset((address), 0, (size)) | 87 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) memset((address), 0, (size)) |
| 87 #else | 88 #else |
| 88 #define FILL_ZERO_IF_PRODUCTION(address, size) memset((address), 0, (size)) | 89 #define FILL_ZERO_IF_PRODUCTION(address, size) memset((address), 0, (size)) |
| 89 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) do { } while (false) | 90 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) do { } while (false) |
| 90 #endif | 91 #endif |
| 91 | 92 |
| 92 class CallbackStack; | 93 class CallbackStack; |
| 93 class FreePagePool; | 94 class FreePagePool; |
| 94 class NormalPageHeap; | 95 class NormalPageHeap; |
| 95 class OrphanedPagePool; | 96 class OrphanedPagePool; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 #endif | 243 #endif |
| 243 }; | 244 }; |
| 244 | 245 |
| 245 class FreeListEntry final : public HeapObjectHeader { | 246 class FreeListEntry final : public HeapObjectHeader { |
| 246 public: | 247 public: |
| 247 NO_SANITIZE_ADDRESS | 248 NO_SANITIZE_ADDRESS |
| 248 explicit FreeListEntry(size_t size) | 249 explicit FreeListEntry(size_t size) |
| 249 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) | 250 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) |
| 250 , m_next(nullptr) | 251 , m_next(nullptr) |
| 251 { | 252 { |
| 252 #if ENABLE(ASSERT) | 253 #if ENABLE(ASSERT) && !defined(ADDRESS_SANITIZER) |
| 254 // Zap free area with asterisks, aka 0x2a2a2a2a. |
| 255 // For ASan don't zap since we keep accounting in the freelist entry. |
| 256 for (size_t i = sizeof(*this); i < size; ++i) |
| 257 reinterpret_cast<Address>(this)[i] = freelistZapValue; |
| 253 ASSERT(size >= sizeof(HeapObjectHeader)); | 258 ASSERT(size >= sizeof(HeapObjectHeader)); |
| 254 zapMagic(); | 259 zapMagic(); |
| 255 #endif | 260 #endif |
| 256 } | 261 } |
| 257 | 262 |
| 258 Address address() { return reinterpret_cast<Address>(this); } | 263 Address address() { return reinterpret_cast<Address>(this); } |
| 259 | 264 |
| 260 NO_SANITIZE_ADDRESS | 265 NO_SANITIZE_ADDRESS |
| 261 void unlink(FreeListEntry** prevNext) | 266 void unlink(FreeListEntry** prevNext) |
| 262 { | 267 { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 274 NO_SANITIZE_ADDRESS | 279 NO_SANITIZE_ADDRESS |
| 275 FreeListEntry* next() const { return m_next; } | 280 FreeListEntry* next() const { return m_next; } |
| 276 | 281 |
| 277 NO_SANITIZE_ADDRESS | 282 NO_SANITIZE_ADDRESS |
| 278 void append(FreeListEntry* next) | 283 void append(FreeListEntry* next) |
| 279 { | 284 { |
| 280 ASSERT(!m_next); | 285 ASSERT(!m_next); |
| 281 m_next = next; | 286 m_next = next; |
| 282 } | 287 } |
| 283 | 288 |
| 289 #if defined(ADDRESS_SANITIZER) |
| 290 NO_SANITIZE_ADDRESS |
| 291 bool shouldAddToFreeList() |
| 292 { |
| 293 // Init if not already magic. |
| 294 if ((m_asanMagic & ~asanDeferMemoryReuseMask) != asanMagic) { |
| 295 m_asanMagic = asanMagic | asanDeferMemoryReuseCount; |
| 296 return false; |
| 297 } |
| 298 // Decrement if count part of asanMagic > 0. |
| 299 if (m_asanMagic & asanDeferMemoryReuseMask) |
| 300 m_asanMagic--; |
| 301 return !(m_asanMagic & asanDeferMemoryReuseMask); |
| 302 } |
| 303 #endif |
| 304 |
| 284 private: | 305 private: |
| 285 FreeListEntry* m_next; | 306 FreeListEntry* m_next; |
| 307 #if defined(ADDRESS_SANITIZER) |
| 308 unsigned m_asanMagic; |
| 309 #endif |
| 286 }; | 310 }; |
| 287 | 311 |
| 288 // Blink heap pages are set up with a guard page before and after the payload. | 312 // Blink heap pages are set up with a guard page before and after the payload. |
| 289 inline size_t blinkPagePayloadSize() | 313 inline size_t blinkPagePayloadSize() |
| 290 { | 314 { |
| 291 return blinkPageSize - 2 * WTF::kSystemPageSize; | 315 return blinkPageSize - 2 * WTF::kSystemPageSize; |
| 292 } | 316 } |
| 293 | 317 |
| 294 // Blink heap pages are aligned to the Blink heap page size. | 318 // Blink heap pages are aligned to the Blink heap page size. |
| 295 // Therefore, the start of a Blink page can be obtained by | 319 // Therefore, the start of a Blink page can be obtained by |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 struct PerBucketFreeListStats { | 654 struct PerBucketFreeListStats { |
| 631 size_t entryCount; | 655 size_t entryCount; |
| 632 size_t freeSize; | 656 size_t freeSize; |
| 633 | 657 |
| 634 PerBucketFreeListStats() : entryCount(0), freeSize(0) { } | 658 PerBucketFreeListStats() : entryCount(0), freeSize(0) { } |
| 635 }; | 659 }; |
| 636 | 660 |
| 637 void getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& totalSiz
e) const; | 661 void getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& totalSiz
e) const; |
| 638 #endif | 662 #endif |
| 639 | 663 |
| 640 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) | |
| 641 static void zapFreedMemory(Address, size_t); | |
| 642 #endif | |
| 643 | |
| 644 private: | 664 private: |
| 645 int m_biggestFreeListIndex; | 665 int m_biggestFreeListIndex; |
| 646 | 666 |
| 647 // All FreeListEntries in the nth list have size >= 2^n. | 667 // All FreeListEntries in the nth list have size >= 2^n. |
| 648 FreeListEntry* m_freeLists[blinkPageSizeLog2]; | 668 FreeListEntry* m_freeLists[blinkPageSizeLog2]; |
| 649 | 669 |
| 650 friend class NormalPageHeap; | 670 friend class NormalPageHeap; |
| 651 }; | 671 }; |
| 652 | 672 |
| 653 // Each thread has a number of thread heaps (e.g., Generic heaps, | 673 // Each thread has a number of thread heaps (e.g., Generic heaps, |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 size_t copySize = previousHeader->payloadSize(); | 1382 size_t copySize = previousHeader->payloadSize(); |
| 1363 if (copySize > size) | 1383 if (copySize > size) |
| 1364 copySize = size; | 1384 copySize = size; |
| 1365 memcpy(address, previous, copySize); | 1385 memcpy(address, previous, copySize); |
| 1366 return address; | 1386 return address; |
| 1367 } | 1387 } |
| 1368 | 1388 |
| 1369 } // namespace blink | 1389 } // namespace blink |
| 1370 | 1390 |
| 1371 #endif // Heap_h | 1391 #endif // Heap_h |
| OLD | NEW |