| 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 void mark(); | 222 void mark(); |
| 223 void unmark(); | 223 void unmark(); |
| 224 | 224 |
| 225 Address payload(); | 225 Address payload(); |
| 226 size_t payloadSize(); | 226 size_t payloadSize(); |
| 227 Address payloadEnd(); | 227 Address payloadEnd(); |
| 228 | 228 |
| 229 // TODO(633030): Make |checkHeader| and |zapMagic| private. This class should | 229 // TODO(633030): Make |checkHeader| and |zapMagic| private. This class should |
| 230 // manage its integrity on its own, without requiring outside callers to | 230 // manage its integrity on its own, without requiring outside callers to |
| 231 // explicitly check. | 231 // explicitly check. |
| 232 bool checkHeader() const; | 232 void checkHeader() const; |
| 233 | 233 |
| 234 #if DCHECK_IS_ON() && CPU(64BIT) | 234 #if DCHECK_IS_ON() && CPU(64BIT) |
| 235 // Zap |m_magic| with a new magic number that means there was once an object | 235 // 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. | 236 // allocated here, but it was freed because nobody marked it during GC. |
| 237 void zapMagic(); | 237 void zapMagic(); |
| 238 #endif | 238 #endif |
| 239 | 239 |
| 240 void finalize(Address, size_t); | 240 void finalize(Address, size_t); |
| 241 static HeapObjectHeader* fromPayload(const void*); | 241 static HeapObjectHeader* fromPayload(const void*); |
| 242 | 242 |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 | 831 |
| 832 NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::size() const { | 832 NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::size() const { |
| 833 size_t result = m_encoded & headerSizeMask; | 833 size_t result = m_encoded & headerSizeMask; |
| 834 // Large objects should not refer to header->size(). The actual size of a | 834 // Large objects should not refer to header->size(). The actual size of a |
| 835 // large object is stored in |LargeObjectPage::m_payloadSize|. | 835 // large object is stored in |LargeObjectPage::m_payloadSize|. |
| 836 ASSERT(result != largeObjectSizeInHeader); | 836 ASSERT(result != largeObjectSizeInHeader); |
| 837 ASSERT(!pageFromObject(this)->isLargeObjectPage()); | 837 ASSERT(!pageFromObject(this)->isLargeObjectPage()); |
| 838 return result; | 838 return result; |
| 839 } | 839 } |
| 840 | 840 |
| 841 NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::checkHeader() const { | 841 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::checkHeader() const { |
| 842 #if CPU(64BIT) | 842 #if CPU(64BIT) |
| 843 return m_magic == getMagic(); | 843 const bool good = getMagic() == m_magic; |
| 844 #else | 844 DCHECK(good); |
| 845 return true; | |
| 846 #endif | 845 #endif |
| 847 } | 846 } |
| 848 | 847 |
| 849 inline Address HeapObjectHeader::payload() { | 848 inline Address HeapObjectHeader::payload() { |
| 850 return reinterpret_cast<Address>(this) + sizeof(HeapObjectHeader); | 849 return reinterpret_cast<Address>(this) + sizeof(HeapObjectHeader); |
| 851 } | 850 } |
| 852 | 851 |
| 853 inline Address HeapObjectHeader::payloadEnd() { | 852 inline Address HeapObjectHeader::payloadEnd() { |
| 854 return reinterpret_cast<Address>(this) + size(); | 853 return reinterpret_cast<Address>(this) + size(); |
| 855 } | 854 } |
| 856 | 855 |
| 857 NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::payloadSize() { | 856 NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::payloadSize() { |
| 858 size_t size = m_encoded & headerSizeMask; | 857 size_t size = m_encoded & headerSizeMask; |
| 859 if (UNLIKELY(size == largeObjectSizeInHeader)) { | 858 if (UNLIKELY(size == largeObjectSizeInHeader)) { |
| 860 ASSERT(pageFromObject(this)->isLargeObjectPage()); | 859 ASSERT(pageFromObject(this)->isLargeObjectPage()); |
| 861 return static_cast<LargeObjectPage*>(pageFromObject(this))->payloadSize(); | 860 return static_cast<LargeObjectPage*>(pageFromObject(this))->payloadSize(); |
| 862 } | 861 } |
| 863 ASSERT(!pageFromObject(this)->isLargeObjectPage()); | 862 ASSERT(!pageFromObject(this)->isLargeObjectPage()); |
| 864 return size - sizeof(HeapObjectHeader); | 863 return size - sizeof(HeapObjectHeader); |
| 865 } | 864 } |
| 866 | 865 |
| 867 inline HeapObjectHeader* HeapObjectHeader::fromPayload(const void* payload) { | 866 inline HeapObjectHeader* HeapObjectHeader::fromPayload(const void* payload) { |
| 868 Address addr = reinterpret_cast<Address>(const_cast<void*>(payload)); | 867 Address addr = reinterpret_cast<Address>(const_cast<void*>(payload)); |
| 869 HeapObjectHeader* header = | 868 HeapObjectHeader* header = |
| 870 reinterpret_cast<HeapObjectHeader*>(addr - sizeof(HeapObjectHeader)); | 869 reinterpret_cast<HeapObjectHeader*>(addr - sizeof(HeapObjectHeader)); |
| 871 ASSERT(header->checkHeader()); | 870 header->checkHeader(); |
| 872 return header; | 871 return header; |
| 873 } | 872 } |
| 874 | 873 |
| 875 #if CPU(64BIT) | 874 #if CPU(64BIT) |
| 876 ALWAYS_INLINE uint32_t RotateLeft16(uint32_t x) { | 875 ALWAYS_INLINE uint32_t RotateLeft16(uint32_t x) { |
| 877 #if COMPILER(MSVC) | 876 #if COMPILER(MSVC) |
| 878 return _lrotr(x, 16); | 877 return _lrotr(x, 16); |
| 879 #else | 878 #else |
| 880 // http://blog.regehr.org/archives/1063 | 879 // http://blog.regehr.org/archives/1063 |
| 881 return (x << 16) | (x >> (-16 & 31)); | 880 return (x << 16) | (x >> (-16 & 31)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 #if COMPILER(MSVC) | 920 #if COMPILER(MSVC) |
| 922 #pragma warning(pop) | 921 #pragma warning(pop) |
| 923 #endif | 922 #endif |
| 924 | 923 |
| 925 return random; | 924 return random; |
| 926 } | 925 } |
| 927 #endif // CPU(64BIT) | 926 #endif // CPU(64BIT) |
| 928 | 927 |
| 929 NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::isWrapperHeaderMarked() | 928 NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::isWrapperHeaderMarked() |
| 930 const { | 929 const { |
| 931 ASSERT(checkHeader()); | 930 checkHeader(); |
| 932 return m_encoded & headerWrapperMarkBitMask; | 931 return m_encoded & headerWrapperMarkBitMask; |
| 933 } | 932 } |
| 934 | 933 |
| 935 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::markWrapperHeader() { | 934 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::markWrapperHeader() { |
| 936 ASSERT(checkHeader()); | 935 checkHeader(); |
| 937 ASSERT(!isWrapperHeaderMarked()); | 936 ASSERT(!isWrapperHeaderMarked()); |
| 938 m_encoded |= headerWrapperMarkBitMask; | 937 m_encoded |= headerWrapperMarkBitMask; |
| 939 } | 938 } |
| 940 | 939 |
| 941 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::unmarkWrapperHeader() { | 940 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::unmarkWrapperHeader() { |
| 942 ASSERT(checkHeader()); | 941 checkHeader(); |
| 943 ASSERT(isWrapperHeaderMarked()); | 942 ASSERT(isWrapperHeaderMarked()); |
| 944 m_encoded &= ~headerWrapperMarkBitMask; | 943 m_encoded &= ~headerWrapperMarkBitMask; |
| 945 } | 944 } |
| 946 | 945 |
| 947 NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::isMarked() const { | 946 NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::isMarked() const { |
| 948 ASSERT(checkHeader()); | 947 checkHeader(); |
| 949 return m_encoded & headerMarkBitMask; | 948 return m_encoded & headerMarkBitMask; |
| 950 } | 949 } |
| 951 | 950 |
| 952 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::mark() { | 951 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::mark() { |
| 953 ASSERT(checkHeader()); | 952 checkHeader(); |
| 954 ASSERT(!isMarked()); | 953 ASSERT(!isMarked()); |
| 955 m_encoded = m_encoded | headerMarkBitMask; | 954 m_encoded = m_encoded | headerMarkBitMask; |
| 956 } | 955 } |
| 957 | 956 |
| 958 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::unmark() { | 957 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::unmark() { |
| 959 ASSERT(checkHeader()); | 958 checkHeader(); |
| 960 ASSERT(isMarked()); | 959 ASSERT(isMarked()); |
| 961 m_encoded &= ~headerMarkBitMask; | 960 m_encoded &= ~headerMarkBitMask; |
| 962 } | 961 } |
| 963 | 962 |
| 964 inline Address NormalPageArena::allocateObject(size_t allocationSize, | 963 inline Address NormalPageArena::allocateObject(size_t allocationSize, |
| 965 size_t gcInfoIndex) { | 964 size_t gcInfoIndex) { |
| 966 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { | 965 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { |
| 967 Address headerAddress = m_currentAllocationPoint; | 966 Address headerAddress = m_currentAllocationPoint; |
| 968 m_currentAllocationPoint += allocationSize; | 967 m_currentAllocationPoint += allocationSize; |
| 969 m_remainingAllocationSize -= allocationSize; | 968 m_remainingAllocationSize -= allocationSize; |
| 970 ASSERT(gcInfoIndex > 0); | 969 ASSERT(gcInfoIndex > 0); |
| 971 new (NotNull, headerAddress) HeapObjectHeader(allocationSize, gcInfoIndex); | 970 new (NotNull, headerAddress) HeapObjectHeader(allocationSize, gcInfoIndex); |
| 972 Address result = headerAddress + sizeof(HeapObjectHeader); | 971 Address result = headerAddress + sizeof(HeapObjectHeader); |
| 973 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); | 972 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); |
| 974 | 973 |
| 975 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader)); | 974 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader)); |
| 976 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); | 975 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); |
| 977 return result; | 976 return result; |
| 978 } | 977 } |
| 979 return outOfLineAllocate(allocationSize, gcInfoIndex); | 978 return outOfLineAllocate(allocationSize, gcInfoIndex); |
| 980 } | 979 } |
| 981 | 980 |
| 982 inline NormalPageArena* NormalPage::arenaForNormalPage() const { | 981 inline NormalPageArena* NormalPage::arenaForNormalPage() const { |
| 983 return static_cast<NormalPageArena*>(arena()); | 982 return static_cast<NormalPageArena*>(arena()); |
| 984 } | 983 } |
| 985 | 984 |
| 986 } // namespace blink | 985 } // namespace blink |
| 987 | 986 |
| 988 #endif // HeapPage_h | 987 #endif // HeapPage_h |
| OLD | NEW |