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 GarbageColl ectedMixinTrait; | |
660 template<typename T> | |
661 class GarbageCollectedMixinTrait<T, true> { | |
662 public: | |
663 static HeapObjectHeader* heapObjectHeader(T* obj) | |
664 { | |
665 return obj->heapObjectHeader(); | |
666 } | |
667 static uint16_t gcGeneration(T* obj) | |
668 { | |
669 // While constructing GarbageCollectedMixin classes, we skip looking | |
670 // for gcGeneration, because the object may not be fully allocated. | |
haraken
2015/11/10 16:37:05
Sorry, I'm getting confused. Why can't we call hea
peria
2015/11/11 02:46:34
obj->heapObjectHeader() (on line#665) depends on t
haraken
2015/11/11 04:19:29
Thanks for the clarification; now I understand the
peria
2015/11/11 05:51:51
SGTM
I moved this Trait to Heap.h in PS6.
| |
671 if (ThreadState::current()->isGCForbidden()) | |
haraken
2015/11/10 16:37:05
Let's rename isGCForbidden() to isConstructingGCMi
peria
2015/11/11 05:51:51
Renaming it looks confusing in other places, so I
| |
672 return 0; | |
673 return heapObjectHeader(obj)->gcGeneration(); | |
674 } | |
675 }; | |
676 template<typename T> | |
677 class GarbageCollectedMixinTrait<T, false> { | |
678 public: | |
679 static HeapObjectHeader* heapObjectHeader(T* obj) | |
680 { | |
681 return HeapObjectHeader::fromPayload(obj); | |
682 } | |
683 static uint16_t gcGeneration(T* obj) | |
684 { | |
685 return heapObjectHeader(obj)->gcGeneration(); | |
686 } | |
687 }; | |
688 | |
659 // Members are used in classes to contain strong pointers to other oilpan heap | 689 // Members are used in classes to contain strong pointers to other oilpan heap |
660 // allocated objects. | 690 // allocated objects. |
661 // All Member fields of a class must be traced in the class' trace method. | 691 // 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 | 692 // 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. | 693 // all Member fields of a live object will be traced marked as live as well. |
664 template<typename T> | 694 template<typename T> |
665 class Member { | 695 class Member { |
666 public: | 696 public: |
667 Member() : m_raw(nullptr) | 697 Member() : m_raw(nullptr) |
668 { | 698 { |
699 checkPointer(); | |
669 } | 700 } |
670 | 701 |
671 Member(std::nullptr_t) : m_raw(nullptr) | 702 Member(std::nullptr_t) : m_raw(nullptr) |
672 { | 703 { |
704 checkPointer(); | |
673 } | 705 } |
674 | 706 |
675 Member(T* raw) : m_raw(raw) | 707 Member(T* raw) : m_raw(raw) |
676 { | 708 { |
677 checkPointer(); | 709 checkPointer(); |
678 } | 710 } |
679 | 711 |
680 explicit Member(T& raw) : m_raw(&raw) | 712 explicit Member(T& raw) : m_raw(&raw) |
681 { | 713 { |
682 checkPointer(); | 714 checkPointer(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
755 Member& operator=(RawPtr<U> other) | 787 Member& operator=(RawPtr<U> other) |
756 { | 788 { |
757 m_raw = other; | 789 m_raw = other; |
758 checkPointer(); | 790 checkPointer(); |
759 return *this; | 791 return *this; |
760 } | 792 } |
761 | 793 |
762 Member& operator=(std::nullptr_t) | 794 Member& operator=(std::nullptr_t) |
763 { | 795 { |
764 m_raw = nullptr; | 796 m_raw = nullptr; |
797 checkPointer(); | |
765 return *this; | 798 return *this; |
766 } | 799 } |
767 | 800 |
768 void swap(Member<T>& other) | 801 void swap(Member<T>& other) |
769 { | 802 { |
770 std::swap(m_raw, other.m_raw); | 803 std::swap(m_raw, other.m_raw); |
771 checkPointer(); | 804 checkPointer(); |
772 } | 805 } |
773 | 806 |
774 T* get() const { return m_raw; } | 807 T* get() const |
808 { | |
809 #if ENABLE(ASSERT) | |
810 // Verify that this handle points a live on-heap object, if a pointer | |
haraken
2015/11/10 16:37:05
points to
peria
2015/11/11 02:46:34
Done.
| |
811 // has been assigned to this handle out of GarbageCollectedMixin constru ctions. | |
812 if (m_raw && m_gcGeneration) { | |
813 ASSERT(m_gcGeneration == GarbageCollectedMixinTrait<T>::heapObjectHe ader(m_raw)->gcGeneration()); | |
814 } | |
815 #endif | |
816 return m_raw; | |
817 } | |
775 | 818 |
776 void clear() { m_raw = nullptr; } | 819 // This method is an accessor without any security checks, and it is |
820 // expected to be used under some limited condition. | |
821 // So do NOT use it, if you do not know what it means. | |
822 T* unsafeGet() const | |
823 { | |
824 return m_raw; | |
825 } | |
777 | 826 |
827 void clear() | |
828 { | |
829 m_raw = nullptr; | |
830 checkPointer(); | |
831 } | |
778 | 832 |
779 protected: | 833 protected: |
780 void checkPointer() | 834 void checkPointer() |
781 { | 835 { |
782 #if ENABLE(ASSERT) | 836 #if ENABLE(ASSERT) |
783 if (!m_raw) | 837 if (!m_raw) { |
838 m_gcGeneration = 0; | |
haraken
2015/11/10 16:37:05
You won't need this. Given that you're checking if
peria
2015/11/11 02:46:34
Agree. Done.
| |
784 return; | 839 return; |
840 } | |
785 // HashTable can store a special value (which is not aligned to the | 841 // HashTable can store a special value (which is not aligned to the |
786 // allocation granularity) to Member<> to represent a deleted entry. | 842 // allocation granularity) to Member<> to represent a deleted entry. |
787 // Thus we treat a pointer that is not aligned to the granularity | 843 // Thus we treat a pointer that is not aligned to the granularity |
788 // as a valid pointer. | 844 // as a valid pointer. |
789 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) | 845 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) |
790 return; | 846 return; |
791 | 847 |
792 // TODO(haraken): What we really want to check here is that the pointer | 848 // 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: | 849 // is a traceable object. In other words, the pointer is either of: |
794 // | 850 // |
795 // (a) a pointer to the head of an on-heap object. | 851 // (a) a pointer to the head of an on-heap object. |
796 // (b) a pointer to the head of an on-heap mixin object. | 852 // (b) a pointer to the head of an on-heap mixin object. |
797 // | 853 // |
798 // We can check it by calling Heap::isHeapObjectAlive(m_raw), | 854 // We can check it by calling Heap::isHeapObjectAlive(m_raw), |
799 // but we cannot call it here because it requires to include T.h. | 855 // 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 | 856 // So we currently only try to implement the check for (a), but do |
801 // not insist that T's definition is in scope. | 857 // not insist that T's definition is in scope. |
802 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) | 858 m_gcGeneration = GarbageCollectedMixinTrait<T>::gcGeneration(m_raw); |
haraken
2015/11/11 04:19:29
So you can update the code to:
HeapObjectHeader
peria
2015/11/11 05:51:51
Acknowledged.
| |
803 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); | |
804 #endif | 859 #endif |
805 } | 860 } |
806 | 861 |
807 T* m_raw; | 862 T* m_raw; |
808 | 863 |
864 #if ENABLE(ASSERT) | |
865 uint16_t m_gcGeneration; | |
866 #endif | |
867 | |
809 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; | 868 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; |
810 friend class Visitor; | 869 friend class Visitor; |
811 | |
812 }; | 870 }; |
813 | 871 |
814 // WeakMember is similar to Member in that it is used to point to other oilpan | 872 // WeakMember is similar to Member in that it is used to point to other oilpan |
815 // heap allocated objects. | 873 // heap allocated objects. |
816 // However instead of creating a strong pointer to the object, the WeakMember cr eates | 874 // 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 | 875 // 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 | 876 // 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. | 877 // time of GC the weak pointers will automatically be set to null. |
820 template<typename T> | 878 template<typename T> |
821 class WeakMember : public Member<T> { | 879 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) | 920 WeakMember& operator=(const RawPtr<U>& other) |
863 { | 921 { |
864 this->m_raw = other; | 922 this->m_raw = other; |
865 this->checkPointer(); | 923 this->checkPointer(); |
866 return *this; | 924 return *this; |
867 } | 925 } |
868 | 926 |
869 WeakMember& operator=(std::nullptr_t) | 927 WeakMember& operator=(std::nullptr_t) |
870 { | 928 { |
871 this->m_raw = nullptr; | 929 this->m_raw = nullptr; |
930 this->checkPointer(); | |
872 return *this; | 931 return *this; |
873 } | 932 } |
874 | 933 |
875 private: | 934 private: |
876 T** cell() const { return const_cast<T**>(&this->m_raw); } | 935 T** cell() const { return const_cast<T**>(&this->m_raw); } |
877 | 936 |
878 template<typename Derived> friend class VisitorHelper; | 937 template<typename Derived> friend class VisitorHelper; |
879 }; | 938 }; |
880 | 939 |
881 // UntracedMember is a pointer to an on-heap object that is not traced for some | 940 // 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) | 993 UntracedMember& operator=(const RawPtr<U>& other) |
935 { | 994 { |
936 this->m_raw = other; | 995 this->m_raw = other; |
937 this->checkPointer(); | 996 this->checkPointer(); |
938 return *this; | 997 return *this; |
939 } | 998 } |
940 | 999 |
941 UntracedMember& operator=(std::nullptr_t) | 1000 UntracedMember& operator=(std::nullptr_t) |
942 { | 1001 { |
943 this->m_raw = nullptr; | 1002 this->m_raw = nullptr; |
1003 this->checkPointer(); | |
944 return *this; | 1004 return *this; |
945 } | 1005 } |
946 }; | 1006 }; |
947 | 1007 |
948 // Comparison operators between (Weak)Members, Persistents, and UntracedMembers. | 1008 // 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(); } | 1009 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(); } | 1010 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(); } | 1011 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(); } | 1012 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); } |
953 | 1013 |
954 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons t Persistent<U>& b) { return a.get() == b.get(); } | 1014 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(); } | 1015 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(); } | 1016 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(); } | 1017 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); } |
958 | 1018 |
959 template<typename T> | 1019 template<typename T> |
960 class DummyBase { | 1020 class DummyBase { |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1407 | 1467 |
1408 template<typename T> struct PtrHash<blink::Member<T>> : PtrHash<T*> { | 1468 template<typename T> struct PtrHash<blink::Member<T>> : PtrHash<T*> { |
1409 template<typename U> | 1469 template<typename U> |
1410 static unsigned hash(const U& key) { return PtrHash<T*>::hash(key); } | 1470 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; } | 1471 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; } | 1472 static bool equal(const blink::Member<T>& a, T* b) { return a == b; } |
1413 template<typename U, typename V> | 1473 template<typename U, typename V> |
1414 static bool equal(const U& a, const V& b) { return a == b; } | 1474 static bool equal(const U& a, const V& b) { return a == b; } |
1415 }; | 1475 }; |
1416 | 1476 |
1417 template<typename T> struct PtrHash<blink::WeakMember<T>> : PtrHash<blink::Membe r<T>> { | 1477 template<typename T> struct PtrHash<blink::WeakMember<T>> : PtrHash<blink::Membe r<T>> { }; |
1418 }; | |
1419 | 1478 |
1420 template<typename T> struct PtrHash<blink::UntracedMember<T>> : PtrHash<blink::M ember<T>> { | 1479 template<typename T> struct PtrHash<blink::UntracedMember<T>> : PtrHash<blink::M ember<T>> { }; |
1421 }; | |
1422 | 1480 |
1423 // PtrHash is the default hash for hash tables with members. | 1481 // PtrHash is the default hash for hash tables with members. |
1424 template<typename T> struct DefaultHash<blink::Member<T>> { | 1482 template<typename T> struct DefaultHash<blink::Member<T>> { |
1425 using Hash = PtrHash<blink::Member<T>>; | 1483 using Hash = PtrHash<blink::Member<T>>; |
1426 }; | 1484 }; |
1427 | 1485 |
1428 template<typename T> struct DefaultHash<blink::WeakMember<T>> { | 1486 template<typename T> struct DefaultHash<blink::WeakMember<T>> { |
1429 using Hash = PtrHash<blink::WeakMember<T>>; | 1487 using Hash = PtrHash<blink::WeakMember<T>>; |
1430 }; | 1488 }; |
1431 | 1489 |
(...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. | 1562 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C rossThread)WeakPersistent. |
1505 static T* unwrap(const StorageType& value) { return value.get(); } | 1563 static T* unwrap(const StorageType& value) { return value.get(); } |
1506 }; | 1564 }; |
1507 | 1565 |
1508 template<typename T> | 1566 template<typename T> |
1509 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | 1567 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; |
1510 | 1568 |
1511 } // namespace WTF | 1569 } // namespace WTF |
1512 | 1570 |
1513 #endif | 1571 #endif |
OLD | NEW |