| 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 const uint8_t freelistZapValue = 42; | 70 // A zap value used for freed memory that is allowed to be added to the free |
| 71 const uint8_t finalizedZapValue = 24; | 71 // list in the next addToFreeList(). |
| 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; |
| 72 // The orphaned zap value must be zero in the lowest bits to allow for using | 76 // The orphaned zap value must be zero in the lowest bits to allow for using |
| 73 // the mark bit when tracing. | 77 // the mark bit when tracing. |
| 74 const uint8_t orphanedZapValue = 240; | 78 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; | |
| 78 | 79 |
| 79 #if defined(ADDRESS_SANITIZER) | 80 // In non-production builds, memory is zapped when it's freed. The zapped |
| 80 const size_t asanMagic = 0xabefeed0; | 81 // memory is zeroed out when the memory is reused in Heap::allocateObject(). |
| 81 const size_t asanDeferMemoryReuseCount = 2; | 82 // In production builds, memory is not zapped (for performance). The memory |
| 82 const size_t asanDeferMemoryReuseMask = 0x3; | 83 // is just zeroed out when it is added to the free list. |
| 83 #endif | |
| 84 | |
| 85 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) | 84 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
| 86 #define FILL_ZERO_IF_PRODUCTION(address, size) do { } while (false) | 85 #define FILL_ZERO_IF_PRODUCTION(address, size) FreeList::zapFreedMemory(address,
size) |
| 87 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) memset((address), 0, (size)) | 86 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) memset((address), 0, (size)) |
| 88 #else | 87 #else |
| 89 #define FILL_ZERO_IF_PRODUCTION(address, size) memset((address), 0, (size)) | 88 #define FILL_ZERO_IF_PRODUCTION(address, size) memset((address), 0, (size)) |
| 90 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) do { } while (false) | 89 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) do { } while (false) |
| 91 #endif | 90 #endif |
| 92 | 91 |
| 93 class CallbackStack; | 92 class CallbackStack; |
| 94 class FreePagePool; | 93 class FreePagePool; |
| 95 class NormalPageHeap; | 94 class NormalPageHeap; |
| 96 class OrphanedPagePool; | 95 class OrphanedPagePool; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 #endif | 243 #endif |
| 245 }; | 244 }; |
| 246 | 245 |
| 247 class FreeListEntry final : public HeapObjectHeader { | 246 class FreeListEntry final : public HeapObjectHeader { |
| 248 public: | 247 public: |
| 249 NO_SANITIZE_ADDRESS | 248 NO_SANITIZE_ADDRESS |
| 250 explicit FreeListEntry(size_t size) | 249 explicit FreeListEntry(size_t size) |
| 251 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) | 250 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) |
| 252 , m_next(nullptr) | 251 , m_next(nullptr) |
| 253 { | 252 { |
| 254 #if ENABLE(ASSERT) && !defined(ADDRESS_SANITIZER) | 253 #if ENABLE(ASSERT) |
| 255 // Zap free area with asterisks, aka 0x2a2a2a2a. | |
| 256 // For ASan don't zap since we keep accounting in the freelist entry. | |
| 257 for (size_t i = sizeof(*this); i < size; ++i) | |
| 258 reinterpret_cast<Address>(this)[i] = freelistZapValue; | |
| 259 ASSERT(size >= sizeof(HeapObjectHeader)); | 254 ASSERT(size >= sizeof(HeapObjectHeader)); |
| 260 zapMagic(); | 255 zapMagic(); |
| 261 #endif | 256 #endif |
| 262 } | 257 } |
| 263 | 258 |
| 264 Address address() { return reinterpret_cast<Address>(this); } | 259 Address address() { return reinterpret_cast<Address>(this); } |
| 265 | 260 |
| 266 NO_SANITIZE_ADDRESS | 261 NO_SANITIZE_ADDRESS |
| 267 void unlink(FreeListEntry** prevNext) | 262 void unlink(FreeListEntry** prevNext) |
| 268 { | 263 { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 280 NO_SANITIZE_ADDRESS | 275 NO_SANITIZE_ADDRESS |
| 281 FreeListEntry* next() const { return m_next; } | 276 FreeListEntry* next() const { return m_next; } |
| 282 | 277 |
| 283 NO_SANITIZE_ADDRESS | 278 NO_SANITIZE_ADDRESS |
| 284 void append(FreeListEntry* next) | 279 void append(FreeListEntry* next) |
| 285 { | 280 { |
| 286 ASSERT(!m_next); | 281 ASSERT(!m_next); |
| 287 m_next = next; | 282 m_next = next; |
| 288 } | 283 } |
| 289 | 284 |
| 290 #if defined(ADDRESS_SANITIZER) | |
| 291 NO_SANITIZE_ADDRESS | |
| 292 bool shouldAddToFreeList() | |
| 293 { | |
| 294 // Init if not already magic. | |
| 295 if ((m_asanMagic & ~asanDeferMemoryReuseMask) != asanMagic) { | |
| 296 m_asanMagic = asanMagic | asanDeferMemoryReuseCount; | |
| 297 return false; | |
| 298 } | |
| 299 // Decrement if count part of asanMagic > 0. | |
| 300 if (m_asanMagic & asanDeferMemoryReuseMask) | |
| 301 m_asanMagic--; | |
| 302 return !(m_asanMagic & asanDeferMemoryReuseMask); | |
| 303 } | |
| 304 #endif | |
| 305 | |
| 306 private: | 285 private: |
| 307 FreeListEntry* m_next; | 286 FreeListEntry* m_next; |
| 308 #if defined(ADDRESS_SANITIZER) | |
| 309 unsigned m_asanMagic; | |
| 310 #endif | |
| 311 }; | 287 }; |
| 312 | 288 |
| 313 // Blink heap pages are set up with a guard page before and after the payload. | 289 // Blink heap pages are set up with a guard page before and after the payload. |
| 314 inline size_t blinkPagePayloadSize() | 290 inline size_t blinkPagePayloadSize() |
| 315 { | 291 { |
| 316 return blinkPageSize - 2 * WTF::kSystemPageSize; | 292 return blinkPageSize - 2 * WTF::kSystemPageSize; |
| 317 } | 293 } |
| 318 | 294 |
| 319 // Blink heap pages are aligned to the Blink heap page size. | 295 // Blink heap pages are aligned to the Blink heap page size. |
| 320 // Therefore, the start of a Blink page can be obtained by | 296 // Therefore, the start of a Blink page can be obtained by |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 struct PerBucketFreeListStats { | 639 struct PerBucketFreeListStats { |
| 664 size_t entryCount; | 640 size_t entryCount; |
| 665 size_t freeSize; | 641 size_t freeSize; |
| 666 | 642 |
| 667 PerBucketFreeListStats() : entryCount(0), freeSize(0) { } | 643 PerBucketFreeListStats() : entryCount(0), freeSize(0) { } |
| 668 }; | 644 }; |
| 669 | 645 |
| 670 void getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& totalSiz
e) const; | 646 void getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& totalSiz
e) const; |
| 671 #endif | 647 #endif |
| 672 | 648 |
| 649 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
| 650 static void zapFreedMemory(Address, size_t); |
| 651 #endif |
| 652 |
| 673 private: | 653 private: |
| 674 int m_biggestFreeListIndex; | 654 int m_biggestFreeListIndex; |
| 675 | 655 |
| 676 // All FreeListEntries in the nth list have size >= 2^n. | 656 // All FreeListEntries in the nth list have size >= 2^n. |
| 677 FreeListEntry* m_freeLists[blinkPageSizeLog2]; | 657 FreeListEntry* m_freeLists[blinkPageSizeLog2]; |
| 678 | 658 |
| 679 friend class NormalPageHeap; | 659 friend class NormalPageHeap; |
| 680 }; | 660 }; |
| 681 | 661 |
| 682 // Each thread has a number of thread heaps (e.g., Generic heaps, | 662 // Each thread has a number of thread heaps (e.g., Generic heaps, |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 size_t copySize = previousHeader->payloadSize(); | 1381 size_t copySize = previousHeader->payloadSize(); |
| 1402 if (copySize > size) | 1382 if (copySize > size) |
| 1403 copySize = size; | 1383 copySize = size; |
| 1404 memcpy(address, previous, copySize); | 1384 memcpy(address, previous, copySize); |
| 1405 return address; | 1385 return address; |
| 1406 } | 1386 } |
| 1407 | 1387 |
| 1408 } // namespace blink | 1388 } // namespace blink |
| 1409 | 1389 |
| 1410 #endif // Heap_h | 1390 #endif // Heap_h |
| OLD | NEW |