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 |