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

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

Issue 319593004: Oilpan:Allow custom handling of classes that contain weak pointers that are embedded in collections. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Feedback from Haraken Created 6 years, 6 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
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 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 } 1447 }
1448 1448
1449 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo Tracing(t); } 1449 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo Tracing(t); }
1450 1450
1451 template<typename T, typename Traits> 1451 template<typename T, typename Traits>
1452 static void trace(Visitor* visitor, T& t) 1452 static void trace(Visitor* visitor, T& t)
1453 { 1453 {
1454 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits:: isWeak, WeakPointersActWeak, T, Traits>::trace(visitor, t); 1454 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits:: isWeak, WeakPointersActWeak, T, Traits>::trace(visitor, t);
1455 } 1455 }
1456 1456
1457 template<typename T>
1458 static bool hasDeadMember(Visitor*, const T&)
1459 {
1460 return false;
1461 }
1462
1463 template<typename T>
1464 static bool hasDeadMember(Visitor* visitor, const Member<T>& t)
1465 {
1466 ASSERT(visitor->isAlive(t));
1467 return false;
1468 }
1469
1470 template<typename T>
1471 static bool hasDeadMember(Visitor* visitor, const WeakMember<T>& t)
1472 {
1473 return !visitor->isAlive(t);
1474 }
1475
1476 template<typename T, typename U>
1477 static bool hasDeadMember(Visitor* visitor, const WTF::KeyValuePair<T, U>& t )
1478 {
1479 return hasDeadMember(visitor, t.key) || hasDeadMember(visitor, t.value);
1480 }
1481
1482 template<typename T>
1483 static bool hasDeadMember(Visitor*, const WTF::LinkedHashSetNode<T>&);
1484
1485 static void registerWeakMembers(Visitor* visitor, const void* closure, const void* object, WeakPointerCallback callback) 1457 static void registerWeakMembers(Visitor* visitor, const void* closure, const void* object, WeakPointerCallback callback)
1486 { 1458 {
1487 visitor->registerWeakMembers(closure, object, callback); 1459 visitor->registerWeakMembers(closure, object, callback);
1488 } 1460 }
1489 1461
1490 template<typename T> 1462 template<typename T>
1491 struct ResultType { 1463 struct ResultType {
1492 typedef T* Type; 1464 typedef T* Type;
1493 }; 1465 };
1494 1466
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 } 1662 }
1691 1663
1692 template<typename U> 1664 template<typename U>
1693 void append(const U& other) 1665 void append(const U& other)
1694 { 1666 {
1695 Deque<T, inlineCapacity, HeapAllocator>::append(other); 1667 Deque<T, inlineCapacity, HeapAllocator>::append(other);
1696 } 1668 }
1697 }; 1669 };
1698 1670
1699 template<typename T> 1671 template<typename T>
1700 bool HeapAllocator::hasDeadMember(Visitor* visitor, const WTF::LinkedHashSetNode <T>& t)
1701 {
1702 return hasDeadMember(visitor, t.m_value);
1703 }
1704
1705 template<typename T>
1706 struct ThreadingTrait<Member<T> > { 1672 struct ThreadingTrait<Member<T> > {
1707 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; 1673 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1708 }; 1674 };
1709 1675
1710 template<typename T> 1676 template<typename T>
1711 struct ThreadingTrait<WeakMember<T> > { 1677 struct ThreadingTrait<WeakMember<T> > {
1712 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; 1678 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1713 }; 1679 };
1714 1680
1715 template<typename Key, typename Value, typename T, typename U, typename V> 1681 template<typename Key, typename Value, typename T, typename U, typename V>
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
2003 Table::ValueTraits::needsDestruction, 1969 Table::ValueTraits::needsDestruction,
2004 WTF::IsPolymorphic<TargetType>::value, 1970 WTF::IsPolymorphic<TargetType>::value,
2005 #if ENABLE(GC_TRACING) 1971 #if ENABLE(GC_TRACING)
2006 TypenameStringTrait<TargetType>::get() 1972 TypenameStringTrait<TargetType>::get()
2007 #endif 1973 #endif
2008 }; 1974 };
2009 return &info; 1975 return &info;
2010 } 1976 }
2011 }; 1977 };
2012 1978
2013 template<typename T, typename Traits> 1979 // This is for tracing inside collections that have special support for weak
2014 struct BaseVisitVectorBackingTrait { 1980 // pointers. This is normally handled through the HashTraits, but it is not
2015 static void trace(WebCore::Visitor* visitor, void* self) 1981 // feasible to add methods for handling tracing to the hash traits of WTF
1982 // classes like KeyValuePair, which is used to implement HashMap. This trait
1983 // lets us add custom handling for such classes.
1984 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits>
1985 struct TraceInCollectionTrait;
1986
1987 // Catch-all for types that have a way to trace that don't have special
1988 // handling for weakness in collections. This means that if this type
1989 // contains WeakMember fields, they will simply be zeroed, but the entry
1990 // will not be removed from the collection. This always happens for
1991 // things in vectors, which don't currently support special handling of
1992 // weak elements.
1993 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts>
1994 struct TraceInCollectionTrait<false, strongify, T, Traits> {
1995 static void trace(Visitor* visitor, T& t)
1996 {
1997 TraceTrait<T>::trace(visitor, &t);
1998 }
1999 };
2000
2001 // Catch-all for things that have HashTrait support for tracing with weakness.
2002 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts>
2003 struct TraceInCollectionTrait<true, strongify, T, Traits> {
2004 static void trace(Visitor* visitor, T& t)
2005 {
2006 Traits::traceInCollection(visitor, t, strongify);
2007 }
2008 };
2009
2010 // Vector backing that needs marking. We don't support weak members in vectors.
2011 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts>
2012 struct TraceInCollectionTrait<false, strongify, HeapVectorBacking<T, Traits>, vo id> {
2013 static void trace(Visitor* visitor, void* self)
2016 { 2014 {
2017 // The allocator can oversize the allocation a little, according to 2015 // The allocator can oversize the allocation a little, according to
2018 // the allocation granularity. The extra size is included in the 2016 // the allocation granularity. The extra size is included in the
2019 // payloadSize call below, since there is nowhere to store the 2017 // payloadSize call below, since there is nowhere to store the
2020 // originally allocated memory. This assert ensures that visiting the 2018 // originally allocated memory. This assert ensures that visiting the
2021 // last bit of memory can't cause trouble. 2019 // last bit of memory can't cause trouble.
2022 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp uriousVisits); 2020 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp uriousVisits);
2023 2021
2024 T* array = reinterpret_cast<T*>(self); 2022 T* array = reinterpret_cast<T*>(self);
2025 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self); 2023 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self);
2026 // Use the payload size as recorded by the heap to determine how many 2024 // Use the payload size as recorded by the heap to determine how many
2027 // elements to mark. 2025 // elements to mark.
2028 size_t length = header->payloadSize() / sizeof(T); 2026 size_t length = header->payloadSize() / sizeof(T);
2029 for (size_t i = 0; i < length; i++) 2027 for (size_t i = 0; i < length; i++)
2030 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai ts::isWeak, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]); 2028 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai ts::isWeak, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]);
2031 } 2029 }
2032 }; 2030 };
2033 2031
2034 // Almost all hash table backings are visited with this specialization. 2032 // Almost all hash table backings are visited with this specialization.
2035 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> 2033 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table>
2036 struct BaseVisitHashTableBackingTrait { 2034 struct TraceInCollectionTrait<false, strongify, HeapHashTableBacking<Table>, voi d> {
2037 typedef typename Table::ValueType Value; 2035 typedef typename Table::ValueType Value;
2038 typedef typename Table::ValueTraits Traits; 2036 typedef typename Table::ValueTraits Traits;
2039 static void trace(WebCore::Visitor* visitor, void* self) 2037 static void trace(Visitor* visitor, void* self)
2040 { 2038 {
2041 Value* array = reinterpret_cast<Value*>(self); 2039 Value* array = reinterpret_cast<Value*>(self);
2042 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self); 2040 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self);
2043 size_t length = header->payloadSize() / sizeof(Value); 2041 size_t length = header->payloadSize() / sizeof(Value);
2044 for (size_t i = 0; i < length; i++) { 2042 for (size_t i = 0; i < length; i++) {
2045 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) 2043 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i]))
2046 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::isWeak, strongify, Value, Traits>::trace(visitor, array[i]); 2044 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::isWeak, strongify, Value, Traits>::trace(visitor, array[i]);
2047 } 2045 }
2048 } 2046 }
2049 }; 2047 };
2050 2048
2051 // This specialization of BaseVisitHashTableBackingTrait is for the backing of 2049 // This specialization of TraceInCollectionTrait is for the backing of
2052 // HeapListHashSet. This is for the case that we find a reference to the 2050 // HeapListHashSet. This is for the case that we find a reference to the
2053 // backing from the stack. That probably means we have a GC while we are in a 2051 // backing from the stack. That probably means we have a GC while we are in a
2054 // ListHashSet method since normal API use does not put pointers to the backing 2052 // ListHashSet method since normal API use does not put pointers to the backing
2055 // on the stack. 2053 // on the stack.
2056 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X, typename Y> 2054 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, si ze_t inlineCapacity, typename T, typename U, typename V, typename W, typename X, typename Y>
2057 struct BaseVisitHashTableBackingTrait<strongify, WTF::HashTable<WTF::ListHashSet Node<NodeContents, HeapListHashSetAllocator<T, inlineCapacity> >*, U, V, W, X, Y , HeapAllocator> > { 2055 struct TraceInCollectionTrait<false, strongify, HeapHashTableBacking<WTF::HashTa ble<WTF::ListHashSetNode<NodeContents, HeapListHashSetAllocator<T, inlineCapacit y> >*, U, V, W, X, Y, HeapAllocator> >, void> {
2058 typedef WTF::ListHashSetNode<NodeContents, HeapListHashSetAllocator<T, inlin eCapacity> > Node; 2056 typedef WTF::ListHashSetNode<NodeContents, HeapListHashSetAllocator<T, inlin eCapacity> > Node;
2059 typedef WTF::HashTable<Node*, U, V, W, X, Y, HeapAllocator> Table; 2057 typedef WTF::HashTable<Node*, U, V, W, X, Y, HeapAllocator> Table;
2060 static void trace(WebCore::Visitor* visitor, void* self) 2058 static void trace(Visitor* visitor, void* self)
2061 { 2059 {
2062 Node** array = reinterpret_cast<Node**>(self); 2060 Node** array = reinterpret_cast<Node**>(self);
2063 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self); 2061 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec tHeader::fromPayload(self);
2064 size_t length = header->payloadSize() / sizeof(Node*); 2062 size_t length = header->payloadSize() / sizeof(Node*);
2065 for (size_t i = 0; i < length; i++) { 2063 for (size_t i = 0; i < length; i++) {
2066 if (!WTF::HashTableHelper<Node*, typename Table::ExtractorType, type name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) { 2064 if (!WTF::HashTableHelper<Node*, typename Table::ExtractorType, type name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) {
2067 traceListHashSetValue(visitor, array[i]->m_value); 2065 traceListHashSetValue(visitor, array[i]->m_value);
2068 // Just mark the node without tracing because we already traced 2066 // Just mark the node without tracing because we already traced
2069 // the contents, and there is no need to trace the next and 2067 // the contents, and there is no need to trace the next and
2070 // prev fields since iterating over the hash table backing will 2068 // prev fields since iterating over the hash table backing will
2071 // find the whole chain. 2069 // find the whole chain.
2072 visitor->markNoTracing(array[i]); 2070 visitor->markNoTracing(array[i]);
2073 } 2071 }
2074 } 2072 }
2075 } 2073 }
2076 }; 2074 };
2077 2075
2076 // Key value pairs, as used in HashMap. To disambiguate template choice we have
2077 // to have two versions, first the one with no special weak handling, then the
2078 // one with weak handling.
2079 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va lue, typename Traits>
2080 struct TraceInCollectionTrait<false, strongify, WTF::KeyValuePair<Key, Value>, T raits> {
2081 static void trace(Visitor* visitor, WTF::KeyValuePair<Key, Value>& self)
2082 {
2083 ASSERT(WTF::ShouldBeTraced<Traits>::value);
2084 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai ts>::value, false, strongify, Key, typename Traits::KeyTraits>::trace(visitor, s elf.key);
2085 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr aits>::value, false, strongify, Value, typename Traits::ValueTraits>::trace(visi tor, self.value);
2086 }
2087 };
2088
2078 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va lue, typename Traits> 2089 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va lue, typename Traits>
2079 struct BaseVisitKeyValuePairTrait { 2090 struct TraceInCollectionTrait<true, strongify, WTF::KeyValuePair<Key, Value>, Tr aits> {
2080 static void trace(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& self) 2091 static void trace(Visitor* visitor, WTF::KeyValuePair<Key, Value>& self)
2081 { 2092 {
2082 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif y == WeakPointersActStrong)); 2093 ASSERT(WTF::ShouldBeTraced<Traits>::value || strongify == WeakPointersAc tStrong);
2083 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai ts>::value, Traits::KeyTraits::isWeak, strongify, Key, typename Traits::KeyTrait s>::trace(visitor, self.key); 2094 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai ts>::value, Traits::KeyTraits::isWeak, strongify, Key, typename Traits::KeyTrait s>::trace(visitor, self.key);
2084 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr aits>::value, Traits::ValueTraits::isWeak, strongify, Value, typename Traits::Va lueTraits>::trace(visitor, self.value); 2095 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr aits>::value, Traits::ValueTraits::isWeak, strongify, Value, typename Traits::Va lueTraits>::trace(visitor, self.value);
2085 } 2096 }
2086 }; 2097 };
2087 2098
2099 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the
2100 // template.
2088 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename Traits> 2101 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename Traits>
2089 struct BaseVisitLinkedNodeTrait { 2102 struct TraceInCollectionTrait<false, strongify, WTF::LinkedHashSetNode<Value>, T raits> {
2090 static void trace(WebCore::Visitor* visitor, WTF::LinkedHashSetNode<Value>& self) 2103 static void trace(Visitor* visitor, WTF::LinkedHashSetNode<Value>& self)
2091 { 2104 {
2092 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif y == WeakPointersActStrong)); 2105 ASSERT(WTF::ShouldBeTraced<Traits>::value);
2093 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits:: isWeak, strongify, Value, Traits>::trace(visitor, self.m_value); 2106 TraceTrait<Value>::trace(visitor, &self.m_value);
2094 } 2107 }
2095 }; 2108 };
2096 2109
2097 // Catch-all for things that don't need marking and have no weak pointers. We 2110 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename Traits>
2098 // do nothing, even if WeakPointersActStrong. 2111 struct TraceInCollectionTrait<true, strongify, WTF::LinkedHashSetNode<Value>, Tr aits> {
2099 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename U> 2112 static void trace(Visitor* visitor, WTF::LinkedHashSetNode<Value>& self)
2100 struct CollectionBackingTraceTrait<false, false, strongify, T, U> { 2113 {
2101 static void trace(Visitor*, const T&) { } 2114 ASSERT(WTF::ShouldBeTraced<Traits>::value || strongify == WeakPointersAc tStrong);
2102 static void trace(Visitor*, const void*) { } 2115 TraceInCollectionTrait<true, strongify, Value, typename Traits::ValueTra its>::trace(visitor, self.m_value);
2103 }; 2116 }
2104
2105 // Catch-all for things that don't need marking. They have weak pointers, but
2106 // we are not marking weak pointers in this object in this GC.
2107 template<typename T, typename U>
2108 struct CollectionBackingTraceTrait<false, true, WeakPointersActWeak, T, U> {
2109 static void trace(Visitor*, const T&) { }
2110 static void trace(Visitor*, const void*) { }
2111 };
2112
2113 // For each type that we understand we have the strongified case and the
2114 // needsMarking case. The strongified case is where we would not normally need
2115 // to mark it, but it has weak pointers, and we are marking them as strong
2116 // because there is a live iterator that would be disturbed if the collection
2117 // were subject to weak processing right now. The needsMarking case is the
2118 // case for things that need marking, which may also be strongified (eg. for
2119 // a map pair that has a key that is weak and a value that needs marking).
2120
2121 // The body is the same for most objects, but there are two template
2122 // specializations because there is no way to express needsMarking || (isWeak
2123 // && WeakPointersActStrong) in a single specialization.
2124
2125 // Hash table that would not normally need marking, but strongified.
2126 template<typename Table>
2127 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, HeapHashT ableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<WeakPointersAc tStrong, Table> {
2128 };
2129
2130 // Hash table that needs marking, optionally also strongified.
2131 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Tab le>
2132 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapHashTableBacking <Table>, void> : public BaseVisitHashTableBackingTrait<strongify, Table> {
2133 };
2134
2135 // Key-value pair that would not normally need marking, but strongified.
2136 template<typename Key, typename Value, typename Traits>
2137 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::KeyV aluePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<WeakPointersAc tStrong, Key, Value, Traits> {
2138 };
2139
2140 // Key value pair that needs marking, optionally also strongified.
2141 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Key , typename Value, typename Traits>
2142 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::KeyValuePair<Ke y, Value>, Traits> : public BaseVisitKeyValuePairTrait<strongify, Key, Value, Tr aits> {
2143 };
2144
2145 // Linked hash set node that would not normally need marking, but strongified.
2146 template<typename Value, typename Traits>
2147 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::Link edHashSetNode<Value>, Traits> : public BaseVisitLinkedNodeTrait<WeakPointersActS trong, Value, Traits> {
2148 };
2149
2150 // Linked hash set node that needs marking, optionally also strongified.
2151 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Val ue, typename Traits>
2152 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::LinkedHashSetNo de<Value>, Traits> : public BaseVisitLinkedNodeTrait<strongify, Value, Traits> {
2153 }; 2117 };
2154 2118
2155 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of the se pointers). 2119 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of the se pointers).
2156 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in lineCapacity, typename Traits> 2120 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t in lineCapacity, typename Traits>
2157 struct CollectionBackingTraceTrait<true, false, strongify, WTF::ListHashSetNode< Value, HeapListHashSetAllocator<Value, inlineCapacity> >*, Traits> { 2121 struct TraceInCollectionTrait<false, strongify, WTF::ListHashSetNode<Value, Heap ListHashSetAllocator<Value, inlineCapacity> >*, Traits> {
2158 typedef WTF::ListHashSetNode<Value, HeapListHashSetAllocator<Value, inlineCa pacity> > Node; 2122 typedef WTF::ListHashSetNode<Value, HeapListHashSetAllocator<Value, inlineCa pacity> > Node;
2159 static void trace(WebCore::Visitor* visitor, Node* node) 2123 static void trace(Visitor* visitor, Node* node)
2160 { 2124 {
2161 traceListHashSetValue(visitor, node->m_value); 2125 traceListHashSetValue(visitor, node->m_value);
2162 // Just mark the node without tracing because we already traced the 2126 // Just mark the node without tracing because we already traced the
2163 // contents, and there is no need to trace the next and prev fields 2127 // contents, and there is no need to trace the next and prev fields
2164 // since iterating over the hash table backing will find the whole 2128 // since iterating over the hash table backing will find the whole
2165 // chain. 2129 // chain.
2166 visitor->markNoTracing(node); 2130 visitor->markNoTracing(node);
2167 } 2131 }
2168 }; 2132 };
2169 2133
2170 // Vector backing that needs marking. We don't support weak members in vectors, 2134 // FIXME: oilpan: Perhaps we don't need this any more.
2171 // so we don't need a strongified variant here. 2135 // Catch-all for things that don't need marking and have no weak pointers. We
2172 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> 2136 // do nothing, even if WeakPointersActStrong.
2173 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapVectorBacking<T, Traits>, void> : public BaseVisitVectorBackingTrait<T, Traits> { 2137 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename U>
2138 struct CollectionBackingTraceTrait<false, false, strongify, T, U> {
2139 static void trace(Visitor*, T&) { }
2174 }; 2140 };
2175 2141
2176 // Member always needs marking, never weak. 2142 // Catch-all for things that don't need marking. They have weak pointers, but
2177 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai ts> 2143 // we are not marking weak pointers in this object in this GC.
2178 struct CollectionBackingTraceTrait<true, false, strongify, Member<T>, Traits> { 2144 template<typename T, typename U>
2179 static void trace(WebCore::Visitor* visitor, Member<T> self) 2145 struct CollectionBackingTraceTrait<false, true, WeakPointersActWeak, T, U> {
2180 { 2146 static void trace(Visitor*, T&) { }
2181 visitor->mark(self.get());
2182 }
2183 }; 2147 };
2184 2148
2185 // Weak member never has needsMarking, always weak, strongified case. 2149 // Things that need marking because they contain weak pointers that we are makin g
2150 // strong for this GC because there is an outstanding iterator that would be
2151 // disturbed if we started removing entries from the colletion.
2186 template<typename T, typename Traits> 2152 template<typename T, typename Traits>
2187 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WeakMembe r<T>, Traits> { 2153 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, T, Traits > {
Mads Ager (chromium) 2014/06/06 09:59:16 I'm a little lost in boolean parameters. Maybe we
Erik Corry 2014/06/06 12:37:21 The true means that this is a specialization for t
2188 static void trace(WebCore::Visitor* visitor, WeakMember<T> self) 2154 static void trace(Visitor* visitor, T& t) { TraceInCollectionTrait<true, Wea kPointersActStrong, T, Traits>::trace(visitor, t); }
2189 { 2155 static void trace(Visitor* visitor, void* t) { TraceInCollectionTrait<true, WeakPointersActStrong, T, Traits>::trace(visitor, t); }
2190 // This can mark weak members as if they were strong. The reason we
2191 // need this is that we don't do weak processing unless we reach the
2192 // backing only through the hash table. Reaching it in any other way
2193 // makes it impossible to update the size and deleted slot count of the
2194 // table, and exposes us to weak processing during iteration issues.
2195 visitor->mark(self.get());
2196 }
2197 }; 2156 };
2198 2157
2199 // Catch-all for things that have a way to trace. For things that contain weak 2158 // Things that need marking because they contain strong pointers
2200 // pointers they will generally be visited weakly even if
2201 // WeakPointersActStrong. This is a deliberate choice: We currently don't
2202 // strongify weak members that are embedded in larger structures, they are just
2203 // zeroed during weak processing without the whole structure being
2204 // removed from the collection.
2205 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> 2159 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits>
2206 struct CollectionBackingTraceTrait<true, isWeak, strongify, T, Traits> { 2160 struct CollectionBackingTraceTrait<true, isWeak, strongify, T, Traits> {
2207 static void trace(WebCore::Visitor* visitor, T& t) 2161 static void trace(Visitor* visitor, T& t) { TraceInCollectionTrait<isWeak, s trongify, T, Traits>::trace(visitor, t); }
2162 template <typename U>
2163 static void trace(Visitor* visitor, U* t) { TraceInCollectionTrait<isWeak, s trongify, T, Traits>::trace(visitor, T(t)); }
2164 };
2165
2166 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits< T> {
2167 // We want to treat the object as a weak object in the sense that it can
2168 // disappear from hash sets and hash maps.
2169 static const bool isWeak = true;
2170 // Normally whether or not an object needs tracing is inferred
2171 // automatically from the presence of the trace method, but we don't
2172 // necessarily have a trace method, and we may not need one because T
2173 // can perhaps only be allocated inside collections, never as indpendent
2174 // objects. Explicitly mark this as needing tracing and it will be traced
2175 // in collections using the traceInCollection method, which it must have.
2176 template<typename U = void> struct NeedsTracingLazily {
2177 static const bool value = true;
2178 };
2179 // This method is called at the end of GC to test which elements should be
2180 // removed from the collection. It returns true if the object contains
2181 // non-live pointers. If this method incorrectly returns false, then we can
2182 // have dangerous dangling pointers!
2183 template<typename Visitor> static bool shouldRemoveFromCollection(Visitor* v isitor, T& t)
2208 { 2184 {
2209 TraceTrait<T>::trace(visitor, &t); 2185 return t.shouldRemoveFromCollection(visitor);
2186 }
2187 // The traceInCollection method traces differently depending on whether we
2188 // are strongifying the trace operation. We strongify the trace operation
2189 // when there are active iterators on the object. In this case all
2190 // WeakMembers are marked like strong members so that elements do not
2191 // suddenly disappear during iteration.
2192 static void traceInCollection(WebCore::Visitor* visitor, T& t, WebCore::Shou ldWeakPointersBeMarkedStrongly strongify)
2193 {
2194 t.traceInCollection(visitor, strongify);
2210 } 2195 }
2211 }; 2196 };
2212 2197
2213 template<typename T, typename Traits> 2198 template<typename T, typename Traits>
2214 struct TraceTrait<HeapVectorBacking<T, Traits> > { 2199 struct TraceTrait<HeapVectorBacking<T, Traits> > {
2215 typedef HeapVectorBacking<T, Traits> Backing; 2200 typedef HeapVectorBacking<T, Traits> Backing;
2216 static void trace(WebCore::Visitor* visitor, void* self) 2201 static void trace(Visitor* visitor, void* self)
2217 { 2202 {
2218 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectorsOrDequ es); 2203 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectorsOrDequ es);
2219 if (WTF::ShouldBeTraced<Traits>::value) 2204 if (WTF::ShouldBeTraced<Traits>::value)
2220 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, fals e, WeakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self ); 2205 TraceInCollectionTrait<Traits::isWeak, WeakPointersActWeak, HeapVect orBacking<T, Traits>, void>::trace(visitor, self);
2221 } 2206 }
2222 static void mark(Visitor* visitor, const Backing* backing) 2207 static void mark(Visitor* visitor, const Backing* backing)
2223 { 2208 {
2224 visitor->mark(backing, &trace); 2209 visitor->mark(backing, &trace);
2225 } 2210 }
2226 static void checkGCInfo(Visitor* visitor, const Backing* backing) 2211 static void checkGCInfo(Visitor* visitor, const Backing* backing)
2227 { 2212 {
2228 #ifndef NDEBUG 2213 #ifndef NDEBUG
2229 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing> ::get()); 2214 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing> ::get());
2230 #endif 2215 #endif
2231 } 2216 }
2232 }; 2217 };
2233 2218
2234 // The trace trait for the heap hashtable backing is used when we find a 2219 // The trace trait for the heap hashtable backing is used when we find a
2235 // direct pointer to the backing from the conservative stack scanner. This 2220 // direct pointer to the backing from the conservative stack scanner. This
2236 // normally indicates that there is an ongoing iteration over the table, and so 2221 // normally indicates that there is an ongoing iteration over the table, and so
2237 // we disable weak processing of table entries. When the backing is found 2222 // we disable weak processing of table entries. When the backing is found
2238 // through the owning hash table we mark differently, in order to do weak 2223 // through the owning hash table we mark differently, in order to do weak
2239 // processing. 2224 // processing.
2240 template<typename Table> 2225 template<typename Table>
2241 struct TraceTrait<HeapHashTableBacking<Table> > { 2226 struct TraceTrait<HeapHashTableBacking<Table> > {
2242 typedef HeapHashTableBacking<Table> Backing; 2227 typedef HeapHashTableBacking<Table> Backing;
2243 typedef typename Table::ValueTraits Traits; 2228 typedef typename Table::ValueTraits Traits;
2244 static void trace(WebCore::Visitor* visitor, void* self) 2229 static void trace(Visitor* visitor, void* self)
2245 { 2230 {
2246 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) 2231 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak)
2247 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai ts::isWeak, WeakPointersActStrong, Backing, void>::trace(visitor, self); 2232 TraceInCollectionTrait<false, WeakPointersActStrong, Backing, void>: :trace(visitor, self);
2248 } 2233 }
2249 static void mark(Visitor* visitor, const Backing* backing) 2234 static void mark(Visitor* visitor, const Backing* backing)
2250 { 2235 {
2251 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) 2236 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak)
2252 visitor->mark(backing, &trace); 2237 visitor->mark(backing, &trace);
2253 else 2238 else
2254 visitor->markNoTracing(backing); // If we know the trace function wi ll do nothing there is no need to call it. 2239 visitor->markNoTracing(backing); // If we know the trace function wi ll do nothing there is no need to call it.
2255 } 2240 }
2256 static void checkGCInfo(Visitor* visitor, const Backing* backing) 2241 static void checkGCInfo(Visitor* visitor, const Backing* backing)
2257 { 2242 {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2311 // to export. This forces it to export all the methods from ThreadHeap. 2296 // to export. This forces it to export all the methods from ThreadHeap.
2312 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf o*); 2297 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf o*);
2313 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); 2298 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*);
2314 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; 2299 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>;
2315 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; 2300 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>;
2316 #endif 2301 #endif
2317 2302
2318 } 2303 }
2319 2304
2320 #endif // Heap_h 2305 #endif // Heap_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698