Chromium Code Reviews| 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 |