 Chromium Code Reviews
 Chromium Code Reviews Issue 131803005:
  Add more oilpan collections support  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk
    
  
    Issue 131803005:
  Add more oilpan collections support  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk| 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 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 714 virtual void makeConsistentForGC(); | 714 virtual void makeConsistentForGC(); | 
| 715 virtual bool isConsistentForGC(); | 715 virtual bool isConsistentForGC(); | 
| 716 | 716 | 
| 717 ThreadState* threadState() { return m_threadState; } | 717 ThreadState* threadState() { return m_threadState; } | 
| 718 HeapStats& stats() { return m_threadState->stats(); } | 718 HeapStats& stats() { return m_threadState->stats(); } | 
| 719 HeapContainsCache* heapContainsCache() { return m_threadState->heapContainsC ache(); } | 719 HeapContainsCache* heapContainsCache() { return m_threadState->heapContainsC ache(); } | 
| 720 | 720 | 
| 721 inline Address allocate(size_t, const GCInfo*); | 721 inline Address allocate(size_t, const GCInfo*); | 
| 722 void addToFreeList(Address, size_t); | 722 void addToFreeList(Address, size_t); | 
| 723 void addPageToPool(HeapPage<Header>*); | 723 void addPageToPool(HeapPage<Header>*); | 
| 724 inline size_t roundedAllocationSize(size_t size) | 724 inline static size_t roundedAllocationSize(size_t size) | 
| 725 { | 725 { | 
| 726 return allocationSizeFromSize(size) - sizeof(Header); | 726 return allocationSizeFromSize(size) - sizeof(Header); | 
| 727 } | 727 } | 
| 728 | 728 | 
| 729 private: | 729 private: | 
| 730 // Once pages have been used for one thread heap they will never | 730 // Once pages have been used for one thread heap they will never | 
| 731 // be reused for another thread heap. Instead of unmapping, we add | 731 // be reused for another thread heap. Instead of unmapping, we add | 
| 732 // the pages to a pool of pages to be reused later by this thread | 732 // the pages to a pool of pages to be reused later by this thread | 
| 733 // heap. This is done as a security feature to avoid type | 733 // heap. This is done as a security feature to avoid type | 
| 734 // confusion. The heap is type segregated by having separate | 734 // confusion. The heap is type segregated by having separate | 
| (...skipping 10 matching lines...) Expand all Loading... | |
| 745 | 745 | 
| 746 PageMemory* storage() { return m_storage; } | 746 PageMemory* storage() { return m_storage; } | 
| 747 PagePoolEntry* next() { return m_next; } | 747 PagePoolEntry* next() { return m_next; } | 
| 748 | 748 | 
| 749 private: | 749 private: | 
| 750 PageMemory* m_storage; | 750 PageMemory* m_storage; | 
| 751 PagePoolEntry* m_next; | 751 PagePoolEntry* m_next; | 
| 752 }; | 752 }; | 
| 753 | 753 | 
| 754 HEAP_EXPORT Address outOfLineAllocate(size_t, const GCInfo*); | 754 HEAP_EXPORT Address outOfLineAllocate(size_t, const GCInfo*); | 
| 755 size_t allocationSizeFromSize(size_t); | 755 static size_t allocationSizeFromSize(size_t); | 
| 756 void addPageToHeap(const GCInfo*); | 756 void addPageToHeap(const GCInfo*); | 
| 757 HEAP_EXPORT Address allocateLargeObject(size_t, const GCInfo*); | 757 HEAP_EXPORT Address allocateLargeObject(size_t, const GCInfo*); | 
| 758 Address currentAllocationPoint() const { return m_currentAllocationPoint; } | 758 Address currentAllocationPoint() const { return m_currentAllocationPoint; } | 
| 759 size_t remainingAllocationSize() const { return m_remainingAllocationSize; } | 759 size_t remainingAllocationSize() const { return m_remainingAllocationSize; } | 
| 760 bool ownsNonEmptyAllocationArea() const { return currentAllocationPoint() && remainingAllocationSize(); } | 760 bool ownsNonEmptyAllocationArea() const { return currentAllocationPoint() && remainingAllocationSize(); } | 
| 761 void setAllocationPoint(Address point, size_t size) | 761 void setAllocationPoint(Address point, size_t size) | 
| 762 { | 762 { | 
| 763 ASSERT(!point || heapPageFromAddress(point)); | 763 ASSERT(!point || heapPageFromAddress(point)); | 
| 764 ASSERT(size <= HeapPage<Header>::payloadSize()); | 764 ASSERT(size <= HeapPage<Header>::payloadSize()); | 
| 765 m_currentAllocationPoint = point; | 765 m_currentAllocationPoint = point; | 
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1154 memcpy(address, previous, copySize); | 1154 memcpy(address, previous, copySize); | 
| 1155 return address; | 1155 return address; | 
| 1156 } | 1156 } | 
| 1157 | 1157 | 
| 1158 class HeapAllocatorQuantizer { | 1158 class HeapAllocatorQuantizer { | 
| 1159 public: | 1159 public: | 
| 1160 template<typename T> | 1160 template<typename T> | 
| 1161 static size_t quantizedSize(size_t count) | 1161 static size_t quantizedSize(size_t count) | 
| 1162 { | 1162 { | 
| 1163 RELEASE_ASSERT(count <= kMaxUnquantizedAllocation / sizeof(T)); | 1163 RELEASE_ASSERT(count <= kMaxUnquantizedAllocation / sizeof(T)); | 
| 1164 return typename HeapTrait<T>::HeapType::roundedAllocationSize(count * si zeof(T)); | 1164 return HeapTrait<T>::HeapType::roundedAllocationSize(count * sizeof(T)); | 
| 1165 } | 1165 } | 
| 1166 static const size_t kMaxUnquantizedAllocation = maxHeapObjectSize; | 1166 static const size_t kMaxUnquantizedAllocation = maxHeapObjectSize; | 
| 1167 }; | 1167 }; | 
| 1168 | 1168 | 
| 1169 class HeapAllocator { | 1169 class HeapAllocator { | 
| 1170 public: | 1170 public: | 
| 1171 typedef HeapAllocatorQuantizer Quantizer; | 1171 typedef HeapAllocatorQuantizer Quantizer; | 
| 1172 typedef WebCore::Visitor Visitor; | 1172 typedef WebCore::Visitor Visitor; | 
| 1173 static const bool isGarbageCollected = true; | 1173 static const bool isGarbageCollected = true; | 
| 1174 | 1174 | 
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1205 { | 1205 { | 
| 1206 visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->tr aceCallback()); | 1206 visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->tr aceCallback()); | 
| 1207 } | 1207 } | 
| 1208 | 1208 | 
| 1209 static void markNoTracing(Visitor* visitor, const void* t) | 1209 static void markNoTracing(Visitor* visitor, const void* t) | 
| 1210 { | 1210 { | 
| 1211 visitor->mark(t); | 1211 visitor->mark(t); | 
| 1212 } | 1212 } | 
| 1213 | 1213 | 
| 1214 template<typename T, typename Traits> | 1214 template<typename T, typename Traits> | 
| 1215 static void mark(Visitor* visitor, T& t) | 1215 static void trace(Visitor* visitor, T& t) | 
| 1216 { | 1216 { | 
| 1217 CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak, false, T, Traits>::mark(visitor, t); | 1217 CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak, false, T, Traits>::mark(visitor, t); | 
| 1218 } | 1218 } | 
| 1219 | 1219 | 
| 1220 template<typename T> | 1220 template<typename T> | 
| 1221 static bool hasDeadMember(Visitor*, const T&) | 1221 static bool hasDeadMember(Visitor*, const T&) | 
| 1222 { | 1222 { | 
| 1223 return false; | 1223 return false; | 
| 1224 } | 1224 } | 
| 1225 | 1225 | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1272 }; | 1272 }; | 
| 1273 | 1273 | 
| 1274 template<typename T> | 1274 template<typename T> | 
| 1275 struct OtherType { | 1275 struct OtherType { | 
| 1276 typedef T* Type; | 1276 typedef T* Type; | 
| 1277 }; | 1277 }; | 
| 1278 | 1278 | 
| 1279 template<typename T> | 1279 template<typename T> | 
| 1280 static T& getOther(T* other) | 1280 static T& getOther(T* other) | 
| 1281 { | 1281 { | 
| 1282 return *(other); | 1282 return *other; | 
| 1283 } | 1283 } | 
| 1284 | 1284 | 
| 1285 private: | 1285 private: | 
| 1286 template<typename T, size_t u, typename V> friend class WTF::Vector; | 1286 template<typename T, size_t u, typename V> friend class WTF::Vector; | 
| 1287 template<typename T, typename U, typename V, typename W> friend class WTF::H ashSet; | 1287 template<typename T, typename U, typename V, typename W> friend class WTF::H ashSet; | 
| 1288 template<typename T, typename U, typename V, typename W, typename X, typenam e Y> friend class WTF::HashMap; | 1288 template<typename T, typename U, typename V, typename W, typename X, typenam e Y> friend class WTF::HashMap; | 
| 1289 }; | 1289 }; | 
| 1290 | 1290 | 
| 1291 // FIXME: These should just be template aliases: | |
| 1292 // | |
| 1293 // template<typename T, size_t inlineCapacity = 0> | |
| 1294 // using HeapVector = Vector<T, inlineCapacity, HeapAllocator>; | |
| 1295 // | |
| 1296 // as soon as all the compilers we care about support that. | |
| 1297 // MSVC supports it only in MSVC 2013. | |
| 
Nico
2014/08/29 19:41:41
We're now on 2013. Can this be simplified now?
 
