OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2014 Google Inc. All rights reserved. | 2 * Copyright (C) 2014 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 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 public: | 649 public: |
650 PersistentHeapDeque() { } | 650 PersistentHeapDeque() { } |
651 | 651 |
652 template<size_t otherCapacity> | 652 template<size_t otherCapacity> |
653 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) | 653 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) |
654 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) | 654 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) |
655 { | 655 { |
656 } | 656 } |
657 }; | 657 }; |
658 | 658 |
| 659 template<typename T, bool = IsGarbageCollectedMixin<T>::value> class GCMixinTrai
t; |
| 660 template<typename T> |
| 661 class GCMixinTrait<T, true> { |
| 662 public: |
| 663 static HeapObjectHeader* heapObjectHeader(T* obj) |
| 664 { |
| 665 return obj->heapObjectHeader(); |
| 666 } |
| 667 }; |
| 668 template<typename T> |
| 669 class GCMixinTrait<T, false> { |
| 670 public: |
| 671 static HeapObjectHeader* heapObjectHeader(T* obj) |
| 672 { |
| 673 return HeapObjectHeader::fromPayload(obj); |
| 674 } |
| 675 }; |
| 676 |
659 // Members are used in classes to contain strong pointers to other oilpan heap | 677 // Members are used in classes to contain strong pointers to other oilpan heap |
660 // allocated objects. | 678 // allocated objects. |
661 // All Member fields of a class must be traced in the class' trace method. | 679 // All Member fields of a class must be traced in the class' trace method. |
662 // During the mark phase of the GC all live objects are marked as live and | 680 // During the mark phase of the GC all live objects are marked as live and |
663 // all Member fields of a live object will be traced marked as live as well. | 681 // all Member fields of a live object will be traced marked as live as well. |
664 template<typename T> | 682 template<typename T> |
665 class Member { | 683 class Member { |
666 public: | 684 public: |
667 Member() : m_raw(nullptr) | 685 Member() : m_raw(nullptr) |
668 { | 686 { |
| 687 checkPointer(); |
669 } | 688 } |
670 | 689 |
671 Member(std::nullptr_t) : m_raw(nullptr) | 690 Member(std::nullptr_t) : m_raw(nullptr) |
672 { | 691 { |
| 692 checkPointer(); |
673 } | 693 } |
674 | 694 |
675 Member(T* raw) : m_raw(raw) | 695 Member(T* raw) : m_raw(raw) |
676 { | 696 { |
677 checkPointer(); | 697 checkPointer(); |
678 } | 698 } |
679 | 699 |
680 explicit Member(T& raw) : m_raw(&raw) | 700 explicit Member(T& raw) : m_raw(&raw) |
681 { | 701 { |
682 checkPointer(); | 702 checkPointer(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 Member& operator=(RawPtr<U> other) | 775 Member& operator=(RawPtr<U> other) |
756 { | 776 { |
757 m_raw = other; | 777 m_raw = other; |
758 checkPointer(); | 778 checkPointer(); |
759 return *this; | 779 return *this; |
760 } | 780 } |
761 | 781 |
762 Member& operator=(std::nullptr_t) | 782 Member& operator=(std::nullptr_t) |
763 { | 783 { |
764 m_raw = nullptr; | 784 m_raw = nullptr; |
| 785 checkPointer(); |
765 return *this; | 786 return *this; |
766 } | 787 } |
767 | 788 |
768 void swap(Member<T>& other) | 789 void swap(Member<T>& other) |
769 { | 790 { |
770 std::swap(m_raw, other.m_raw); | 791 std::swap(m_raw, other.m_raw); |
771 checkPointer(); | 792 checkPointer(); |
772 } | 793 } |
773 | 794 |
774 T* get() const { return m_raw; } | 795 T* get() const |
| 796 { |
| 797 #if ENABLE(ASSERT) |
| 798 if (m_raw && m_gcGeneration) { |
| 799 ASSERT(m_gcGeneration == GCMixinTrait<T>::heapObjectHeader(m_raw)->g
cGeneration()); |
| 800 } |
| 801 #endif |
| 802 return m_raw; |
| 803 } |
775 | 804 |
776 void clear() { m_raw = nullptr; } | 805 // This method is an accessor without any security checks, and it is |
| 806 // expected to be used under some limited condition. |
| 807 // So do NOT use it, if you do not know what it means. |
| 808 T* unsafeGet() const |
| 809 { |
| 810 return m_raw; |
| 811 } |
777 | 812 |
| 813 void clear() |
| 814 { |
| 815 m_raw = nullptr; |
| 816 checkPointer(); |
| 817 } |
778 | 818 |
779 protected: | 819 protected: |
780 void checkPointer() | 820 void checkPointer() |
781 { | 821 { |
782 #if ENABLE(ASSERT) | 822 #if ENABLE(ASSERT) |
783 if (!m_raw) | 823 if (!m_raw) { |
| 824 m_gcGeneration = 0; |
784 return; | 825 return; |
| 826 } |
785 // HashTable can store a special value (which is not aligned to the | 827 // HashTable can store a special value (which is not aligned to the |
786 // allocation granularity) to Member<> to represent a deleted entry. | 828 // allocation granularity) to Member<> to represent a deleted entry. |
787 // Thus we treat a pointer that is not aligned to the granularity | 829 // Thus we treat a pointer that is not aligned to the granularity |
788 // as a valid pointer. | 830 // as a valid pointer. |
789 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) | 831 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) |
790 return; | 832 return; |
791 | 833 |
792 // TODO(haraken): What we really want to check here is that the pointer | 834 // TODO(haraken): What we really want to check here is that the pointer |
793 // is a traceable object. In other words, the pointer is either of: | 835 // is a traceable object. In other words, the pointer is either of: |
794 // | 836 // |
795 // (a) a pointer to the head of an on-heap object. | 837 // (a) a pointer to the head of an on-heap object. |
796 // (b) a pointer to the head of an on-heap mixin object. | 838 // (b) a pointer to the head of an on-heap mixin object. |
797 // | 839 // |
798 // We can check it by calling Heap::isHeapObjectAlive(m_raw), | 840 // We can check it by calling Heap::isHeapObjectAlive(m_raw), |
799 // but we cannot call it here because it requires to include T.h. | 841 // but we cannot call it here because it requires to include T.h. |
800 // So we currently only try to implement the check for (a), but do | 842 // So we currently only try to implement the check for (a), but do |
801 // not insist that T's definition is in scope. | 843 // not insist that T's definition is in scope. |
802 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) | 844 if (IsFullyDefined<T>::value) { |
803 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); | 845 m_gcGeneration = GCMixinTrait<T>::heapObjectHeader(m_raw)->gcGenerat
ion(); |
| 846 } else { |
| 847 m_gcGeneration = 0; |
| 848 } |
804 #endif | 849 #endif |
805 } | 850 } |
806 | 851 |
807 T* m_raw; | 852 T* m_raw; |
808 | 853 |
| 854 #if ENABLE(ASSERT) |
| 855 uint16_t m_gcGeneration; |
| 856 #endif |
| 857 |
809 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr
ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; | 858 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr
ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; |
810 friend class Visitor; | 859 friend class Visitor; |
811 | |
812 }; | 860 }; |
813 | 861 |
814 // WeakMember is similar to Member in that it is used to point to other oilpan | 862 // WeakMember is similar to Member in that it is used to point to other oilpan |
815 // heap allocated objects. | 863 // heap allocated objects. |
816 // However instead of creating a strong pointer to the object, the WeakMember cr
eates | 864 // However instead of creating a strong pointer to the object, the WeakMember cr
eates |
817 // a weak pointer, which does not keep the pointee alive. Hence if all pointers
to | 865 // a weak pointer, which does not keep the pointee alive. Hence if all pointers
to |
818 // to a heap allocated object are weak the object will be garbage collected. At
the | 866 // to a heap allocated object are weak the object will be garbage collected. At
the |
819 // time of GC the weak pointers will automatically be set to null. | 867 // time of GC the weak pointers will automatically be set to null. |
820 template<typename T> | 868 template<typename T> |
821 class WeakMember : public Member<T> { | 869 class WeakMember : public Member<T> { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 WeakMember& operator=(const RawPtr<U>& other) | 910 WeakMember& operator=(const RawPtr<U>& other) |
863 { | 911 { |
864 this->m_raw = other; | 912 this->m_raw = other; |
865 this->checkPointer(); | 913 this->checkPointer(); |
866 return *this; | 914 return *this; |
867 } | 915 } |
868 | 916 |
869 WeakMember& operator=(std::nullptr_t) | 917 WeakMember& operator=(std::nullptr_t) |
870 { | 918 { |
871 this->m_raw = nullptr; | 919 this->m_raw = nullptr; |
| 920 this->checkPointer(); |
872 return *this; | 921 return *this; |
873 } | 922 } |
874 | 923 |
875 private: | 924 private: |
876 T** cell() const { return const_cast<T**>(&this->m_raw); } | 925 T** cell() const { return const_cast<T**>(&this->m_raw); } |
877 | 926 |
878 template<typename Derived> friend class VisitorHelper; | 927 template<typename Derived> friend class VisitorHelper; |
879 }; | 928 }; |
880 | 929 |
881 // UntracedMember is a pointer to an on-heap object that is not traced for some | 930 // UntracedMember is a pointer to an on-heap object that is not traced for some |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 UntracedMember& operator=(const RawPtr<U>& other) | 983 UntracedMember& operator=(const RawPtr<U>& other) |
935 { | 984 { |
936 this->m_raw = other; | 985 this->m_raw = other; |
937 this->checkPointer(); | 986 this->checkPointer(); |
938 return *this; | 987 return *this; |
939 } | 988 } |
940 | 989 |
941 UntracedMember& operator=(std::nullptr_t) | 990 UntracedMember& operator=(std::nullptr_t) |
942 { | 991 { |
943 this->m_raw = nullptr; | 992 this->m_raw = nullptr; |
| 993 this->checkPointer(); |
944 return *this; | 994 return *this; |
945 } | 995 } |
946 }; | 996 }; |
947 | 997 |
948 // Comparison operators between (Weak)Members, Persistents, and UntracedMembers. | 998 // Comparison operators between (Weak)Members, Persistents, and UntracedMembers. |
949 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Member<U>& b) { return a.get() == b.get(); } | 999 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Member<U>& b) { return a.unsafeGet() == b.unsafeGet(); } |
950 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Member<U>& b) { return a.get() != b.get(); } | 1000 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Member<U>& b) { return a.unsafeGet() != b.unsafeGet(); } |
951 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() == b.get(); } | 1001 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() == b.get(); } |
952 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() != b.get(); } | 1002 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() != b.get(); } |
953 | 1003 |
954 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } | 1004 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } |
955 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() != b.get(); } | 1005 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() != b.get(); } |
956 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Member<U>& b) { return a.get() == b.get(); } | 1006 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Member<U>& b) { return a.get() == b.get(); } |
957 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Member<U>& b) { return a.get() != b.get(); } | 1007 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Member<U>& b) { return a.get() != b.get(); } |
958 | 1008 |
959 template<typename T> | 1009 template<typename T> |
960 class DummyBase { | 1010 class DummyBase { |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 | 1457 |
1408 template<typename T> struct PtrHash<blink::Member<T>> : PtrHash<T*> { | 1458 template<typename T> struct PtrHash<blink::Member<T>> : PtrHash<T*> { |
1409 template<typename U> | 1459 template<typename U> |
1410 static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); } | 1460 static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); } |
1411 static bool equal(T* a, const blink::Member<T>& b) { return a == b; } | 1461 static bool equal(T* a, const blink::Member<T>& b) { return a == b; } |
1412 static bool equal(const blink::Member<T>& a, T* b) { return a == b; } | 1462 static bool equal(const blink::Member<T>& a, T* b) { return a == b; } |
1413 template<typename U, typename V> | 1463 template<typename U, typename V> |
1414 static bool equal(const U& a, const V& b) { return a == b; } | 1464 static bool equal(const U& a, const V& b) { return a == b; } |
1415 }; | 1465 }; |
1416 | 1466 |
1417 template<typename T> struct PtrHash<blink::WeakMember<T>> : PtrHash<blink::Membe
r<T>> { | 1467 template<typename T> struct PtrHash<blink::WeakMember<T>> : PtrHash<blink::Membe
r<T>> { }; |
1418 }; | |
1419 | 1468 |
1420 template<typename T> struct PtrHash<blink::UntracedMember<T>> : PtrHash<blink::M
ember<T>> { | 1469 template<typename T> struct PtrHash<blink::UntracedMember<T>> : PtrHash<blink::M
ember<T>> { }; |
1421 }; | |
1422 | 1470 |
1423 // PtrHash is the default hash for hash tables with members. | 1471 // PtrHash is the default hash for hash tables with members. |
1424 template<typename T> struct DefaultHash<blink::Member<T>> { | 1472 template<typename T> struct DefaultHash<blink::Member<T>> { |
1425 using Hash = PtrHash<blink::Member<T>>; | 1473 using Hash = PtrHash<blink::Member<T>>; |
1426 }; | 1474 }; |
1427 | 1475 |
1428 template<typename T> struct DefaultHash<blink::WeakMember<T>> { | 1476 template<typename T> struct DefaultHash<blink::WeakMember<T>> { |
1429 using Hash = PtrHash<blink::WeakMember<T>>; | 1477 using Hash = PtrHash<blink::WeakMember<T>>; |
1430 }; | 1478 }; |
1431 | 1479 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1504 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C
rossThread)WeakPersistent. | 1552 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C
rossThread)WeakPersistent. |
1505 static T* unwrap(const StorageType& value) { return value.get(); } | 1553 static T* unwrap(const StorageType& value) { return value.get(); } |
1506 }; | 1554 }; |
1507 | 1555 |
1508 template<typename T> | 1556 template<typename T> |
1509 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | 1557 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; |
1510 | 1558 |
1511 } // namespace WTF | 1559 } // namespace WTF |
1512 | 1560 |
1513 #endif | 1561 #endif |
OLD | NEW |