| 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 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 #ifndef Heap_h | 31 #ifndef Heap_h |
| 32 #define Heap_h | 32 #define Heap_h |
| 33 | 33 |
| 34 #include "platform/PlatformExport.h" | 34 #include "platform/PlatformExport.h" |
| 35 #include "platform/heap/AddressSanitizer.h" | 35 #include "platform/heap/AddressSanitizer.h" |
| 36 #include "platform/heap/ThreadState.h" | 36 #include "platform/heap/ThreadState.h" |
| 37 #include "platform/heap/Visitor.h" | 37 #include "platform/heap/Visitor.h" |
| 38 | 38 |
| 39 #include "wtf/Assertions.h" | 39 #include "wtf/Assertions.h" |
| 40 #include "wtf/LinkedHashSet.h" |
| 40 #include "wtf/OwnPtr.h" | 41 #include "wtf/OwnPtr.h" |
| 41 #include "wtf/PassRefPtr.h" | 42 #include "wtf/PassRefPtr.h" |
| 42 | 43 |
| 43 #include <stdint.h> | 44 #include <stdint.h> |
| 44 | 45 |
| 45 namespace WebCore { | 46 namespace WebCore { |
| 46 | 47 |
| 47 const size_t blinkPageSizeLog2 = 17; | 48 const size_t blinkPageSizeLog2 = 17; |
| 48 const size_t blinkPageSize = 1 << blinkPageSizeLog2; | 49 const size_t blinkPageSize = 1 << blinkPageSizeLog2; |
| 49 const size_t blinkPageOffsetMask = blinkPageSize - 1; | 50 const size_t blinkPageOffsetMask = blinkPageSize - 1; |
| (...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 } | 1279 } |
| 1279 | 1280 |
| 1280 static void markNoTracing(Visitor* visitor, const void* t) | 1281 static void markNoTracing(Visitor* visitor, const void* t) |
| 1281 { | 1282 { |
| 1282 visitor->mark(t, reinterpret_cast<TraceCallback>(0)); | 1283 visitor->mark(t, reinterpret_cast<TraceCallback>(0)); |
| 1283 } | 1284 } |
| 1284 | 1285 |
| 1285 template<typename T, typename Traits> | 1286 template<typename T, typename Traits> |
| 1286 static void trace(Visitor* visitor, T& t) | 1287 static void trace(Visitor* visitor, T& t) |
| 1287 { | 1288 { |
| 1288 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, false, T, Traits>::mark(visitor, t); | 1289 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, WeakPointersActWeak, T, Traits>::mark(visitor, t); |
| 1289 } | 1290 } |
| 1290 | 1291 |
| 1291 template<typename T> | 1292 template<typename T> |
| 1292 static bool hasDeadMember(Visitor*, const T&) | 1293 static bool hasDeadMember(Visitor*, const T&) |
| 1293 { | 1294 { |
| 1294 return false; | 1295 return false; |
| 1295 } | 1296 } |
| 1296 | 1297 |
| 1297 template<typename T> | 1298 template<typename T> |
| 1298 static bool hasDeadMember(Visitor* visitor, const Member<T>& t) | 1299 static bool hasDeadMember(Visitor* visitor, const Member<T>& t) |
| 1299 { | 1300 { |
| 1300 ASSERT(visitor->isAlive(t)); | 1301 ASSERT(visitor->isAlive(t)); |
| 1301 return false; | 1302 return false; |
| 1302 } | 1303 } |
| 1303 | 1304 |
| 1304 template<typename T> | 1305 template<typename T> |
| 1305 static bool hasDeadMember(Visitor* visitor, const WeakMember<T>& t) | 1306 static bool hasDeadMember(Visitor* visitor, const WeakMember<T>& t) |
| 1306 { | 1307 { |
| 1307 return !visitor->isAlive(t); | 1308 return !visitor->isAlive(t); |
| 1308 } | 1309 } |
| 1309 | 1310 |
| 1310 template<typename T, typename U> | 1311 template<typename T, typename U> |
| 1311 static bool hasDeadMember(Visitor* visitor, const WTF::KeyValuePair<T, U>& t
) | 1312 static bool hasDeadMember(Visitor* visitor, const WTF::KeyValuePair<T, U>& t
) |
| 1312 { | 1313 { |
| 1313 return hasDeadMember(visitor, t.key) || hasDeadMember(visitor, t.value); | 1314 return hasDeadMember(visitor, t.key) || hasDeadMember(visitor, t.value); |
| 1314 } | 1315 } |
| 1315 | 1316 |
| 1317 template<typename T> |
| 1318 static bool hasDeadMember(Visitor*, const WTF::LinkedHashSetNode<T>&); |
| 1319 |
| 1316 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1320 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) |
| 1317 { | 1321 { |
| 1318 visitor->registerWeakMembers(closure, object, callback); | 1322 visitor->registerWeakMembers(closure, object, callback); |
| 1319 } | 1323 } |
| 1320 | 1324 |
| 1321 template<typename T> | 1325 template<typename T> |
| 1322 struct ResultType { | 1326 struct ResultType { |
| 1323 typedef T* Type; | 1327 typedef T* Type; |
| 1324 }; | 1328 }; |
| 1325 | 1329 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1373 typename KeyTraitsArg = HashTraits<KeyArg>, | 1377 typename KeyTraitsArg = HashTraits<KeyArg>, |
| 1374 typename MappedTraitsArg = HashTraits<MappedArg> > | 1378 typename MappedTraitsArg = HashTraits<MappedArg> > |
| 1375 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, Map
pedTraitsArg, HeapAllocator> { }; | 1379 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, Map
pedTraitsArg, HeapAllocator> { }; |
| 1376 | 1380 |
| 1377 template< | 1381 template< |
| 1378 typename ValueArg, | 1382 typename ValueArg, |
| 1379 typename HashArg = typename DefaultHash<ValueArg>::Hash, | 1383 typename HashArg = typename DefaultHash<ValueArg>::Hash, |
| 1380 typename TraitsArg = HashTraits<ValueArg> > | 1384 typename TraitsArg = HashTraits<ValueArg> > |
| 1381 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator>
{ }; | 1385 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator>
{ }; |
| 1382 | 1386 |
| 1387 template< |
| 1388 typename ValueArg, |
| 1389 typename HashArg = typename DefaultHash<ValueArg>::Hash, |
| 1390 typename TraitsArg = HashTraits<ValueArg> > |
| 1391 class HeapLinkedHashSet : public LinkedHashSet<ValueArg, HashArg, TraitsArg, Hea
pAllocator> { }; |
| 1392 |
| 1383 template<typename T, size_t inlineCapacity = 0> | 1393 template<typename T, size_t inlineCapacity = 0> |
| 1384 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { | 1394 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { |
| 1385 public: | 1395 public: |
| 1386 HeapVector() { } | 1396 HeapVector() { } |
| 1387 | 1397 |
| 1388 explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>(
size) | 1398 explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>(
size) |
| 1389 { | 1399 { |
| 1390 } | 1400 } |
| 1391 | 1401 |
| 1392 HeapVector(size_t size, const T& val) : Vector<T, inlineCapacity, HeapAlloca
tor>(size, val) | 1402 HeapVector(size_t size, const T& val) : Vector<T, inlineCapacity, HeapAlloca
tor>(size, val) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1407 | 1417 |
| 1408 template<typename U, size_t otherCapacity> | 1418 template<typename U, size_t otherCapacity> |
| 1409 void appendVector(const HeapVector<U, otherCapacity>& other) | 1419 void appendVector(const HeapVector<U, otherCapacity>& other) |
| 1410 { | 1420 { |
| 1411 const Vector<U, otherCapacity, HeapAllocator>& otherVector = other; | 1421 const Vector<U, otherCapacity, HeapAllocator>& otherVector = other; |
| 1412 Vector<T, inlineCapacity, HeapAllocator>::appendVector(otherVector); | 1422 Vector<T, inlineCapacity, HeapAllocator>::appendVector(otherVector); |
| 1413 } | 1423 } |
| 1414 }; | 1424 }; |
| 1415 | 1425 |
| 1416 template<typename T> | 1426 template<typename T> |
| 1427 bool HeapAllocator::hasDeadMember(Visitor* visitor, const WTF::LinkedHashSetNode
<T>& t) |
| 1428 { |
| 1429 return hasDeadMember(visitor, t.m_value); |
| 1430 } |
| 1431 |
| 1432 template<typename T> |
| 1417 struct ThreadingTrait<Member<T> > { | 1433 struct ThreadingTrait<Member<T> > { |
| 1418 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | 1434 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
| 1419 }; | 1435 }; |
| 1420 | 1436 |
| 1421 template<typename T> | 1437 template<typename T> |
| 1422 struct ThreadingTrait<WeakMember<T> > { | 1438 struct ThreadingTrait<WeakMember<T> > { |
| 1423 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; | 1439 static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
| 1424 }; | 1440 }; |
| 1425 | 1441 |
| 1426 template<typename Key, typename Value, typename T, typename U, typename V> | 1442 template<typename Key, typename Value, typename T, typename U, typename V> |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 static const GCInfo info; | 1511 static const GCInfo info; |
| 1496 }; | 1512 }; |
| 1497 | 1513 |
| 1498 template<typename T, typename U, typename V> | 1514 template<typename T, typename U, typename V> |
| 1499 const GCInfo GCInfoTrait<HashSet<T, U, V, HeapAllocator> >::info = { | 1515 const GCInfo GCInfoTrait<HashSet<T, U, V, HeapAllocator> >::info = { |
| 1500 TraceTrait<HashSet<T, U, V, HeapAllocator> >::trace, | 1516 TraceTrait<HashSet<T, U, V, HeapAllocator> >::trace, |
| 1501 0, | 1517 0, |
| 1502 false, // HashSet needs no finalizer. | 1518 false, // HashSet needs no finalizer. |
| 1503 }; | 1519 }; |
| 1504 | 1520 |
| 1521 template<typename T, typename U, typename V> |
| 1522 struct GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> > { |
| 1523 static const GCInfo* get() { return &info; } |
| 1524 static const GCInfo info; |
| 1525 }; |
| 1526 |
| 1527 template<typename T, typename U, typename V> |
| 1528 const GCInfo GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> >::info = { |
| 1529 TraceTrait<LinkedHashSet<T, U, V, HeapAllocator> >::trace, |
| 1530 LinkedHashSet<T, U, V, HeapAllocator>::finalize, |
| 1531 true, // Needs finalization. The anchor needs to unlink itself from the chai
n. |
| 1532 }; |
| 1533 |
| 1505 template<typename T> | 1534 template<typename T> |
| 1506 struct GCInfoTrait<Vector<T, 0, HeapAllocator> > { | 1535 struct GCInfoTrait<Vector<T, 0, HeapAllocator> > { |
| 1507 static const GCInfo* get() { return &info; } | 1536 static const GCInfo* get() { return &info; } |
| 1508 static const GCInfo info; | 1537 static const GCInfo info; |
| 1509 }; | 1538 }; |
| 1510 | 1539 |
| 1511 template<typename T> | 1540 template<typename T> |
| 1512 const GCInfo GCInfoTrait<Vector<T, 0, HeapAllocator> >::info = { | 1541 const GCInfo GCInfoTrait<Vector<T, 0, HeapAllocator> >::info = { |
| 1513 TraceTrait<Vector<T, 0, HeapAllocator> >::trace, | 1542 TraceTrait<Vector<T, 0, HeapAllocator> >::trace, |
| 1514 0, | 1543 0, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1551 static const GCInfo info; | 1580 static const GCInfo info; |
| 1552 }; | 1581 }; |
| 1553 | 1582 |
| 1554 template<typename Table> | 1583 template<typename Table> |
| 1555 const GCInfo GCInfoTrait<HeapHashTableBacking<Table> >::info = { | 1584 const GCInfo GCInfoTrait<HeapHashTableBacking<Table> >::info = { |
| 1556 TraceTrait<HeapHashTableBacking<Table> >::trace, | 1585 TraceTrait<HeapHashTableBacking<Table> >::trace, |
| 1557 HeapHashTableBacking<Table>::finalize, | 1586 HeapHashTableBacking<Table>::finalize, |
| 1558 Table::ValueTraits::needsDestruction, | 1587 Table::ValueTraits::needsDestruction, |
| 1559 }; | 1588 }; |
| 1560 | 1589 |
| 1561 template<bool markWeakMembersStrongly, typename T, typename Traits> | 1590 template<typename T, typename Traits> |
| 1562 struct BaseVisitVectorBackingTrait { | 1591 struct BaseVisitVectorBackingTrait { |
| 1563 static void mark(WebCore::Visitor* visitor, void* self) | 1592 static void mark(WebCore::Visitor* visitor, void* self) |
| 1564 { | 1593 { |
| 1565 // The allocator can oversize the allocation a little, according to | 1594 // The allocator can oversize the allocation a little, according to |
| 1566 // the allocation granularity. The extra size is included in the | 1595 // the allocation granularity. The extra size is included in the |
| 1567 // payloadSize call below, since there is nowhere to store the | 1596 // payloadSize call below, since there is nowhere to store the |
| 1568 // originally allocated memory. This assert ensures that visiting the | 1597 // originally allocated memory. This assert ensures that visiting the |
| 1569 // last bit of memory can't cause trouble. | 1598 // last bit of memory can't cause trouble. |
| 1570 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca
tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp
uriousVisits); | 1599 COMPILE_ASSERT(!WTF::ShouldBeTraced<Traits>::value || sizeof(T) > alloca
tionGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSp
uriousVisits); |
| 1571 | 1600 |
| 1572 T* array = reinterpret_cast<T*>(self); | 1601 T* array = reinterpret_cast<T*>(self); |
| 1573 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); | 1602 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); |
| 1574 // Use the payload size as recorded by the heap to determine how many | 1603 // Use the payload size as recorded by the heap to determine how many |
| 1575 // elements to mark. | 1604 // elements to mark. |
| 1576 size_t length = header->payloadSize() / sizeof(T); | 1605 size_t length = header->payloadSize() / sizeof(T); |
| 1577 for (size_t i = 0; i < length; i++) | 1606 for (size_t i = 0; i < length; i++) |
| 1578 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, markWeakMembersStrongly, T, Traits>::mark(visitor, array[i]); | 1607 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, WeakPointersActStrong, T, Traits>::mark(visitor, array[i]); |
| 1579 } | 1608 } |
| 1580 }; | 1609 }; |
| 1581 | 1610 |
| 1582 template<bool markWeakMembersStrongly, typename Table> | 1611 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table> |
| 1583 struct BaseVisitHashTableBackingTrait { | 1612 struct BaseVisitHashTableBackingTrait { |
| 1584 typedef typename Table::ValueType Value; | 1613 typedef typename Table::ValueType Value; |
| 1585 typedef typename Table::ValueTraits Traits; | 1614 typedef typename Table::ValueTraits Traits; |
| 1586 static void mark(WebCore::Visitor* visitor, void* self) | 1615 static void mark(WebCore::Visitor* visitor, void* self) |
| 1587 { | 1616 { |
| 1588 Value* array = reinterpret_cast<Value*>(self); | 1617 Value* array = reinterpret_cast<Value*>(self); |
| 1589 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); | 1618 WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjec
tHeader::fromPayload(self); |
| 1590 size_t length = header->payloadSize() / sizeof(Value); | 1619 size_t length = header->payloadSize() / sizeof(Value); |
| 1591 for (size_t i = 0; i < length; i++) { | 1620 for (size_t i = 0; i < length; i++) { |
| 1592 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) | 1621 if (!WTF::HashTableHelper<Value, typename Table::ExtractorType, type
name Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) |
| 1593 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value,
Traits::isWeak, markWeakMembersStrongly, Value, Traits>::mark(visitor, array[i])
; | 1622 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value,
Traits::isWeak, strongify, Value, Traits>::mark(visitor, array[i]); |
| 1594 } | 1623 } |
| 1595 } | 1624 } |
| 1596 }; | 1625 }; |
| 1597 | 1626 |
| 1598 template<bool markWeakMembersStrongly, typename Key, typename Value, typename Tr
aits> | 1627 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Va
lue, typename Traits> |
| 1599 struct BaseVisitKeyValuePairTrait { | 1628 struct BaseVisitKeyValuePairTrait { |
| 1600 static void mark(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& s
elf) | 1629 static void mark(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& s
elf) |
| 1601 { | 1630 { |
| 1602 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && markWeak
MembersStrongly)); | 1631 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif
y == WeakPointersActStrong)); |
| 1603 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai
ts>::value, Traits::KeyTraits::isWeak, markWeakMembersStrongly, Key, typename Tr
aits::KeyTraits>::mark(visitor, self.key); | 1632 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::KeyTrai
ts>::value, Traits::KeyTraits::isWeak, strongify, Key, typename Traits::KeyTrait
s>::mark(visitor, self.key); |
| 1604 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr
aits>::value, Traits::ValueTraits::isWeak, markWeakMembersStrongly, Value, typen
ame Traits::ValueTraits>::mark(visitor, self.value); | 1633 CollectionBackingTraceTrait<WTF::ShouldBeTraced<typename Traits::ValueTr
aits>::value, Traits::ValueTraits::isWeak, strongify, Value, typename Traits::Va
lueTraits>::mark(visitor, self.value); |
| 1605 } | 1634 } |
| 1606 }; | 1635 }; |
| 1607 | 1636 |
| 1608 // FFX - Things that don't need marking and have no weak pointers. | 1637 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename
Traits> |
| 1609 template<bool markWeakMembersStrongly, typename T, typename U> | 1638 struct BaseVisitLinkedNodeTrait { |
| 1610 struct CollectionBackingTraceTrait<false, false, markWeakMembersStrongly, T, U>
{ | 1639 static void mark(WebCore::Visitor* visitor, WTF::LinkedHashSetNode<Value>& s
elf) |
| 1640 { |
| 1641 ASSERT(WTF::ShouldBeTraced<Traits>::value || (Traits::isWeak && strongif
y == WeakPointersActStrong)); |
| 1642 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
isWeak, strongify, Value, Traits>::mark(visitor, self.m_value); |
| 1643 } |
| 1644 }; |
| 1645 |
| 1646 // Catch-all for things that don't need marking and have no weak pointers. We |
| 1647 // do nothing, even if WeakPointersActStrong. |
| 1648 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename U> |
| 1649 struct CollectionBackingTraceTrait<false, false, strongify, T, U> { |
| 1611 static void mark(Visitor*, const T&) { } | 1650 static void mark(Visitor*, const T&) { } |
| 1612 static void mark(Visitor*, const void*) { } | 1651 static void mark(Visitor*, const void*) { } |
| 1613 }; | 1652 }; |
| 1614 | 1653 |
| 1615 // FTF - Things that don't need marking. They have weak pointers, but we are | 1654 // Catch-all for things that don't need marking. They have weak pointers, but |
| 1616 // not marking weak pointers in this object in this GC. | 1655 // we are not marking weak pointers in this object in this GC. |
| 1617 template<typename T, typename U> | 1656 template<typename T, typename U> |
| 1618 struct CollectionBackingTraceTrait<false, true, false, T, U> { | 1657 struct CollectionBackingTraceTrait<false, true, WeakPointersActWeak, T, U> { |
| 1619 static void mark(Visitor*, const T&) { } | 1658 static void mark(Visitor*, const T&) { } |
| 1620 static void mark(Visitor*, const void*) { } | 1659 static void mark(Visitor*, const void*) { } |
| 1621 }; | 1660 }; |
| 1622 | 1661 |
| 1623 // For each type that we understand we have the FTT case and the TXX case. The | 1662 // For each type that we understand we have the strongified case and the |
| 1624 // FTT case is where we would not normally need to mark it, but it has weak | 1663 // needsMarking case. The strongified case is where we would not normally need |
| 1625 // pointers, and we are marking them as strong. The TXX case is the regular | 1664 // to mark it, but it has weak pointers, and we are marking them as strong |
| 1626 // case for things that need marking. | 1665 // because there is a live iterator that would be disturbed if the collection |
| 1666 // were subject to weak processing right now. The needsMarking case is the |
| 1667 // case for things that need marking, which may also be strongified (eg. for |
| 1668 // a map pair that has a key that is weak and a value that needs marking). |
| 1627 | 1669 |
| 1628 // FTT (vector) | 1670 // The body is the same for most objects, but there are two template |
| 1629 template<typename T, typename Traits> | 1671 // specializations because there is no way to express needsMarking || (isWeak |
| 1630 struct CollectionBackingTraceTrait<false, true, true, HeapVectorBacking<T, Trait
s>, void> : public BaseVisitVectorBackingTrait<true, T, Traits> { | 1672 // && WeakPointersActStrong) in a single specialization. |
| 1673 |
| 1674 // Hash table that would not normally need marking, but strongified. |
| 1675 template<typename Table> |
| 1676 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, HeapHashT
ableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<WeakPointersAc
tStrong, Table> { |
| 1631 }; | 1677 }; |
| 1632 | 1678 |
| 1633 // TXX (vector) | 1679 // Hash table that needs marking, optionally also strongified. |
| 1634 template<bool isWeak, bool markWeakMembersStrongly, typename T, typename Traits> | 1680 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Tab
le> |
| 1635 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapVe
ctorBacking<T, Traits>, void> : public BaseVisitVectorBackingTrait<markWeakMembe
rsStrongly, T, Traits> { | 1681 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapHashTableBacking
<Table>, void> : public BaseVisitHashTableBackingTrait<strongify, Table> { |
| 1636 }; | 1682 }; |
| 1637 | 1683 |
| 1638 // FTT (hash table) | 1684 // Key-value pair that would not normally need marking, but strongified. |
| 1639 template<typename Table> | 1685 template<typename Key, typename Value, typename Traits> |
| 1640 struct CollectionBackingTraceTrait<false, true, true, HeapHashTableBacking<Table
>, void> : public BaseVisitHashTableBackingTrait<true, Table> { | 1686 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::KeyV
aluePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<WeakPointersAc
tStrong, Key, Value, Traits> { |
| 1641 }; | 1687 }; |
| 1642 | 1688 |
| 1643 // TXX (hash table) | 1689 // Key value pair that needs marking, optionally also strongified. |
| 1644 template<bool isWeak, bool markWeakMembersStrongly, typename Table> | 1690 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Key
, typename Value, typename Traits> |
| 1645 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapHa
shTableBacking<Table>, void> : public BaseVisitHashTableBackingTrait<markWeakMem
bersStrongly, Table> { | 1691 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::KeyValuePair<Ke
y, Value>, Traits> : public BaseVisitKeyValuePairTrait<strongify, Key, Value, Tr
aits> { |
| 1646 }; | 1692 }; |
| 1647 | 1693 |
| 1648 // FTT (key value pair) | 1694 // List hash set node that would not normally need marking, but strongified. |
| 1649 template<typename Key, typename Value, typename Traits> | 1695 template<typename Value, typename Traits> |
| 1650 struct CollectionBackingTraceTrait<false, true, true, WTF::KeyValuePair<Key, Val
ue>, Traits> : public BaseVisitKeyValuePairTrait<true, Key, Value, Traits> { | 1696 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WTF::Link
edHashSetNode<Value>, Traits> : public BaseVisitLinkedNodeTrait<WeakPointersActS
trong, Value, Traits> { |
| 1651 }; | 1697 }; |
| 1652 | 1698 |
| 1653 // TXX (key value pair) | 1699 // List hash set node that needs marking, optionally also strongified. |
| 1654 template<bool isWeak, bool markWeakMembersStrongly, typename Key, typename Value
, typename Traits> | 1700 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename Val
ue, typename Traits> |
| 1655 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, WTF::K
eyValuePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<markWeakMem
bersStrongly, Key, Value, Traits> { | 1701 struct CollectionBackingTraceTrait<true, isWeak, strongify, WTF::LinkedHashSetNo
de<Value>, Traits> : public BaseVisitLinkedNodeTrait<strongify, Value, Traits> { |
| 1656 }; | 1702 }; |
| 1657 | 1703 |
| 1658 // TFX (member) | 1704 // Vector backing that needs marking. We don't support weak members in vectors, |
| 1659 template<bool markWeakMembersStrongly, typename T, typename Traits> | 1705 // so we don't need a strongified variant here. |
| 1660 struct CollectionBackingTraceTrait<true, false, markWeakMembersStrongly, Member<
T>, Traits> { | 1706 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T,
typename Traits> |
| 1707 struct CollectionBackingTraceTrait<true, isWeak, strongify, HeapVectorBacking<T,
Traits>, void> : public BaseVisitVectorBackingTrait<T, Traits> { |
| 1708 }; |
| 1709 |
| 1710 // Member always needs marking, never weak. |
| 1711 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
| 1712 struct CollectionBackingTraceTrait<true, false, strongify, Member<T>, Traits> { |
| 1661 static void mark(WebCore::Visitor* visitor, Member<T> self) | 1713 static void mark(WebCore::Visitor* visitor, Member<T> self) |
| 1662 { | 1714 { |
| 1663 visitor->mark(self.get()); | 1715 visitor->mark(self.get()); |
| 1664 } | 1716 } |
| 1665 }; | 1717 }; |
| 1666 | 1718 |
| 1667 // FTT (weak member) | 1719 // Weak member never has needsMarking, always weak, strongified case. |
| 1668 template<typename T, typename Traits> | 1720 template<typename T, typename Traits> |
| 1669 struct CollectionBackingTraceTrait<false, true, true, WeakMember<T>, Traits> { | 1721 struct CollectionBackingTraceTrait<false, true, WeakPointersActStrong, WeakMembe
r<T>, Traits> { |
| 1670 static void mark(WebCore::Visitor* visitor, WeakMember<T> self) | 1722 static void mark(WebCore::Visitor* visitor, WeakMember<T> self) |
| 1671 { | 1723 { |
| 1672 // This can mark weak members as if they were strong. The reason we | 1724 // This can mark weak members as if they were strong. The reason we |
| 1673 // need this is that we don't do weak processing unless we reach the | 1725 // need this is that we don't do weak processing unless we reach the |
| 1674 // backing only through the hash table. Reaching it in any other way | 1726 // backing only through the hash table. Reaching it in any other way |
| 1675 // makes it impossible to update the size and deleted slot count of the | 1727 // makes it impossible to update the size and deleted slot count of the |
| 1676 // table, and exposes us to weak processing during iteration issues. | 1728 // table, and exposes us to weak processing during iteration issues. |
| 1677 visitor->mark(self.get()); | 1729 visitor->mark(self.get()); |
| 1678 } | 1730 } |
| 1679 }; | 1731 }; |
| 1680 | 1732 |
| 1681 // Catch-all for things that have a way to trace. For things that contain weak | 1733 // Catch-all for things that have a way to trace. For things that contain weak |
| 1682 // pointers they will generally be visited weakly even if | 1734 // pointers they will generally be visited weakly even if |
| 1683 // markWeakMembersStrongly is true. This is what you want. | 1735 // WeakPointersActStrong. This is a deliberate choice: We currently don't |
| 1684 template<bool isWeak, bool markWeakMembersStrongly, typename T, typename Traits> | 1736 // strongify weak members that are embedded in larger structures, they are just |
| 1685 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, T, Tra
its> { | 1737 // zeroed during weak processing without the whole structure being |
| 1738 // removed from the collection. |
| 1739 template<bool isWeak, ShouldWeakPointersBeMarkedStrongly strongify, typename T,
typename Traits> |
| 1740 struct CollectionBackingTraceTrait<true, isWeak, strongify, T, Traits> { |
| 1686 static void mark(WebCore::Visitor* visitor, T& t) | 1741 static void mark(WebCore::Visitor* visitor, T& t) |
| 1687 { | 1742 { |
| 1688 TraceTrait<T>::trace(visitor, &t); | 1743 TraceTrait<T>::trace(visitor, &t); |
| 1689 } | 1744 } |
| 1690 }; | 1745 }; |
| 1691 | 1746 |
| 1692 template<typename T, typename Traits> | 1747 template<typename T, typename Traits> |
| 1693 struct TraceTrait<HeapVectorBacking<T, Traits> > { | 1748 struct TraceTrait<HeapVectorBacking<T, Traits> > { |
| 1694 typedef HeapVectorBacking<T, Traits> Backing; | 1749 typedef HeapVectorBacking<T, Traits> Backing; |
| 1695 static void trace(WebCore::Visitor* visitor, void* self) | 1750 static void trace(WebCore::Visitor* visitor, void* self) |
| 1696 { | 1751 { |
| 1697 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectors); | 1752 COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectors); |
| 1698 if (WTF::ShouldBeTraced<Traits>::value) | 1753 if (WTF::ShouldBeTraced<Traits>::value) |
| 1699 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, fals
e, false, HeapVectorBacking<T, Traits>, void>::mark(visitor, self); | 1754 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, fals
e, WeakPointersActWeak, HeapVectorBacking<T, Traits>, void>::mark(visitor, self)
; |
| 1700 } | 1755 } |
| 1701 static void mark(Visitor* visitor, const Backing* backing) | 1756 static void mark(Visitor* visitor, const Backing* backing) |
| 1702 { | 1757 { |
| 1703 visitor->mark(backing, &trace); | 1758 visitor->mark(backing, &trace); |
| 1704 } | 1759 } |
| 1705 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 1760 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
| 1706 { | 1761 { |
| 1707 #ifndef NDEBUG | 1762 #ifndef NDEBUG |
| 1708 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | 1763 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); |
| 1709 #endif | 1764 #endif |
| 1710 } | 1765 } |
| 1711 }; | 1766 }; |
| 1712 | 1767 |
| 1713 // The trace trait for the heap hashtable backing is used when we find a | 1768 // The trace trait for the heap hashtable backing is used when we find a |
| 1714 // direct pointer to the backing from the conservative stack scanner. This | 1769 // direct pointer to the backing from the conservative stack scanner. This |
| 1715 // normally indicates that there is an ongoing iteration over the table, and so | 1770 // normally indicates that there is an ongoing iteration over the table, and so |
| 1716 // we disable weak processing of table entries. When the backing is found | 1771 // we disable weak processing of table entries. When the backing is found |
| 1717 // through the owning hash table we mark differently, in order to do weak | 1772 // through the owning hash table we mark differently, in order to do weak |
| 1718 // processing. | 1773 // processing. |
| 1719 template<typename Table> | 1774 template<typename Table> |
| 1720 struct TraceTrait<HeapHashTableBacking<Table> > { | 1775 struct TraceTrait<HeapHashTableBacking<Table> > { |
| 1721 typedef HeapHashTableBacking<Table> Backing; | 1776 typedef HeapHashTableBacking<Table> Backing; |
| 1722 typedef typename Table::ValueTraits Traits; | 1777 typedef typename Table::ValueTraits Traits; |
| 1723 static void trace(WebCore::Visitor* visitor, void* self) | 1778 static void trace(WebCore::Visitor* visitor, void* self) |
| 1724 { | 1779 { |
| 1725 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) | 1780 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) |
| 1726 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, true, Backing, void>::mark(visitor, self); | 1781 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Trai
ts::isWeak, WeakPointersActStrong, Backing, void>::mark(visitor, self); |
| 1727 } | 1782 } |
| 1728 static void mark(Visitor* visitor, const Backing* backing) | 1783 static void mark(Visitor* visitor, const Backing* backing) |
| 1729 { | 1784 { |
| 1730 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) | 1785 if (WTF::ShouldBeTraced<Traits>::value || Traits::isWeak) |
| 1731 visitor->mark(backing, &trace); | 1786 visitor->mark(backing, &trace); |
| 1732 else | 1787 else |
| 1733 visitor->mark(backing, 0); | 1788 visitor->mark(backing, 0); |
| 1734 } | 1789 } |
| 1735 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 1790 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
| 1736 { | 1791 { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1753 for (unsigned i = 0; i < length; i++) { | 1808 for (unsigned i = 0; i < length; i++) { |
| 1754 if (!Table::isEmptyOrDeletedBucket(table[i])) | 1809 if (!Table::isEmptyOrDeletedBucket(table[i])) |
| 1755 table[i].~Value(); | 1810 table[i].~Value(); |
| 1756 } | 1811 } |
| 1757 } | 1812 } |
| 1758 | 1813 |
| 1759 template<typename T, typename U, typename V, typename W, typename X> | 1814 template<typename T, typename U, typename V, typename W, typename X> |
| 1760 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T,
U, V, W, X, HeapAllocator> > { }; | 1815 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T,
U, V, W, X, HeapAllocator> > { }; |
| 1761 template<typename T, typename U, typename V> | 1816 template<typename T, typename U, typename V> |
| 1762 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V,
HeapAllocator> > { }; | 1817 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V,
HeapAllocator> > { }; |
| 1818 template<typename T, typename U, typename V> |
| 1819 struct GCInfoTrait<HeapLinkedHashSet<T, U, V> > : public GCInfoTrait<LinkedHashS
et<T, U, V, HeapAllocator> > { }; |
| 1763 template<typename T, size_t inlineCapacity> | 1820 template<typename T, size_t inlineCapacity> |
| 1764 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T
, inlineCapacity, HeapAllocator> > { }; | 1821 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T
, inlineCapacity, HeapAllocator> > { }; |
| 1765 | 1822 |
| 1766 template<typename T> | 1823 template<typename T> |
| 1767 struct IfWeakMember; | 1824 struct IfWeakMember; |
| 1768 | 1825 |
| 1769 template<typename T> | 1826 template<typename T> |
| 1770 struct IfWeakMember { | 1827 struct IfWeakMember { |
| 1771 template<typename U> | 1828 template<typename U> |
| 1772 static bool isDead(Visitor*, const U&) { return false; } | 1829 static bool isDead(Visitor*, const U&) { return false; } |
| 1773 }; | 1830 }; |
| 1774 | 1831 |
| 1775 template<typename T> | 1832 template<typename T> |
| 1776 struct IfWeakMember<WeakMember<T> > { | 1833 struct IfWeakMember<WeakMember<T> > { |
| 1777 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } | 1834 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } |
| 1778 }; | 1835 }; |
| 1779 | 1836 |
| 1780 #if COMPILER(CLANG) | 1837 #if COMPILER(CLANG) |
| 1781 // Clang does not export the symbols that we have explicitly asked it | 1838 // Clang does not export the symbols that we have explicitly asked it |
| 1782 // to export. This forces it to export all the methods from ThreadHeap. | 1839 // to export. This forces it to export all the methods from ThreadHeap. |
| 1783 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); | 1840 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); |
| 1784 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); | 1841 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); |
| 1785 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; | 1842 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; |
| 1786 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; | 1843 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; |
| 1787 #endif | 1844 #endif |
| 1788 | 1845 |
| 1789 } | 1846 } |
| 1790 | 1847 |
| 1791 #endif // Heap_h | 1848 #endif // Heap_h |
| OLD | NEW |