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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 #endif | 188 #endif |
| 189 | 189 |
| 190 ASSERT(gcInfoIndex < GCInfoTable::maxIndex); | 190 ASSERT(gcInfoIndex < GCInfoTable::maxIndex); |
| 191 ASSERT(size < nonLargeObjectPageSizeMax); | 191 ASSERT(size < nonLargeObjectPageSizeMax); |
| 192 ASSERT(!(size & allocationMask)); | 192 ASSERT(!(size & allocationMask)); |
| 193 m_encoded = static_cast<uint32_t>( | 193 m_encoded = static_cast<uint32_t>( |
| 194 (gcInfoIndex << headerGCInfoIndexShift) | size | | 194 (gcInfoIndex << headerGCInfoIndexShift) | size | |
| 195 (gcInfoIndex == gcInfoIndexForFreeListHeader ? headerFreedBitMask : 0)); | 195 (gcInfoIndex == gcInfoIndexForFreeListHeader ? headerFreedBitMask : 0)); |
| 196 } | 196 } |
| 197 | 197 |
| 198 NO_SANITIZE_ADDRESS | 198 NO_SANITIZE_ADDRESS bool isFree() const { |
| 199 bool isFree() const { return m_encoded & headerFreedBitMask; } | 199 return m_encoded & headerFreedBitMask; |
| 200 NO_SANITIZE_ADDRESS | 200 } |
| 201 bool isPromptlyFreed() const { | 201 |
| 202 NO_SANITIZE_ADDRESS bool isPromptlyFreed() const { | |
| 202 return (m_encoded & headerPromptlyFreedBitMask) == | 203 return (m_encoded & headerPromptlyFreedBitMask) == |
| 203 headerPromptlyFreedBitMask; | 204 headerPromptlyFreedBitMask; |
| 204 } | 205 } |
| 205 NO_SANITIZE_ADDRESS | 206 |
| 206 void markPromptlyFreed() { m_encoded |= headerPromptlyFreedBitMask; } | 207 NO_SANITIZE_ADDRESS void markPromptlyFreed() { |
| 208 m_encoded |= headerPromptlyFreedBitMask; | |
| 209 } | |
| 210 | |
| 207 size_t size() const; | 211 size_t size() const; |
| 208 | 212 |
| 209 NO_SANITIZE_ADDRESS | 213 NO_SANITIZE_ADDRESS size_t gcInfoIndex() const { |
| 210 size_t gcInfoIndex() const { | |
| 211 return (m_encoded & headerGCInfoIndexMask) >> headerGCInfoIndexShift; | 214 return (m_encoded & headerGCInfoIndexMask) >> headerGCInfoIndexShift; |
| 212 } | 215 } |
| 213 NO_SANITIZE_ADDRESS | 216 |
| 214 void setSize(size_t size) { | 217 NO_SANITIZE_ADDRESS void setSize(size_t size) { |
| 215 ASSERT(size < nonLargeObjectPageSizeMax); | 218 ASSERT(size < nonLargeObjectPageSizeMax); |
| 219 checkHeader(); | |
| 216 m_encoded = static_cast<uint32_t>(size) | (m_encoded & ~headerSizeMask); | 220 m_encoded = static_cast<uint32_t>(size) | (m_encoded & ~headerSizeMask); |
| 217 } | 221 } |
| 222 | |
| 218 bool isWrapperHeaderMarked() const; | 223 bool isWrapperHeaderMarked() const; |
| 219 void markWrapperHeader(); | 224 void markWrapperHeader(); |
| 220 void unmarkWrapperHeader(); | 225 void unmarkWrapperHeader(); |
| 221 bool isMarked() const; | 226 bool isMarked() const; |
| 222 void mark(); | 227 void mark(); |
| 223 void unmark(); | 228 void unmark(); |
| 224 | 229 |
| 225 Address payload(); | 230 Address payload(); |
| 226 size_t payloadSize(); | 231 size_t payloadSize(); |
| 227 Address payloadEnd(); | 232 Address payloadEnd(); |
| 228 | 233 |
| 229 // TODO(633030): Make |checkHeader| and |zapMagic| private. This class should | 234 void finalize(Address, size_t); |
| 230 // manage its integrity on its own, without requiring outside callers to | 235 static HeapObjectHeader* fromPayload(const void*); |
| 231 // explicitly check. | |
| 232 void checkHeader() const; | |
| 233 | 236 |
| 237 static const uint32_t zappedMagic = 0xDEAD4321; | |
| 238 | |
| 239 protected: | |
| 234 #if DCHECK_IS_ON() && CPU(64BIT) | 240 #if DCHECK_IS_ON() && CPU(64BIT) |
| 235 // Zap |m_magic| with a new magic number that means there was once an object | 241 // Zap |m_magic| with a new magic number that means there was once an object |
| 236 // allocated here, but it was freed because nobody marked it during GC. | 242 // allocated here, but it was freed because nobody marked it during GC. |
| 237 void zapMagic(); | 243 void zapMagic(); |
| 238 #endif | 244 #endif |
| 239 | 245 |
| 240 void finalize(Address, size_t); | 246 private: |
| 241 static HeapObjectHeader* fromPayload(const void*); | 247 void checkHeader() const; |
| 242 | 248 |
| 243 static const uint32_t zappedMagic = 0xDEAD4321; | |
| 244 | |
| 245 private: | |
| 246 #if CPU(64BIT) | 249 #if CPU(64BIT) |
| 247 // Returns a random value. | 250 // Returns a random value. |
| 248 // | 251 // |
| 249 // The implementation gets its randomness from the locations of 2 independent | 252 // The implementation gets its randomness from the locations of 2 independent |
| 250 // sources of address space layout randomization: a function in a Chrome | 253 // sources of address space layout randomization: a function in a Chrome |
| 251 // executable image, and a function in an external DLL/so. This implementation | 254 // executable image, and a function in an external DLL/so. This implementation |
| 252 // should be fast and small, and should have the benefit of requiring | 255 // should be fast and small, and should have the benefit of requiring |
| 253 // attackers to discover and use 2 independent weak infoleak bugs, or 1 | 256 // attackers to discover and use 2 independent weak infoleak bugs, or 1 |
| 254 // arbitrary infoleak bug (used twice). | 257 // arbitrary infoleak bug (used twice). |
| 255 uint32_t getMagic() const; | 258 uint32_t getMagic() const; |
| 256 uint32_t m_magic; | 259 uint32_t m_magic; |
| 257 #endif | 260 #endif // CPU(64BIT) |
| 258 | 261 |
| 259 uint32_t m_encoded; | 262 uint32_t m_encoded; |
| 260 }; | 263 }; |
| 261 | 264 |
| 262 class FreeListEntry final : public HeapObjectHeader { | 265 class FreeListEntry final : public HeapObjectHeader { |
| 263 public: | 266 public: |
| 264 NO_SANITIZE_ADDRESS | 267 NO_SANITIZE_ADDRESS |
| 265 explicit FreeListEntry(size_t size) | 268 explicit FreeListEntry(size_t size) |
| 266 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader), m_next(nullptr) { | 269 : HeapObjectHeader(size, gcInfoIndexForFreeListHeader), m_next(nullptr) { |
| 267 #if DCHECK_IS_ON() && CPU(64BIT) | 270 #if DCHECK_IS_ON() && CPU(64BIT) |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 833 size_t result = m_encoded & headerSizeMask; | 836 size_t result = m_encoded & headerSizeMask; |
| 834 // Large objects should not refer to header->size(). The actual size of a | 837 // Large objects should not refer to header->size(). The actual size of a |
| 835 // large object is stored in |LargeObjectPage::m_payloadSize|. | 838 // large object is stored in |LargeObjectPage::m_payloadSize|. |
| 836 ASSERT(result != largeObjectSizeInHeader); | 839 ASSERT(result != largeObjectSizeInHeader); |
| 837 ASSERT(!pageFromObject(this)->isLargeObjectPage()); | 840 ASSERT(!pageFromObject(this)->isLargeObjectPage()); |
| 838 return result; | 841 return result; |
| 839 } | 842 } |
| 840 | 843 |
| 841 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::checkHeader() const { | 844 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::checkHeader() const { |
| 842 #if CPU(64BIT) | 845 #if CPU(64BIT) |
| 843 const bool good = getMagic() == m_magic; | 846 const bool goodMagic = getMagic() == m_magic; |
| 844 DCHECK(good); | 847 CHECK(goodMagic); |
|
haraken
2017/03/30 14:12:46
What's a performance implication for the DCHECK =>
| |
| 845 #endif | 848 #endif |
| 846 } | 849 } |
| 847 | 850 |
| 848 inline Address HeapObjectHeader::payload() { | 851 inline Address HeapObjectHeader::payload() { |
| 849 return reinterpret_cast<Address>(this) + sizeof(HeapObjectHeader); | 852 return reinterpret_cast<Address>(this) + sizeof(HeapObjectHeader); |
| 850 } | 853 } |
| 851 | 854 |
| 852 inline Address HeapObjectHeader::payloadEnd() { | 855 inline Address HeapObjectHeader::payloadEnd() { |
| 853 return reinterpret_cast<Address>(this) + size(); | 856 return reinterpret_cast<Address>(this) + size(); |
| 854 } | 857 } |
| 855 | 858 |
| 856 NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::payloadSize() { | 859 NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::payloadSize() { |
| 860 checkHeader(); | |
| 857 size_t size = m_encoded & headerSizeMask; | 861 size_t size = m_encoded & headerSizeMask; |
| 858 if (UNLIKELY(size == largeObjectSizeInHeader)) { | 862 if (UNLIKELY(size == largeObjectSizeInHeader)) { |
| 859 ASSERT(pageFromObject(this)->isLargeObjectPage()); | 863 ASSERT(pageFromObject(this)->isLargeObjectPage()); |
| 860 return static_cast<LargeObjectPage*>(pageFromObject(this))->payloadSize(); | 864 return static_cast<LargeObjectPage*>(pageFromObject(this))->payloadSize(); |
| 861 } | 865 } |
| 862 ASSERT(!pageFromObject(this)->isLargeObjectPage()); | 866 ASSERT(!pageFromObject(this)->isLargeObjectPage()); |
| 863 return size - sizeof(HeapObjectHeader); | 867 return size - sizeof(HeapObjectHeader); |
| 864 } | 868 } |
| 865 | 869 |
| 866 inline HeapObjectHeader* HeapObjectHeader::fromPayload(const void* payload) { | 870 inline HeapObjectHeader* HeapObjectHeader::fromPayload(const void* payload) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 978 return outOfLineAllocate(allocationSize, gcInfoIndex); | 982 return outOfLineAllocate(allocationSize, gcInfoIndex); |
| 979 } | 983 } |
| 980 | 984 |
| 981 inline NormalPageArena* NormalPage::arenaForNormalPage() const { | 985 inline NormalPageArena* NormalPage::arenaForNormalPage() const { |
| 982 return static_cast<NormalPageArena*>(arena()); | 986 return static_cast<NormalPageArena*>(arena()); |
| 983 } | 987 } |
| 984 | 988 |
| 985 } // namespace blink | 989 } // namespace blink |
| 986 | 990 |
| 987 #endif // HeapPage_h | 991 #endif // HeapPage_h |
| OLD | NEW |