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 1875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1886 return Traits::traceInCollection(visitor, t, strongify); | 1886 return Traits::traceInCollection(visitor, t, strongify); |
| 1887 } | 1887 } |
| 1888 }; | 1888 }; |
| 1889 | 1889 |
| 1890 // Vector backing that needs marking. We don't support weak members in vectors. | 1890 // Vector backing that needs marking. We don't support weak members in vectors. |
| 1891 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts> | 1891 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts> |
| 1892 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pVectorBacking<T, Traits>, void> { | 1892 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea pVectorBacking<T, Traits>, void> { |
| 1893 template<typename VisitorDispatcher> | 1893 template<typename VisitorDispatcher> |
| 1894 static bool trace(VisitorDispatcher visitor, void* self) | 1894 static bool trace(VisitorDispatcher visitor, void* self) |
| 1895 { | 1895 { |
| 1896 // The allocator can oversize the allocation a little, according to | 1896 // HeapVectorBacking does not know the exact size of the vector |
| 1897 // the allocation granularity. The extra size is included in the | 1897 // and thus cannot avoid tracing all slots in the backing. |
| 1898 // payloadSize call below, since there is nowhere to store the | 1898 // This works correctly as long as unused slots are cleared out |
| 1899 // originally allocated memory. This assert ensures that visiting the | 1899 // (this is done by VectorUnusedSlotClearer) and T can be initialized |
|
tkent
2015/04/27 03:29:23
Please document this in http://dev.chromium.org/bl
haraken
2015/04/27 03:54:41
Done.
| |
| 1900 // last bit of memory can't cause trouble. | 1900 // with memset (if T can be initialized with memset, it is safe to |
| 1901 static_assert(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::alloc ationGranularity || Traits::canInitializeWithMemset, "heap overallocation can ca use spurious visits"); | 1901 // treat a zeroed object as a valid object). |
| 1902 static_assert(!ShouldBeTraced<Traits>::value || Traits::canInitializeWit hMemset, "HeapVectorBacking doesn't support objects that cannot be initialized w ith memset."); | |
| 1902 | 1903 |
| 1903 T* array = reinterpret_cast<T*>(self); | 1904 T* array = reinterpret_cast<T*>(self); |
| 1904 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s elf); | 1905 blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(s elf); |
| 1905 // Use the payload size as recorded by the heap to determine how many | 1906 // Use the payload size as recorded by the heap to determine how many |
| 1906 // elements to mark. | 1907 // elements to trace. |
| 1907 size_t length = header->payloadSize() / sizeof(T); | 1908 size_t length = header->payloadSize() / sizeof(T); |
| 1908 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER | 1909 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER |
| 1909 // Have no option but to mark the whole container as accessible, but | 1910 // As commented above, HeapVectorBacking can trace unused slots |
| 1910 // this trace() is only used for backing stores that are identified | 1911 // (which are already zeroed out). |
| 1911 // as roots independent from a vector. | |
| 1912 ANNOTATE_CHANGE_SIZE(array, length, 0, length); | 1912 ANNOTATE_CHANGE_SIZE(array, length, 0, length); |
| 1913 #endif | 1913 #endif |
| 1914 for (size_t i = 0; i < length; ++i) | 1914 for (size_t i = 0; i < length; ++i) |
| 1915 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[ i]); | 1915 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[ i]); |
| 1916 return false; | 1916 return false; |
| 1917 } | 1917 } |
| 1918 }; | 1918 }; |
| 1919 | 1919 |
| 1920 // Almost all hash table backings are visited with this specialization. | 1920 // Almost all hash table backings are visited with this specialization. |
| 1921 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> | 1921 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2182 { | 2182 { |
| 2183 #if ENABLE(ASSERT) | 2183 #if ENABLE(ASSERT) |
| 2184 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing >::index()); | 2184 assertObjectHasGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing >::index()); |
| 2185 #endif | 2185 #endif |
| 2186 } | 2186 } |
| 2187 }; | 2187 }; |
| 2188 | 2188 |
| 2189 template<typename T, typename Traits> | 2189 template<typename T, typename Traits> |
| 2190 void HeapVectorBacking<T, Traits>::finalize(void* pointer) | 2190 void HeapVectorBacking<T, Traits>::finalize(void* pointer) |
| 2191 { | 2191 { |
| 2192 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 | |
| 2194 // and thus cannot avoid calling finalizers for all slots in the backing. | |
| 2195 // This works correctly as long as unused slots are cleared out | |
| 2196 // (this is done by VectorUnusedSlotClearer) and T can be initialized | |
| 2197 // with memset (if T can be initialized with memset, it is safe to | |
| 2198 // treat a zeroed object as a valid object). | |
| 2199 static_assert(Traits::canInitializeWithMemset, "HeapVectorBacking doesn't su pport objects that cannot be initialized with memset."); | |
| 2200 | |
| 2192 ASSERT(!WTF::IsTriviallyDestructible<T>::value); | 2201 ASSERT(!WTF::IsTriviallyDestructible<T>::value); |
| 2193 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); | 2202 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); |
| 2194 // Use the payload size as recorded by the heap to determine how many | 2203 // Use the payload size as recorded by the heap to determine how many |
| 2195 // elements to finalize. | 2204 // elements to finalize. |
| 2196 size_t length = header->payloadSize() / sizeof(T); | 2205 size_t length = header->payloadSize() / sizeof(T); |
| 2197 T* buffer = reinterpret_cast<T*>(pointer); | 2206 T* buffer = reinterpret_cast<T*>(pointer); |
| 2198 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER | 2207 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER |
| 2199 // Like for trace(), have no option but to mark the whole container | 2208 // As commented above, HeapVectorBacking calls finalizers for unused slots |
| 2200 // as accessible. | 2209 // (which are already zeroed out). |
| 2201 ANNOTATE_CHANGE_SIZE(buffer, length, 0, length); | 2210 ANNOTATE_CHANGE_SIZE(buffer, length, 0, length); |
| 2202 #endif | 2211 #endif |
| 2203 for (unsigned i = 0; i < length; ++i) | 2212 for (unsigned i = 0; i < length; ++i) |
| 2204 buffer[i].~T(); | 2213 buffer[i].~T(); |
| 2205 } | 2214 } |
| 2206 | 2215 |
| 2207 template<typename Table> | 2216 template<typename Table> |
| 2208 void HeapHashTableBacking<Table>::finalize(void* pointer) | 2217 void HeapHashTableBacking<Table>::finalize(void* pointer) |
| 2209 { | 2218 { |
| 2210 using Value = typename Table::ValueType; | 2219 using Value = typename Table::ValueType; |
| 2211 ASSERT(!WTF::IsTriviallyDestructible<Value>::value); | 2220 ASSERT(!WTF::IsTriviallyDestructible<Value>::value); |
| 2212 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); | 2221 HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer); |
| 2213 // Use the payload size as recorded by the heap to determine how many | 2222 // Use the payload size as recorded by the heap to determine how many |
| 2214 // elements to finalize. | 2223 // elements to finalize. |
| 2215 size_t length = header->payloadSize() / sizeof(Value); | 2224 size_t length = header->payloadSize() / sizeof(Value); |
| 2216 Value* table = reinterpret_cast<Value*>(pointer); | 2225 Value* table = reinterpret_cast<Value*>(pointer); |
| 2217 for (unsigned i = 0; i < length; ++i) { | 2226 for (unsigned i = 0; i < length; ++i) { |
| 2218 if (!Table::isEmptyOrDeletedBucket(table[i])) | 2227 if (!Table::isEmptyOrDeletedBucket(table[i])) |
| 2219 table[i].~Value(); | 2228 table[i].~Value(); |
| 2220 } | 2229 } |
| 2221 } | 2230 } |
| 2222 | 2231 |
| 2223 } // namespace blink | 2232 } // namespace blink |
| 2224 | 2233 |
| 2225 #endif // Heap_h | 2234 #endif // Heap_h |
| OLD | NEW |