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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 { | 329 { |
| 330 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address - 1) & blinkPageBaseMask) + blinkPageSize; | 330 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address - 1) & blinkPageBaseMask) + blinkPageSize; |
| 331 } | 331 } |
| 332 | 332 |
| 333 // Masks an address down to the enclosing blink page base address. | 333 // Masks an address down to the enclosing blink page base address. |
| 334 inline Address blinkPageAddress(Address address) | 334 inline Address blinkPageAddress(Address address) |
| 335 { | 335 { |
| 336 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blin kPageBaseMask); | 336 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blin kPageBaseMask); |
| 337 } | 337 } |
| 338 | 338 |
| 339 inline bool vTableInitialized(void* objectPointer) | |
| 340 { | |
| 341 return !!(*reinterpret_cast<Address*>(objectPointer)); | |
| 342 } | |
| 343 | |
| 339 #if ENABLE(ASSERT) | 344 #if ENABLE(ASSERT) |
| 340 | |
| 341 // Sanity check for a page header address: the address of the page | 345 // Sanity check for a page header address: the address of the page |
| 342 // header should be OS page size away from being Blink page size | 346 // header should be OS page size away from being Blink page size |
| 343 // aligned. | 347 // aligned. |
| 344 inline bool isPageHeaderAddress(Address address) | 348 inline bool isPageHeaderAddress(Address address) |
| 345 { | 349 { |
| 346 return !((reinterpret_cast<uintptr_t>(address) & blinkPageOffsetMask) - WTF: :kSystemPageSize); | 350 return !((reinterpret_cast<uintptr_t>(address) & blinkPageOffsetMask) - WTF: :kSystemPageSize); |
| 347 } | 351 } |
| 348 #endif | 352 #endif |
| 349 | 353 |
| 350 // BasePage is a base class for NormalPage and LargeObjectPage. | 354 // BasePage is a base class for NormalPage and LargeObjectPage. |
| (...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1887 } | 1891 } |
| 1888 }; | 1892 }; |
| 1889 | 1893 |
| 1890 // Vector backing that needs marking. We don't support weak members in vectors. | 1894 // Vector backing that needs marking. We don't support weak members in vectors. |
| 1891 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts> | 1895 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts> |
| 1892 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pVectorBacking<T, Traits>, void> { | 1896 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pVectorBacking<T, Traits>, void> { |
| 1893 template<typename VisitorDispatcher> | 1897 template<typename VisitorDispatcher> |
| 1894 static bool trace(VisitorDispatcher visitor, void* self) | 1898 static bool trace(VisitorDispatcher visitor, void* self) |
| 1895 { | 1899 { |
| 1896 // HeapVectorBacking does not know the exact size of the vector | 1900 // HeapVectorBacking does not know the exact size of the vector |
| 1897 // and thus cannot avoid tracing all slots in the backing. | 1901 // and just knows the capacity of the vector. Due to the constraint, |
| 1898 // This works correctly as long as unused slots are cleared out | 1902 // HeapVectorBacking can support only the following objects: |
| 1899 // (this is done by VectorUnusedSlotClearer) and T can be initialized | 1903 // |
| 1900 // with memset (if T can be initialized with memset, it is safe to | 1904 // - An object that has a vtable. In this case, HeapVectorBacking |
| 1901 // treat a zeroed object as a valid object). | 1905 // traces only slots that are not zeroed out. This is because if |
| 1902 static_assert(!ShouldBeTraced<Traits>::value || Traits::canInitializeWit hMemset, "HeapVectorBacking doesn't support objects that cannot be initialized w ith memset."); | 1906 // the object has a vtable, the zeroed slot means that it is |
| 1907 // an unused slot (Remember that the unused slots are guaranteed | |
| 1908 // to be zeroed out by VectorUnusedSlotClearer). | |
| 1909 // | |
| 1910 // - An object that can be initialized with memset. In this case, | |
| 1911 // HeapVectorBacking traces all slots including unused slots. | |
| 1912 // This is fine because the fact that the object can be initialized | |
| 1913 // with memset indicates that it is safe to treat the zerod slot | |
| 1914 // as a valid object. | |
| 1915 static_assert(!ShouldBeTraced<Traits>::value || Traits::canInitializeWit hMemset || WTF::IsPolymorphic<T>::value, "HeapVectorBacking doesn't support obje cts that cannot be initialized with memset."); | |
| 1903 | 1916 |
| 1904 T* array = reinterpret_cast<T*>(self); | 1917 T* array = reinterpret_cast<T*>(self); |
| 1905 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s elf); | 1918 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s elf); |
| 1906 // Use the payload size as recorded by the heap to determine how many | 1919 // Use the payload size as recorded by the heap to determine how many |
| 1907 // elements to trace. | 1920 // elements to trace. |
| 1908 size_t length = header->payloadSize() / sizeof(T); | 1921 size_t length = header->payloadSize() / sizeof(T); |
| 1922 if (WTF::IsPolymorphic<T>::value) { | |
| 1923 for (size_t i = 0; i < length; ++i) { | |
| 1924 if (blink::vTableInitialized(&array[i])) | |
| 1925 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::v alue, Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor , array[i]); | |
| 1926 } | |
| 1927 } else { | |
| 1909 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER | 1928 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER |
| 1910 // As commented above, HeapVectorBacking can trace unused slots | 1929 // As commented above, HeapVectorBacking can trace unused slots |
| 1911 // (which are already zeroed out). | 1930 // (which are already zeroed out). |
| 1912 ANNOTATE_CHANGE_SIZE(array, length, 0, length); | 1931 ANNOTATE_CHANGE_SIZE(array, length, 0, length); |
| 1913 #endif | 1932 #endif |
| 1914 for (size_t i = 0; i < length; ++i) | 1933 for (size_t i = 0; i < length; ++i) |
| 1915 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[ i]); | 1934 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value , Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, ar ray[i]); |
| 1935 } | |
| 1916 return false; | 1936 return false; |
| 1917 } | 1937 } |
| 1918 }; | 1938 }; |
| 1919 | 1939 |
| 1920 // Almost all hash table backings are visited with this specialization. | 1940 // Almost all hash table backings are visited with this specialization. |
| 1921 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> | 1941 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
| 1922 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pHashTableBacking<Table>, void> { | 1942 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pHashTableBacking<Table>, void> { |
| 1923 using Value = typename Table::ValueType; | 1943 using Value = typename Table::ValueType; |
| 1924 using Traits = typename Table::ValueTraits; | 1944 using Traits = typename Table::ValueTraits; |
| 1925 | 1945 |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2183 #if ENABLE(ASSERT) | 2203 #if ENABLE(ASSERT) |
| 2184 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing >::index()); | 2204 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing >::index()); |
| 2185 #endif | 2205 #endif |
| 2186 } | 2206 } |
| 2187 }; | 2207 }; |
| 2188 | 2208 |
| 2189 template<typename T, typename Traits> | 2209 template<typename T, typename Traits> |
| 2190 void HeapVectorBacking<T, Traits>::finalize(void* pointer) | 2210 void HeapVectorBacking<T, Traits>::finalize(void* pointer) |
| 2191 { | 2211 { |
| 2192 static_assert(Traits::needsDestruction, "Only vector buffers with items requ iring destruction should be finalized"); | 2212 static_assert(Traits::needsDestruction, "Only vector buffers with items requ iring destruction should be finalized"); |
| 2193 // HeapVectorBacking does not know the exact size of the vector | 2213 // HeapVectorBacking does not know the exact size of the vector |
|
sof
2015/04/30 21:15:47
Possible to have this long comment, which is very
haraken
2015/04/30 23:40:19
Done.
| |
| 2194 // and thus cannot avoid calling finalizers for all slots in the backing. | 2214 // and just knows the capacity of the vector. Due to the constraint, |
| 2195 // This works correctly as long as unused slots are cleared out | 2215 // HeapVectorBacking can support only the following objects: |
| 2196 // (this is done by VectorUnusedSlotClearer) and T can be initialized | 2216 // |
| 2197 // with memset (if T can be initialized with memset, it is safe to | 2217 // - An object that has a vtable. In this case, HeapVectorBacking calls |
| 2198 // treat a zeroed object as a valid object). | 2218 // destructors only for slots that are not zeroed out. This is because |
| 2199 static_assert(Traits::canInitializeWithMemset, "HeapVectorBacking doesn't su pport objects that cannot be initialized with memset."); | 2219 // if the object has a vtable, the zeroed slot means that it is |
| 2220 // an unused slot (Remember that the unused slots are guaranteed to be | |
| 2221 // zeroed out by VectorUnusedSlotClearer). | |
| 2222 // | |
| 2223 // - An object that can be initialized with memset. In this case, | |
| 2224 // HeapVectorBacking calls destructors for all slots including unused | |
| 2225 // slots. This is fine because the fact that the object can be initialized | |
| 2226 // with memset indicates that it is safe to treat the zerod slot | |
| 2227 // as a valid object. | |
| 2228 static_assert(Traits::canInitializeWithMemset || WTF::IsPolymorphic<T>::valu e, "HeapVectorBacking doesn't support objects that cannot be initialized with me mset or don't have a vtable"); | |
| 2200 | 2229 |
| 2201 ASSERT(!WTF::IsTriviallyDestructible<T>::value); | 2230 ASSERT(!WTF::IsTriviallyDestructible<T>::value); |
| 2202 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); | 2231 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); |
| 2203 // Use the payload size as recorded by the heap to determine how many | 2232 // Use the payload size as recorded by the heap to determine how many |
| 2204 // elements to finalize. | 2233 // elements to finalize. |
| 2205 size_t length = header->payloadSize() / sizeof(T); | 2234 size_t length = header->payloadSize() / sizeof(T); |
| 2206 T* buffer = reinterpret_cast<T*>(pointer); | 2235 T* buffer = reinterpret_cast<T*>(pointer); |
| 2207 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER | 2236 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER |
| 2208 // As commented above, HeapVectorBacking calls finalizers for unused slots | 2237 // As commented above, HeapVectorBacking calls finalizers for unused slots |
| 2209 // (which are already zeroed out). | 2238 // (which are already zeroed out). |
| 2210 ANNOTATE_CHANGE_SIZE(buffer, length, 0, length); | 2239 ANNOTATE_CHANGE_SIZE(buffer, length, 0, length); |
| 2211 #endif | 2240 #endif |
| 2212 for (unsigned i = 0; i < length; ++i) | 2241 if (WTF::IsPolymorphic<T>::value) { |
| 2213 buffer[i].~T(); | 2242 for (unsigned i = 0; i < length; ++i) { |
| 2243 if (blink::vTableInitialized(&buffer[i])) | |
| 2244 buffer[i].~T(); | |
| 2245 } | |
| 2246 } else { | |
| 2247 for (unsigned i = 0; i < length; ++i) { | |
| 2248 buffer[i].~T(); | |
| 2249 } | |
| 2250 } | |
| 2214 } | 2251 } |
| 2215 | 2252 |
| 2216 template<typename Table> | 2253 template<typename Table> |
| 2217 void HeapHashTableBacking<Table>::finalize(void* pointer) | 2254 void HeapHashTableBacking<Table>::finalize(void* pointer) |
| 2218 { | 2255 { |
| 2219 using Value = typename Table::ValueType; | 2256 using Value = typename Table::ValueType; |
| 2220 ASSERT(!WTF::IsTriviallyDestructible<Value>::value); | 2257 ASSERT(!WTF::IsTriviallyDestructible<Value>::value); |
| 2221 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); | 2258 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); |
| 2222 // Use the payload size as recorded by the heap to determine how many | 2259 // Use the payload size as recorded by the heap to determine how many |
| 2223 // elements to finalize. | 2260 // elements to finalize. |
| 2224 size_t length = header->payloadSize() / sizeof(Value); | 2261 size_t length = header->payloadSize() / sizeof(Value); |
| 2225 Value* table = reinterpret_cast<Value*>(pointer); | 2262 Value* table = reinterpret_cast<Value*>(pointer); |
| 2226 for (unsigned i = 0; i < length; ++i) { | 2263 for (unsigned i = 0; i < length; ++i) { |
| 2227 if (!Table::isEmptyOrDeletedBucket(table[i])) | 2264 if (!Table::isEmptyOrDeletedBucket(table[i])) |
| 2228 table[i].~Value(); | 2265 table[i].~Value(); |
| 2229 } | 2266 } |
| 2230 } | 2267 } |
| 2231 | 2268 |
| 2232 } // namespace blink | 2269 } // namespace blink |
| 2233 | 2270 |
| 2234 #endif // Heap_h | 2271 #endif // Heap_h |
| OLD | NEW |