Chromium Code Reviews| 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 | 164 |
| 165 static_assert(nonLargeObjectPageSizeMax >= blinkPageSize, "max size supported by HeapObjectHeader must at least be blinkPageSize"); | 165 static_assert(nonLargeObjectPageSizeMax >= blinkPageSize, "max size supported by HeapObjectHeader must at least be blinkPageSize"); |
| 166 | 166 |
| 167 class PLATFORM_EXPORT HeapObjectHeader { | 167 class PLATFORM_EXPORT HeapObjectHeader { |
| 168 public: | 168 public: |
| 169 // If gcInfoIndex is 0, this header is interpreted as a free list header. | 169 // If gcInfoIndex is 0, this header is interpreted as a free list header. |
| 170 NO_SANITIZE_ADDRESS | 170 NO_SANITIZE_ADDRESS |
| 171 HeapObjectHeader(size_t size, size_t gcInfoIndex) | 171 HeapObjectHeader(size_t size, size_t gcInfoIndex) |
| 172 { | 172 { |
| 173 #if ENABLE(ASSERT) | 173 #if ENABLE(ASSERT) |
| 174 m_magic = magic; | 174 putGcGeneration(); |
|
haraken
2015/11/11 10:03:16
Actually this is not quite right. Remember that He
peria
2015/11/12 14:38:42
Done.
| |
| 175 #endif | 175 #endif |
| 176 // sizeof(HeapObjectHeader) must be equal to or smaller than | 176 // sizeof(HeapObjectHeader) must be equal to or smaller than |
| 177 // allocationGranurarity, because HeapObjectHeader is used as a header | 177 // allocationGranurarity, because HeapObjectHeader is used as a header |
| 178 // for an freed entry. Given that the smallest entry size is | 178 // for an freed entry. Given that the smallest entry size is |
| 179 // allocationGranurarity, HeapObjectHeader must fit into the size. | 179 // allocationGranurarity, HeapObjectHeader must fit into the size. |
| 180 static_assert(sizeof(HeapObjectHeader) <= allocationGranularity, "size o f HeapObjectHeader must be smaller than allocationGranularity"); | 180 static_assert(sizeof(HeapObjectHeader) <= allocationGranularity, "size o f HeapObjectHeader must be smaller than allocationGranularity"); |
| 181 #if CPU(64BIT) | 181 #if CPU(64BIT) |
| 182 static_assert(sizeof(HeapObjectHeader) == 8, "size of HeapObjectHeader m ust be 8 byte aligned"); | 182 static_assert(sizeof(HeapObjectHeader) == 8, "size of HeapObjectHeader m ust be 8 byte aligned"); |
| 183 #endif | 183 #endif |
| 184 | 184 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 205 void unmark(); | 205 void unmark(); |
| 206 void markDead(); | 206 void markDead(); |
| 207 bool isDead() const; | 207 bool isDead() const; |
| 208 | 208 |
| 209 Address payload(); | 209 Address payload(); |
| 210 size_t payloadSize(); | 210 size_t payloadSize(); |
| 211 Address payloadEnd(); | 211 Address payloadEnd(); |
| 212 | 212 |
| 213 #if ENABLE(ASSERT) | 213 #if ENABLE(ASSERT) |
| 214 bool checkHeader() const; | 214 bool checkHeader() const; |
| 215 // Zap magic number with a new magic number that means there was once an | 215 |
| 216 // object allocated here, but it was freed because nobody marked it during | 216 void putGcGeneration(); |
|
haraken
2015/11/11 10:03:16
putGcGeneration => recordGCGeneration
peria
2015/11/12 14:38:42
I removed this method with making gcGeneration a p
| |
| 217 // GC. | 217 void clearGcGeneration(); |
| 218 void zapMagic(); | 218 uint32_t gcGeneration() const { return m_gcGeneration; } |
| 219 #endif | 219 #endif |
| 220 | 220 |
| 221 void finalize(Address, size_t); | 221 void finalize(Address, size_t); |
| 222 static HeapObjectHeader* fromPayload(const void*); | 222 static HeapObjectHeader* fromPayload(const void*); |
| 223 | 223 |
| 224 static const uint16_t magic = 0xfff1; | |
| 225 static const uint16_t zappedMagic = 0x4321; | |
| 226 | |
| 227 private: | 224 private: |
| 228 uint32_t m_encoded; | 225 uint32_t m_encoded; |
| 229 #if ENABLE(ASSERT) | 226 #if ENABLE(ASSERT) |
| 230 uint16_t m_magic; | 227 uint32_t m_gcGeneration; |
|
haraken
2015/11/11 10:03:16
Add a comment.
// m_gcGeneration keeps track of t
peria
2015/11/12 14:38:42
Done.
| |
| 231 #endif | 228 #endif |
| 232 | 229 |
| 233 // In 64 bit architectures, we intentionally add 4 byte padding immediately | 230 // In 64 bit architectures, we intentionally add 4 byte padding immediately |
| 234 // after the HeapHeaderObject. This is because: | 231 // after the HeapHeaderObject. This is because: |
| 235 // | 232 // |
| 236 // | HeapHeaderObject (4 byte) | padding (4 byte) | object payload (8 * n by te) | | 233 // | HeapHeaderObject (4 byte) | padding (4 byte) | object payload (8 * n by te) | |
| 237 // ^8 byte aligned ^8 byte aligned | 234 // ^8 byte aligned ^8 byte aligned |
| 238 // | 235 // |
| 239 // is better than: | 236 // is better than: |
| 240 // | 237 // |
| 241 // | HeapHeaderObject (4 byte) | object payload (8 * n byte) | padding (4 by te) | | 238 // | HeapHeaderObject (4 byte) | object payload (8 * n byte) | padding (4 by te) | |
| 242 // ^4 byte aligned ^8 byte aligned ^4 byte aligned | 239 // ^4 byte aligned ^8 byte aligned ^4 byte aligned |
| 243 // | 240 // |
| 244 // since the former layout aligns both header and payload to 8 byte. | 241 // since the former layout aligns both header and payload to 8 byte. |
| 245 #if USE_4BYTE_HEADER_PADDING | 242 #if USE_4BYTE_HEADER_PADDING |
| 246 public: | 243 public: |
| 247 uint32_t m_padding; | 244 uint32_t m_padding; |
| 248 #endif | 245 #endif |
| 249 }; | 246 }; |
| 250 | 247 |
| 251 class FreeListEntry final : public HeapObjectHeader { | 248 class FreeListEntry final : public HeapObjectHeader { |
| 252 public: | 249 public: |
| 253 NO_SANITIZE_ADDRESS | 250 NO_SANITIZE_ADDRESS |
| 254 explicit FreeListEntry(size_t size) | 251 explicit FreeListEntry(size_t size) |
| 255 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) | 252 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader) |
| 256 , m_next(nullptr) | 253 , m_next(nullptr) |
| 257 { | 254 { |
| 258 #if ENABLE(ASSERT) | 255 #if ENABLE(ASSERT) |
| 259 ASSERT(size >= sizeof(HeapObjectHeader)); | 256 ASSERT(size >= sizeof(HeapObjectHeader)); |
| 260 zapMagic(); | 257 clearGcGeneration(); |
| 261 #endif | 258 #endif |
| 262 } | 259 } |
| 263 | 260 |
| 264 Address address() { return reinterpret_cast<Address>(this); } | 261 Address address() { return reinterpret_cast<Address>(this); } |
| 265 | 262 |
| 266 NO_SANITIZE_ADDRESS | 263 NO_SANITIZE_ADDRESS |
| 267 void unlink(FreeListEntry** prevNext) | 264 void unlink(FreeListEntry** prevNext) |
| 268 { | 265 { |
| 269 *prevNext = m_next; | 266 *prevNext = m_next; |
| 270 m_next = nullptr; | 267 m_next = nullptr; |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 776 // LargeObjectPage::m_payloadSize. | 773 // LargeObjectPage::m_payloadSize. |
| 777 ASSERT(result != largeObjectSizeInHeader); | 774 ASSERT(result != largeObjectSizeInHeader); |
| 778 ASSERT(!pageFromObject(this)->isLargeObjectPage()); | 775 ASSERT(!pageFromObject(this)->isLargeObjectPage()); |
| 779 return result; | 776 return result; |
| 780 } | 777 } |
| 781 | 778 |
| 782 #if ENABLE(ASSERT) | 779 #if ENABLE(ASSERT) |
| 783 NO_SANITIZE_ADDRESS inline | 780 NO_SANITIZE_ADDRESS inline |
| 784 bool HeapObjectHeader::checkHeader() const | 781 bool HeapObjectHeader::checkHeader() const |
| 785 { | 782 { |
| 786 return !pageFromObject(this)->orphaned() && m_magic == magic; | 783 return !pageFromObject(this)->orphaned() && m_gcGeneration; |
| 787 } | 784 } |
| 788 #endif | 785 #endif |
| 789 | 786 |
| 790 inline Address HeapObjectHeader::payload() | 787 inline Address HeapObjectHeader::payload() |
| 791 { | 788 { |
| 792 return reinterpret_cast<Address>(this) + sizeof(HeapObjectHeader); | 789 return reinterpret_cast<Address>(this) + sizeof(HeapObjectHeader); |
| 793 } | 790 } |
| 794 | 791 |
| 795 inline Address HeapObjectHeader::payloadEnd() | 792 inline Address HeapObjectHeader::payloadEnd() |
| 796 { | 793 { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 869 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader)) ; | 866 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader)) ; |
| 870 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); | 867 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); |
| 871 return result; | 868 return result; |
| 872 } | 869 } |
| 873 return outOfLineAllocate(allocationSize, gcInfoIndex); | 870 return outOfLineAllocate(allocationSize, gcInfoIndex); |
| 874 } | 871 } |
| 875 | 872 |
| 876 } // namespace blink | 873 } // namespace blink |
| 877 | 874 |
| 878 #endif // HeapPage_h | 875 #endif // HeapPage_h |
| OLD | NEW |