OLD | NEW |
1 /* | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2014 Google Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * | 3 // found in the LICENSE file. |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | 4 |
31 #ifndef Handle_h | 5 #ifndef Persistent_h |
32 #define Handle_h | 6 #define Persistent_h |
33 | 7 |
34 #include "platform/heap/Heap.h" | 8 #include "platform/heap/Member.h" |
35 #include "platform/heap/HeapAllocator.h" | |
36 #include "platform/heap/InlinedGlobalMarkingVisitor.h" | |
37 #include "platform/heap/PersistentNode.h" | 9 #include "platform/heap/PersistentNode.h" |
38 #include "platform/heap/ThreadState.h" | |
39 #include "platform/heap/TraceTraits.h" | |
40 #include "platform/heap/Visitor.h" | |
41 #include "wtf/Allocator.h" | 10 #include "wtf/Allocator.h" |
42 #include "wtf/Atomics.h" | 11 #include "wtf/Atomics.h" |
43 #include "wtf/HashFunctions.h" | |
44 #include "wtf/TypeTraits.h" | |
45 | |
46 #if defined(LEAK_SANITIZER) | |
47 #include "wtf/LeakAnnotations.h" | |
48 #endif | |
49 | 12 |
50 namespace blink { | 13 namespace blink { |
51 | 14 |
52 // Marker used to annotate persistent objects and collections with, | 15 // Marker used to annotate persistent objects and collections with, |
53 // so as to enable reliable testing for persistent references via | 16 // so as to enable reliable testing for persistent references via |
54 // a type trait (see TypeTraits.h's IsPersistentReferenceType<>.) | 17 // a type trait (see TypeTraits.h's IsPersistentReferenceType<>.) |
55 #define IS_PERSISTENT_REFERENCE_TYPE() \ | 18 #define IS_PERSISTENT_REFERENCE_TYPE() \ |
56 public: \ | 19 public: \ |
57 using IsPersistentReferenceTypeMarker = int; \ | 20 using IsPersistentReferenceTypeMarker = int; \ |
58 private: | 21 private: |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 public: | 622 public: |
660 PersistentHeapDeque() { } | 623 PersistentHeapDeque() { } |
661 | 624 |
662 template<size_t otherCapacity> | 625 template<size_t otherCapacity> |
663 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) | 626 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) |
664 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) | 627 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) |
665 { | 628 { |
666 } | 629 } |
667 }; | 630 }; |
668 | 631 |
669 // Members are used in classes to contain strong pointers to other oilpan heap | |
670 // allocated objects. | |
671 // All Member fields of a class must be traced in the class' trace method. | |
672 // During the mark phase of the GC all live objects are marked as live and | |
673 // all Member fields of a live object will be traced marked as live as well. | |
674 template<typename T> | |
675 class Member { | |
676 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | |
677 public: | |
678 Member() : m_raw(nullptr) | |
679 { | |
680 } | |
681 | |
682 Member(std::nullptr_t) : m_raw(nullptr) | |
683 { | |
684 } | |
685 | |
686 Member(T* raw) : m_raw(raw) | |
687 { | |
688 checkPointer(); | |
689 } | |
690 | |
691 explicit Member(T& raw) : m_raw(&raw) | |
692 { | |
693 checkPointer(); | |
694 } | |
695 | |
696 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) | |
697 { | |
698 } | |
699 | |
700 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(
-1); } | |
701 | |
702 template<typename U> | |
703 Member(const Persistent<U>& other) : m_raw(other) | |
704 { | |
705 checkPointer(); | |
706 } | |
707 | |
708 Member(const Member& other) : m_raw(other) | |
709 { | |
710 checkPointer(); | |
711 } | |
712 | |
713 template<typename U> | |
714 Member(const Member<U>& other) : m_raw(other) | |
715 { | |
716 checkPointer(); | |
717 } | |
718 | |
719 T* release() | |
720 { | |
721 T* result = m_raw; | |
722 m_raw = nullptr; | |
723 return result; | |
724 } | |
725 | |
726 explicit operator bool() const { return m_raw; } | |
727 | |
728 operator T*() const { return m_raw; } | |
729 | |
730 T* operator->() const { return m_raw; } | |
731 T& operator*() const { return *m_raw; } | |
732 | |
733 template<typename U> | |
734 Member& operator=(const Persistent<U>& other) | |
735 { | |
736 m_raw = other; | |
737 checkPointer(); | |
738 return *this; | |
739 } | |
740 | |
741 template<typename U> | |
742 Member& operator=(const Member<U>& other) | |
743 { | |
744 m_raw = other; | |
745 checkPointer(); | |
746 return *this; | |
747 } | |
748 | |
749 template<typename U> | |
750 Member& operator=(U* other) | |
751 { | |
752 m_raw = other; | |
753 checkPointer(); | |
754 return *this; | |
755 } | |
756 | |
757 Member& operator=(std::nullptr_t) | |
758 { | |
759 m_raw = nullptr; | |
760 return *this; | |
761 } | |
762 | |
763 void swap(Member<T>& other) | |
764 { | |
765 std::swap(m_raw, other.m_raw); | |
766 checkPointer(); | |
767 } | |
768 | |
769 T* get() const { return m_raw; } | |
770 | |
771 void clear() { m_raw = nullptr; } | |
772 | |
773 | |
774 protected: | |
775 void checkPointer() | |
776 { | |
777 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) | |
778 if (!m_raw) | |
779 return; | |
780 // HashTable can store a special value (which is not aligned to the | |
781 // allocation granularity) to Member<> to represent a deleted entry. | |
782 // Thus we treat a pointer that is not aligned to the granularity | |
783 // as a valid pointer. | |
784 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) | |
785 return; | |
786 | |
787 // TODO(haraken): What we really want to check here is that the pointer | |
788 // is a traceable object. In other words, the pointer is either of: | |
789 // | |
790 // (a) a pointer to the head of an on-heap object. | |
791 // (b) a pointer to the head of an on-heap mixin object. | |
792 // | |
793 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw), | |
794 // but we cannot call it here because it requires to include T.h. | |
795 // So we currently only try to implement the check for (a), but do | |
796 // not insist that T's definition is in scope. | |
797 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) | |
798 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); | |
799 #endif | |
800 } | |
801 | |
802 T* m_raw; | |
803 | |
804 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr
ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; | |
805 friend class Visitor; | |
806 | |
807 }; | |
808 | |
809 // WeakMember is similar to Member in that it is used to point to other oilpan | |
810 // heap allocated objects. | |
811 // However instead of creating a strong pointer to the object, the WeakMember cr
eates | |
812 // a weak pointer, which does not keep the pointee alive. Hence if all pointers
to | |
813 // to a heap allocated object are weak the object will be garbage collected. At
the | |
814 // time of GC the weak pointers will automatically be set to null. | |
815 template<typename T> | |
816 class WeakMember : public Member<T> { | |
817 public: | |
818 WeakMember() : Member<T>() { } | |
819 | |
820 WeakMember(std::nullptr_t) : Member<T>(nullptr) { } | |
821 | |
822 WeakMember(T* raw) : Member<T>(raw) { } | |
823 | |
824 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } | |
825 | |
826 template<typename U> | |
827 WeakMember(const Persistent<U>& other) : Member<T>(other) { } | |
828 | |
829 template<typename U> | |
830 WeakMember(const Member<U>& other) : Member<T>(other) { } | |
831 | |
832 template<typename U> | |
833 WeakMember& operator=(const Persistent<U>& other) | |
834 { | |
835 this->m_raw = other; | |
836 this->checkPointer(); | |
837 return *this; | |
838 } | |
839 | |
840 template<typename U> | |
841 WeakMember& operator=(const Member<U>& other) | |
842 { | |
843 this->m_raw = other; | |
844 this->checkPointer(); | |
845 return *this; | |
846 } | |
847 | |
848 template<typename U> | |
849 WeakMember& operator=(U* other) | |
850 { | |
851 this->m_raw = other; | |
852 this->checkPointer(); | |
853 return *this; | |
854 } | |
855 | |
856 WeakMember& operator=(std::nullptr_t) | |
857 { | |
858 this->m_raw = nullptr; | |
859 return *this; | |
860 } | |
861 | |
862 private: | |
863 T** cell() const { return const_cast<T**>(&this->m_raw); } | |
864 | |
865 template<typename Derived> friend class VisitorHelper; | |
866 }; | |
867 | |
868 // UntracedMember is a pointer to an on-heap object that is not traced for some | |
869 // reason. Please don't use this unless you understand what you're doing. | |
870 // Basically, all pointers to on-heap objects must be stored in either of | |
871 // Persistent, Member or WeakMember. It is not allowed to leave raw pointers to | |
872 // on-heap objects. However, there can be scenarios where you have to use raw | |
873 // pointers for some reason, and in that case you can use UntracedMember. Of | |
874 // course, it must be guaranteed that the pointing on-heap object is kept alive | |
875 // while the raw pointer is pointing to the object. | |
876 template<typename T> | |
877 class UntracedMember final : public Member<T> { | |
878 public: | |
879 UntracedMember() : Member<T>() { } | |
880 | |
881 UntracedMember(std::nullptr_t) : Member<T>(nullptr) { } | |
882 | |
883 UntracedMember(T* raw) : Member<T>(raw) { } | |
884 | |
885 template<typename U> | |
886 UntracedMember(const Persistent<U>& other) : Member<T>(other) { } | |
887 | |
888 template<typename U> | |
889 UntracedMember(const Member<U>& other) : Member<T>(other) { } | |
890 | |
891 UntracedMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } | |
892 | |
893 template<typename U> | |
894 UntracedMember& operator=(const Persistent<U>& other) | |
895 { | |
896 this->m_raw = other; | |
897 this->checkPointer(); | |
898 return *this; | |
899 } | |
900 | |
901 template<typename U> | |
902 UntracedMember& operator=(const Member<U>& other) | |
903 { | |
904 this->m_raw = other; | |
905 this->checkPointer(); | |
906 return *this; | |
907 } | |
908 | |
909 template<typename U> | |
910 UntracedMember& operator=(U* other) | |
911 { | |
912 this->m_raw = other; | |
913 this->checkPointer(); | |
914 return *this; | |
915 } | |
916 | |
917 UntracedMember& operator=(std::nullptr_t) | |
918 { | |
919 this->m_raw = nullptr; | |
920 return *this; | |
921 } | |
922 }; | |
923 | |
924 // Comparison operators between (Weak)Members, Persistents, and UntracedMembers. | |
925 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Member<U>& b) { return a.get() == b.get(); } | |
926 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Member<U>& b) { return a.get() != b.get(); } | |
927 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() == b.get(); } | |
928 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() != b.get(); } | |
929 | |
930 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } | |
931 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() != b.get(); } | |
932 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Member<U>& b) { return a.get() == b.get(); } | |
933 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Member<U>& b) { return a.get() != b.get(); } | |
934 | |
935 template<typename T, bool = IsGarbageCollectedType<T>::value> | |
936 class RawPtrOrMemberTrait { | |
937 STATIC_ONLY(RawPtrOrMemberTrait) | |
938 public: | |
939 using Type = T*; | |
940 }; | |
941 | |
942 template<typename T> | |
943 class RawPtrOrMemberTrait<T, true> { | |
944 STATIC_ONLY(RawPtrOrMemberTrait) | |
945 public: | |
946 using Type = Member<T>; | |
947 }; | |
948 | |
949 // Abstraction for injecting calls to an object's 'dispose()' method | |
950 // on leaving a stack scope, ensuring earlier release of resources | |
951 // than waiting until the object is eventually GCed. | |
952 template<typename T, void (T::*Disposer)() = (&T::dispose)> | |
953 class ScopedDisposal { | |
954 STACK_ALLOCATED(); | |
955 public: | |
956 ScopedDisposal(T* object) | |
957 : m_object(object) | |
958 { | |
959 } | |
960 | |
961 ~ScopedDisposal() | |
962 { | |
963 if (m_object) | |
964 (m_object->*Disposer)(); | |
965 } | |
966 | |
967 void clear() { m_object.clear(); } | |
968 | |
969 private: | |
970 typename RawPtrOrMemberTrait<T>::Type m_object; | |
971 }; | |
972 | |
973 // SelfKeepAlive<Object> is the idiom to use for objects that have to keep | |
974 // themselves temporarily alive and cannot rely on there being some | |
975 // external reference in that interval: | |
976 // | |
977 // class Opener { | |
978 // public: | |
979 // ... | |
980 // void open() | |
981 // { | |
982 // // Retain a self-reference while in an open()ed state: | |
983 // m_keepAlive = this; | |
984 // .... | |
985 // } | |
986 // | |
987 // void close() | |
988 // { | |
989 // // Clear self-reference that ensured we were kept alive while opened. | |
990 // m_keepAlive.clear(); | |
991 // .... | |
992 // } | |
993 // | |
994 // private: | |
995 // ... | |
996 // SelfKeepAlive m_keepAlive; | |
997 // }; | |
998 // | |
999 // The responsibility to call clear() in a timely fashion resides with the imple
mentation | |
1000 // of the object. | |
1001 // | |
1002 // | |
1003 template<typename Self> | |
1004 class SelfKeepAlive final { | |
1005 DISALLOW_NEW(); | |
1006 public: | |
1007 SelfKeepAlive() | |
1008 { | |
1009 } | |
1010 | |
1011 explicit SelfKeepAlive(Self* self) | |
1012 { | |
1013 assign(self); | |
1014 } | |
1015 | |
1016 SelfKeepAlive& operator=(Self* self) | |
1017 { | |
1018 assign(self); | |
1019 return *this; | |
1020 } | |
1021 | |
1022 void clear() | |
1023 { | |
1024 m_keepAlive.clear(); | |
1025 } | |
1026 | |
1027 typedef Persistent<Self> (SelfKeepAlive::*UnspecifiedBoolType); | |
1028 operator UnspecifiedBoolType() const { return m_keepAlive ? &SelfKeepAlive::
m_keepAlive : 0; } | |
1029 | |
1030 private: | |
1031 void assign(Self* self) | |
1032 { | |
1033 ASSERT(!m_keepAlive || m_keepAlive.get() == self); | |
1034 m_keepAlive = self; | |
1035 } | |
1036 | |
1037 GC_PLUGIN_IGNORE("420515") | |
1038 Persistent<Self> m_keepAlive; | |
1039 }; | |
1040 | |
1041 // Only a very reduced form of weak heap object references can currently be held | 632 // Only a very reduced form of weak heap object references can currently be held |
1042 // by WTF::Closure<>s. i.e., bound as a 'this' pointer only. | 633 // by WTF::Closure<>s. i.e., bound as a 'this' pointer only. |
1043 // | 634 // |
1044 // TODO(sof): once wtf/Functional.h is able to work over platform/heap/ types | 635 // TODO(sof): once wtf/Functional.h is able to work over platform/heap/ types |
1045 // (like CrossThreadWeakPersistent<>), drop the restriction on weak persistent | 636 // (like CrossThreadWeakPersistent<>), drop the restriction on weak persistent |
1046 // use by function closures (and rename this ad-hoc type.) | 637 // use by function closures (and rename this ad-hoc type.) |
1047 template<typename T> | 638 template<typename T> |
1048 class WeakPersistentThisPointer { | 639 class WeakPersistentThisPointer { |
1049 STACK_ALLOCATED(); | 640 STACK_ALLOCATED(); |
1050 public: | 641 public: |
(...skipping 18 matching lines...) Expand all Loading... |
1069 { | 660 { |
1070 return Persistent<T>(value); | 661 return Persistent<T>(value); |
1071 } | 662 } |
1072 | 663 |
1073 template <typename T> | 664 template <typename T> |
1074 CrossThreadPersistent<T> wrapCrossThreadPersistent(T* value) | 665 CrossThreadPersistent<T> wrapCrossThreadPersistent(T* value) |
1075 { | 666 { |
1076 return CrossThreadPersistent<T>(value); | 667 return CrossThreadPersistent<T>(value); |
1077 } | 668 } |
1078 | 669 |
1079 // LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the current scope | 670 // Comparison operators between (Weak)Members, Persistents, and UntracedMembers. |
1080 // will be exempted from LSan consideration. | 671 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Member<U>& b) { return a.get() == b.get(); } |
1081 // | 672 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Member<U>& b) { return a.get() != b.get(); } |
1082 // TODO(sof): move this to wtf/LeakAnnotations.h (LeakSanitizer.h?) once | 673 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() == b.get(); } |
1083 // wtf/ can freely call upon Oilpan functionality. | 674 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Persistent<U>& b) { return a.get() != b.get(); } |
1084 #if defined(LEAK_SANITIZER) | |
1085 class LeakSanitizerDisableScope { | |
1086 STACK_ALLOCATED(); | |
1087 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisableScope); | |
1088 public: | |
1089 LeakSanitizerDisableScope() | |
1090 { | |
1091 __lsan_disable(); | |
1092 if (ThreadState::current()) | |
1093 ThreadState::current()->enterStaticReferenceRegistrationDisabledScop
e(); | |
1094 } | |
1095 | 675 |
1096 ~LeakSanitizerDisableScope() | 676 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } |
1097 { | 677 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() != b.get(); } |
1098 __lsan_enable(); | 678 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Member<U>& b) { return a.get() == b.get(); } |
1099 if (ThreadState::current()) | 679 template<typename T, typename U> inline bool operator!=(const Persistent<T>& a,
const Member<U>& b) { return a.get() != b.get(); } |
1100 ThreadState::current()->leaveStaticReferenceRegistrationDisabledScop
e(); | |
1101 } | |
1102 }; | |
1103 #define LEAK_SANITIZER_DISABLED_SCOPE LeakSanitizerDisableScope lsanDisabledScop
e | |
1104 #else | |
1105 #define LEAK_SANITIZER_DISABLED_SCOPE | |
1106 #endif | |
1107 | 680 |
1108 } // namespace blink | 681 } // namespace blink |
1109 | 682 |
1110 namespace WTF { | 683 namespace WTF { |
1111 | 684 |
1112 template <typename T> | |
1113 struct MemberHash : PtrHash<T> { | |
1114 STATIC_ONLY(MemberHash); | |
1115 template <typename U> | |
1116 static unsigned hash(const U& key) { return PtrHash<T>::hash(key); } | |
1117 template <typename U, typename V> | |
1118 static bool equal(const U& a, const V& b) { return a == b; } | |
1119 }; | |
1120 | |
1121 template <typename T> | |
1122 struct WeakMemberHash : MemberHash<T> { | |
1123 STATIC_ONLY(WeakMemberHash); | |
1124 }; | |
1125 | |
1126 template <typename T> | |
1127 struct UntracedMemberHash : MemberHash<T> { | |
1128 STATIC_ONLY(UntracedMemberHash); | |
1129 }; | |
1130 | |
1131 // PtrHash is the default hash for hash tables with members. | |
1132 template <typename T> | |
1133 struct DefaultHash<blink::Member<T>> { | |
1134 STATIC_ONLY(DefaultHash); | |
1135 using Hash = MemberHash<T>; | |
1136 }; | |
1137 | |
1138 template <typename T> | |
1139 struct DefaultHash<blink::WeakMember<T>> { | |
1140 STATIC_ONLY(DefaultHash); | |
1141 using Hash = WeakMemberHash<T>; | |
1142 }; | |
1143 | |
1144 template <typename T> | |
1145 struct DefaultHash<blink::UntracedMember<T>> { | |
1146 STATIC_ONLY(DefaultHash); | |
1147 using Hash = UntracedMemberHash<T>; | |
1148 }; | |
1149 | |
1150 template<typename T> | |
1151 struct NeedsTracing<blink::Member<T>> { | |
1152 STATIC_ONLY(NeedsTracing); | |
1153 static const bool value = true; | |
1154 }; | |
1155 | |
1156 template<typename T> | |
1157 struct IsWeak<blink::WeakMember<T>> { | |
1158 STATIC_ONLY(IsWeak); | |
1159 static const bool value = true; | |
1160 }; | |
1161 | |
1162 // For wtf/Functional.h | |
1163 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; | |
1164 | |
1165 // The condition of 'T must be fully defined' (except for void) is checked in | |
1166 // blink::IsGarbageCollectedType<T>::value. | |
1167 template<typename T> | |
1168 struct PointerParamStorageTraits<T*, false> { | |
1169 STATIC_ONLY(PointerParamStorageTraits); | |
1170 using StorageType = T*; | |
1171 | |
1172 static StorageType wrap(T* value) { return value; } | |
1173 static T* unwrap(const StorageType& value) { return value; } | |
1174 }; | |
1175 | |
1176 template<typename T> | |
1177 struct PointerParamStorageTraits<T*, true> { | |
1178 STATIC_ONLY(PointerParamStorageTraits); | |
1179 using StorageType = blink::CrossThreadPersistent<T>; | |
1180 | |
1181 static StorageType wrap(T* value) { return value; } | |
1182 static T* unwrap(const StorageType& value) { return value.get(); } | |
1183 }; | |
1184 | |
1185 template<typename T> | |
1186 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGa
rbageCollectedType<T>::value> { | |
1187 STATIC_ONLY(ParamStorageTraits); | |
1188 }; | |
1189 | |
1190 template<typename T> | 685 template<typename T> |
1191 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { | 686 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { |
1192 STATIC_ONLY(ParamStorageTraits); | 687 STATIC_ONLY(ParamStorageTraits); |
1193 static_assert(sizeof(T), "T must be fully defined"); | 688 static_assert(sizeof(T), "T must be fully defined"); |
1194 using StorageType = blink::WeakPersistent<T>; | 689 using StorageType = blink::WeakPersistent<T>; |
1195 | 690 |
1196 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) {
return value.value(); } | 691 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) {
return value.value(); } |
1197 | 692 |
1198 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent | 693 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent |
1199 // into it. | 694 // into it. |
(...skipping 14 matching lines...) Expand all Loading... |
1214 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent | 709 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent |
1215 // into it. | 710 // into it. |
1216 // | 711 // |
1217 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty
pe like | 712 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty
pe like |
1218 // CrossThreadWeakPersistent<>. | 713 // CrossThreadWeakPersistent<>. |
1219 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR
eference<T>::create(value.get())); } | 714 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR
eference<T>::create(value.get())); } |
1220 }; | 715 }; |
1221 | 716 |
1222 } // namespace WTF | 717 } // namespace WTF |
1223 | 718 |
1224 #endif | 719 #endif // Persistent_h |
OLD | NEW |