Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: Source/platform/heap/Heap.h

Issue 1098953006: Oilpan: Support polymorphic objects in HeapVectorBackings (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | Source/platform/heap/Heap.cpp » ('j') | Source/wtf/Vector.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | Source/platform/heap/Heap.cpp » ('j') | Source/wtf/Vector.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698