| 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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 #endif | 242 #endif |
| 244 }; | 243 }; |
| 245 | 244 |
| 246 class FreeListEntry final : public HeapObjectHeader { | 245 class FreeListEntry final : public HeapObjectHeader { |
| 247 public: | 246 public: |
| 248 NO_SANITIZE_ADDRESS | 247 NO_SANITIZE_ADDRESS |
| 249 explicit FreeListEntry(size_t size) | 248 explicit FreeListEntry(size_t size) |
| 250 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) | 249 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) |
| 251 , m_next(nullptr) | 250 , m_next(nullptr) |
| 252 { | 251 { |
| 253 #if ENABLE(ASSERT) && !defined(ADDRESS_SANITIZER) | 252 #if ENABLE(ASSERT) |
| 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; | |
| 258 ASSERT(size >= sizeof(HeapObjectHeader)); | 253 ASSERT(size >= sizeof(HeapObjectHeader)); |
| 259 zapMagic(); | 254 zapMagic(); |
| 260 #endif | 255 #endif |
| 261 } | 256 } |
| 262 | 257 |
| 263 Address address() { return reinterpret_cast<Address>(this); } | 258 Address address() { return reinterpret_cast<Address>(this); } |
| 264 | 259 |
| 265 NO_SANITIZE_ADDRESS | 260 NO_SANITIZE_ADDRESS |
| 266 void unlink(FreeListEntry** prevNext) | 261 void unlink(FreeListEntry** prevNext) |
| 267 { | 262 { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 279 NO_SANITIZE_ADDRESS | 274 NO_SANITIZE_ADDRESS |
| 280 FreeListEntry* next() const { return m_next; } | 275 FreeListEntry* next() const { return m_next; } |
| 281 | 276 |
| 282 NO_SANITIZE_ADDRESS | 277 NO_SANITIZE_ADDRESS |
| 283 void append(FreeListEntry* next) | 278 void append(FreeListEntry* next) |
| 284 { | 279 { |
| 285 ASSERT(!m_next); | 280 ASSERT(!m_next); |
| 286 m_next = next; | 281 m_next = next; |
| 287 } | 282 } |
| 288 | 283 |
| 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 | |
| 305 private: | 284 private: |
| 306 FreeListEntry* m_next; | 285 FreeListEntry* m_next; |
| 307 #if defined(ADDRESS_SANITIZER) | |
| 308 unsigned m_asanMagic; | |
| 309 #endif | |
| 310 }; | 286 }; |
| 311 | 287 |
| 312 // Blink heap pages are set up with a guard page before and after the payload. | 288 // Blink heap pages are set up with a guard page before and after the payload. |
| 313 inline size_t blinkPagePayloadSize() | 289 inline size_t blinkPagePayloadSize() |
| 314 { | 290 { |
| 315 return blinkPageSize - 2 * WTF::kSystemPageSize; | 291 return blinkPageSize - 2 * WTF::kSystemPageSize; |
| 316 } | 292 } |
| 317 | 293 |
| 318 // Blink heap pages are aligned to the Blink heap page size. | 294 // Blink heap pages are aligned to the Blink heap page size. |
| 319 // Therefore, the start of a Blink page can be obtained by | 295 // Therefore, the start of a Blink page can be obtained by |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 struct PerBucketFreeListStats { | 630 struct PerBucketFreeListStats { |
| 655 size_t entryCount; | 631 size_t entryCount; |
| 656 size_t freeSize; | 632 size_t freeSize; |
| 657 | 633 |
| 658 PerBucketFreeListStats() : entryCount(0), freeSize(0) { } | 634 PerBucketFreeListStats() : entryCount(0), freeSize(0) { } |
| 659 }; | 635 }; |
| 660 | 636 |
| 661 void getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& totalSiz
e) const; | 637 void getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& totalSiz
e) const; |
| 662 #endif | 638 #endif |
| 663 | 639 |
| 640 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
| 641 static void zapFreedMemory(Address, size_t); |
| 642 #endif |
| 643 |
| 664 private: | 644 private: |
| 665 int m_biggestFreeListIndex; | 645 int m_biggestFreeListIndex; |
| 666 | 646 |
| 667 // All FreeListEntries in the nth list have size >= 2^n. | 647 // All FreeListEntries in the nth list have size >= 2^n. |
| 668 FreeListEntry* m_freeLists[blinkPageSizeLog2]; | 648 FreeListEntry* m_freeLists[blinkPageSizeLog2]; |
| 669 | 649 |
| 670 friend class NormalPageHeap; | 650 friend class NormalPageHeap; |
| 671 }; | 651 }; |
| 672 | 652 |
| 673 // Each thread has a number of thread heaps (e.g., Generic heaps, | 653 // 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... |
| 1382 size_t copySize = previousHeader->payloadSize(); | 1362 size_t copySize = previousHeader->payloadSize(); |
| 1383 if (copySize > size) | 1363 if (copySize > size) |
| 1384 copySize = size; | 1364 copySize = size; |
| 1385 memcpy(address, previous, copySize); | 1365 memcpy(address, previous, copySize); |
| 1386 return address; | 1366 return address; |
| 1387 } | 1367 } |
| 1388 | 1368 |
| 1389 } // namespace blink | 1369 } // namespace blink |
| 1390 | 1370 |
| 1391 #endif // Heap_h | 1371 #endif // Heap_h |
| OLD | NEW |