Mads Ager (chromium)
2014/09/01 06:34:34
Thanks for the heads up! In that case we should be
 | |
| 1298 template< | |
| 1299 typename KeyArg, | |
| 1300 typename MappedArg, | |
| 1301 typename HashArg = typename DefaultHash<KeyArg>::Hash, | |
| 1302 typename KeyTraitsArg = HashTraits<KeyArg>, | |
| 1303 typename MappedTraitsArg = HashTraits<MappedArg> > | |
| 1304 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, Map pedTraitsArg, HeapAllocator> { }; | |
| 1305 | |
| 1306 template< | |
| 1307 typename ValueArg, | |
| 1308 typename HashArg = typename DefaultHash<ValueArg>::Hash, | |
| 1309 typename TraitsArg = HashTraits<ValueArg> > | |
| 1310 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> { }; | |
| 1311 | |
| 1312 template<typename T, size_t inlineCapacity = 0> | |
| 1313 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { | |
| 1314 public: | |
| 1315 HeapVector() { } | |
| 1316 | |
| 1317 explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>( size) | |
| 1318 { | |
| 1319 } | |
| 1320 | |
| 1321 template<size_t otherCapacity> | |
| 1322 HeapVector(const HeapVector<T, otherCapacity>& other) | |
| 1323 : Vector<T, inlineCapacity, HeapAllocator>(other) | |
| 1324 { | |
| 1325 } | |
| 1326 | |
| 1327 template<typename U> | |
| 1328 void append(const U& other) | |
| 1329 { | |
| 1330 Vector<T, inlineCapacity, HeapAllocator>::append(other); | |
| 1331 } | |
| 1332 | |
| 1333 template<typename U, size_t otherCapacity> | |
| 1334 void append(const HeapVector<U, otherCapacity>& other) | |
| 1335 { | |
| 1336 const Vector<U, otherCapacity, HeapAllocator>& otherVector = other; | |
| 1337 Vector<T, inlineCapacity, HeapAllocator>::append(otherVector); | |
| 1338 } | |
| 1339 }; | |
| 1340 | |
| 1341 template<typename Key, typename Value> | |
| 1342 struct ThreadingTrait<HeapHashMap<Key, Value> > : public ThreadingTrait<HashMap< Key, Value, HeapAllocator> > { }; | |
| 1343 template<typename Value> | |
| 1344 struct ThreadingTrait<HeapHashSet<Value> > : public ThreadingTrait<HashSet<Value , HeapAllocator> > { }; | |
| 1345 template<typename T, size_t inlineCapacity> | |
| 1346 struct ThreadingTrait<HeapVector<T, inlineCapacity> > : public ThreadingTrait<Ve ctor<T, inlineCapacity, HeapAllocator> > { }; | |
| 1347 | |
| 1291 // The standard implementation of GCInfoTrait<T>::get() just returns a static | 1348 // The standard implementation of GCInfoTrait<T>::get() just returns a static | 
| 1292 // from the class T, but we can't do that for HashMap, HashSet and Vector | 1349 // from the class T, but we can't do that for HashMap, HashSet and Vector | 
| 1293 // because they are in WTF and know nothing of GCInfos. Instead we have a | 1350 // because they are in WTF and know nothing of GCInfos. Instead we have a | 
| 1294 // specialization of GCInfoTrait for these three classes here. | 1351 // specialization of GCInfoTrait for these three classes here. | 
| 1295 | 1352 | 
| 1296 template<typename Key, typename Value, typename T, typename U, typename V> | 1353 template<typename Key, typename Value, typename T, typename U, typename V> | 
| 1297 struct GCInfoTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > { | 1354 struct GCInfoTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > { | 
| 1298 static const GCInfo* get() { return &info; } | 1355 static const GCInfo* get() { return &info; } | 
| 1299 static const GCInfo info; | 1356 static const GCInfo info; | 
| 1300 }; | 1357 }; | 
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1555 visitor->mark(backing, 0); | 1612 visitor->mark(backing, 0); | 
| 1556 } | 1613 } | 
| 1557 static void checkTypeMarker(Visitor* visitor, const Backing* backing) | 1614 static void checkTypeMarker(Visitor* visitor, const Backing* backing) | 
| 1558 { | 1615 { | 
| 1559 #ifndef NDEBUG | 1616 #ifndef NDEBUG | 
| 1560 visitor->checkTypeMarker(const_cast<Backing*>(backing), getTypeMarker<Ba cking>()); | 1617 visitor->checkTypeMarker(const_cast<Backing*>(backing), getTypeMarker<Ba cking>()); | 
| 1561 #endif | 1618 #endif | 
| 1562 } | 1619 } | 
| 1563 }; | 1620 }; | 
| 1564 | 1621 | 
| 1622 template<typename T, typename U, typename V, typename W, typename X> | |
| 1623 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator> > { }; | |
| 1624 template<typename T, typename U, typename V> | |
| 1625 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V, HeapAllocator> > { }; | |
| 1626 template<typename T, size_t inlineCapacity> | |
| 1627 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T , inlineCapacity, HeapAllocator> > { }; | |
| 1628 | |
| 1565 template<typename T> | 1629 template<typename T> | 
| 1566 struct IfWeakMember; | 1630 struct IfWeakMember; | 
| 1567 | 1631 | 
| 1568 template<typename T> | 1632 template<typename T> | 
| 1569 struct IfWeakMember { | 1633 struct IfWeakMember { | 
| 1570 template<typename U> | 1634 template<typename U> | 
| 1571 static bool isDead(Visitor*, const U&) { return false; } | 1635 static bool isDead(Visitor*, const U&) { return false; } | 
| 1572 }; | 1636 }; | 
| 1573 | 1637 | 
| 1574 template<typename T> | 1638 template<typename T> | 
| 1575 struct IfWeakMember<WeakMember<T> > { | 1639 struct IfWeakMember<WeakMember<T> > { | 
| 1576 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); } | 1640 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); } | 
| 1577 }; | 1641 }; | 
| 1578 | 1642 | 
| 1579 template<typename K, typename V, typename HashFunctions, typename KeyTraits, typ ename ValueTraits> | |
| 1580 void processWeakOffHeapHashMap(Visitor* visitor, void* self) | |
| 1581 { | |
| 1582 typedef HashMap<K, V, WTF::DefaultAllocator, HashFunctions, KeyTraits, Value Traits> Map; | |
| 1583 Map* map = reinterpret_cast<Map*>(self); | |
| 1584 // Collect up keys here because we can't modify a hash map while iterating | |
| 1585 // over it. | |
| 1586 Vector<K> deletionKeys; | |
| 1587 ASSERT(KeyTraits::isWeak || ValueTraits::isWeak); | |
| 1588 typedef typename Map::iterator Iterator; | |
| 1589 Iterator endIterator(map->end()); | |
| 1590 for (Iterator it = map->begin(); it != endIterator; ++it) { | |
| 1591 if (IfWeakMember<K>::isDead(visitor, it->key)) | |
| 1592 deletionKeys.append(it->key); | |
| 1593 else if (IfWeakMember<V>::isDead(visitor, it->value)) | |
| 1594 deletionKeys.append(it->key); | |
| 1595 } | |
| 1596 size_t size = deletionKeys.size(); | |
| 1597 if (size == map->size()) { | |
| 1598 map->clear(); | |
| 1599 return; | |
| 1600 } | |
| 1601 for (size_t i = 0; i < size; i++) | |
| 1602 map->remove(deletionKeys[i]); | |
| 1603 } | |
| 1604 | |
| 1605 template<typename T, typename HashFunctions, typename Traits> | |
| 1606 void processWeakOffHeapHashSet(Visitor* visitor, void* self) | |
| 1607 { | |
| 1608 typedef HashSet<T, WTF::DefaultAllocator, HashFunctions, Traits> Set; | |
| 1609 Set* set = reinterpret_cast<Set*>(self); | |
| 1610 ASSERT(Traits::isWeak); | |
| 1611 // Collect up keys here because we can't modify a hash set while iterating | |
| 1612 // over it. | |
| 1613 Vector<T> deletionKeys; | |
| 1614 typedef typename Set::iterator Iterator; | |
| 1615 Iterator endIterator(set->end()); | |
| 1616 for (Iterator it = set->begin(); it != endIterator; ++it) { | |
| 1617 if (IfWeakMember<T>::isDead(visitor, *it)) | |
| 1618 deletionKeys.append(*it); | |
| 1619 } | |
| 1620 size_t size = deletionKeys.size(); | |
| 1621 if (size == set->size()) { | |
| 1622 set->clear(); | |
| 1623 return; | |
| 1624 } | |
| 1625 for (size_t i = 0; i < size; i++) | |
| 1626 set->remove(deletionKeys[i]); | |
| 1627 } | |
| 1628 | |
| 1629 #if COMPILER(CLANG) | 1643 #if COMPILER(CLANG) | 
| 1630 // Clang does not export the symbols that we have explicitly asked it | 1644 // Clang does not export the symbols that we have explicitly asked it | 
| 1631 // to export. This forces it to export all the methods from ThreadHeap. | 1645 // to export. This forces it to export all the methods from ThreadHeap. | 
| 1632 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf o*); | 1646 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf o*); | 
| 1633 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); | 1647 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); | 
| 1634 extern template class HEAP_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; | 1648 extern template class HEAP_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; | 
| 1635 extern template class HEAP_EXPORT ThreadHeap<HeapObjectHeader>; | 1649 extern template class HEAP_EXPORT ThreadHeap<HeapObjectHeader>; | 
| 1636 #endif | 1650 #endif | 
| 1637 | 1651 | 
| 1638 } | 1652 } | 
| 1639 | 1653 | 
| 1640 #endif // Heap_h | 1654 #endif // Heap_h | 
| OLD | NEW |