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 | |
45 #if defined(LEAK_SANITIZER) | |
46 #include "wtf/LeakAnnotations.h" | |
47 #endif | |
48 | 12 |
49 namespace blink { | 13 namespace blink { |
50 | 14 |
51 // Marker used to annotate persistent objects and collections with, | 15 // Marker used to annotate persistent objects and collections with, |
52 // so as to enable reliable testing for persistent references via | 16 // so as to enable reliable testing for persistent references via |
53 // a type trait (see TypeTraits.h's IsPersistentReferenceType<>.) | 17 // a type trait (see TypeTraits.h's IsPersistentReferenceType<>.) |
54 #define IS_PERSISTENT_REFERENCE_TYPE() \ | 18 #define IS_PERSISTENT_REFERENCE_TYPE() \ |
55 public: \ | 19 public: \ |
56 using IsPersistentReferenceTypeMarker = int; \ | 20 using IsPersistentReferenceTypeMarker = int; \ |
57 private: | 21 private: |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 public: | 622 public: |
659 PersistentHeapDeque() { } | 623 PersistentHeapDeque() { } |
660 | 624 |
661 template<size_t otherCapacity> | 625 template<size_t otherCapacity> |
662 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) | 626 PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other) |
663 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) | 627 : PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) |
664 { | 628 { |
665 } | 629 } |
666 }; | 630 }; |
667 | 631 |
668 // Members are used in classes to contain strong pointers to other oilpan heap | |
669 // allocated objects. | |
670 // All Member fields of a class must be traced in the class' trace method. | |
671 // During the mark phase of the GC all live objects are marked as live and | |
672 // all Member fields of a live object will be traced marked as live as well. | |
673 template<typename T> | |
674 class Member { | |
675 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | |
676 public: | |
677 Member() : m_raw(nullptr) | |
678 { | |
679 } | |
680 | |
681 Member(std::nullptr_t) : m_raw(nullptr) | |
682 { | |
683 } | |
684 | |
685 Member(T* raw) : m_raw(raw) | |
686 { | |
687 checkPointer(); | |
688 } | |
689 | |
690 explicit Member(T& raw) : m_raw(&raw) | |
691 { | |
692 checkPointer(); | |
693 } | |
694 | |
695 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) | |
696 { | |
697 } | |
698 | |
699 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(
-1); } | |
700 | |
701 template<typename U> | |
702 Member(const Persistent<U>& other) : m_raw(other) | |
703 { | |
704 checkPointer(); | |
705 } | |
706 | |
707 Member(const Member& other) : m_raw(other) | |
708 { | |
709 checkPointer(); | |
710 } | |
711 | |
712 template<typename U> | |
713 Member(const Member<U>& other) : m_raw(other) | |
714 { | |
715 checkPointer(); | |
716 } | |
717 | |
718 T* release() | |
719 { | |
720 T* result = m_raw; | |
721 m_raw = nullptr; | |
722 return result; | |
723 } | |
724 | |
725 explicit operator bool() const { return m_raw; } | |
726 | |
727 operator T*() const { return m_raw; } | |
728 | |
729 T* operator->() const { return m_raw; } | |
730 T& operator*() const { return *m_raw; } | |
731 | |
732 template<typename U> | |
733 Member& operator=(const Persistent<U>& other) | |
734 { | |
735 m_raw = other; | |
736 checkPointer(); | |
737 return *this; | |
738 } | |
739 | |
740 template<typename U> | |
741 Member& operator=(const Member<U>& other) | |
742 { | |
743 m_raw = other; | |
744 checkPointer(); | |
745 return *this; | |
746 } | |
747 | |
748 template<typename U> | |
749 Member& operator=(U* other) | |
750 { | |
751 m_raw = other; | |
752 checkPointer(); | |
753 return *this; | |
754 } | |
755 | |
756 Member& operator=(std::nullptr_t) | |
757 { | |
758 m_raw = nullptr; | |
759 return *this; | |
760 } | |
761 | |
762 void swap(Member<T>& other) | |
763 { | |
764 std::swap(m_raw, other.m_raw); | |
765 checkPointer(); | |
766 } | |
767 | |
768 T* get() const { return m_raw; } | |
769 | |
770 void clear() { m_raw = nullptr; } | |
771 | |
772 | |
773 protected: | |
774 void checkPointer() | |
775 { | |
776 #if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) | |
777 if (!m_raw) | |
778 return; | |
779 // HashTable can store a special value (which is not aligned to the | |
780 // allocation granularity) to Member<> to represent a deleted entry. | |
781 // Thus we treat a pointer that is not aligned to the granularity | |
782 // as a valid pointer. | |
783 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) | |
784 return; | |
785 | |
786 // TODO(haraken): What we really want to check here is that the pointer | |
787 // is a traceable object. In other words, the pointer is either of: | |
788 // | |
789 // (a) a pointer to the head of an on-heap object. | |
790 // (b) a pointer to the head of an on-heap mixin object. | |
791 // | |
792 // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw), | |
793 // but we cannot call it here because it requires to include T.h. | |
794 // So we currently only try to implement the check for (a), but do | |
795 // not insist that T's definition is in scope. | |
796 if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) | |
797 ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); | |
798 #endif | |
799 } | |
800 | |
801 T* m_raw; | |
802 | |
803 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr
ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; | |
804 friend class Visitor; | |
805 | |
806 }; | |
807 | |
808 // WeakMember is similar to Member in that it is used to point to other oilpan | |
809 // heap allocated objects. | |
810 // However instead of creating a strong pointer to the object, the WeakMember cr
eates | |
811 // a weak pointer, which does not keep the pointee alive. Hence if all pointers
to | |
812 // to a heap allocated object are weak the object will be garbage collected. At
the | |
813 // time of GC the weak pointers will automatically be set to null. | |
814 template<typename T> | |
815 class WeakMember : public Member<T> { | |
816 public: | |
817 WeakMember() : Member<T>() { } | |
818 | |
819 WeakMember(std::nullptr_t) : Member<T>(nullptr) { } | |
820 | |
821 WeakMember(T* raw) : Member<T>(raw) { } | |
822 | |
823 WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } | |
824 | |
825 template<typename U> | |
826 WeakMember(const Persistent<U>& other) : Member<T>(other) { } | |
827 | |
828 template<typename U> | |
829 WeakMember(const Member<U>& other) : Member<T>(other) { } | |
830 | |
831 template<typename U> | |
832 WeakMember& operator=(const Persistent<U>& other) | |
833 { | |
834 this->m_raw = other; | |
835 this->checkPointer(); | |
836 return *this; | |
837 } | |
838 | |
839 template<typename U> | |
840 WeakMember& operator=(const Member<U>& other) | |
841 { | |
842 this->m_raw = other; | |
843 this->checkPointer(); | |
844 return *this; | |
845 } | |
846 | |
847 template<typename U> | |
848 WeakMember& operator=(U* other) | |
849 { | |
850 this->m_raw = other; | |
851 this->checkPointer(); | |
852 return *this; | |
853 } | |
854 | |
855 WeakMember& operator=(std::nullptr_t) | |
856 { | |
857 this->m_raw = nullptr; | |
858 return *this; | |
859 } | |
860 | |
861 private: | |
862 T** cell() const { return const_cast<T**>(&this->m_raw); } | |
863 | |
864 template<typename Derived> friend class VisitorHelper; | |
865 }; | |
866 | |
867 // UntracedMember is a pointer to an on-heap object that is not traced for some | |
868 // reason. Please don't use this unless you understand what you're doing. | |
869 // Basically, all pointers to on-heap objects must be stored in either of | |
870 // Persistent, Member or WeakMember. It is not allowed to leave raw pointers to | |
871 // on-heap objects. However, there can be scenarios where you have to use raw | |
872 // pointers for some reason, and in that case you can use UntracedMember. Of | |
873 // course, it must be guaranteed that the pointing on-heap object is kept alive | |
874 // while the raw pointer is pointing to the object. | |
875 template<typename T> | |
876 class UntracedMember final : public Member<T> { | |
877 public: | |
878 UntracedMember() : Member<T>() { } | |
879 | |
880 UntracedMember(std::nullptr_t) : Member<T>(nullptr) { } | |
881 | |
882 UntracedMember(T* raw) : Member<T>(raw) { } | |
883 | |
884 template<typename U> | |
885 UntracedMember(const Persistent<U>& other) : Member<T>(other) { } | |
886 | |
887 template<typename U> | |
888 UntracedMember(const Member<U>& other) : Member<T>(other) { } | |
889 | |
890 UntracedMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { } | |
891 | |
892 template<typename U> | |
893 UntracedMember& operator=(const Persistent<U>& other) | |
894 { | |
895 this->m_raw = other; | |
896 this->checkPointer(); | |
897 return *this; | |
898 } | |
899 | |
900 template<typename U> | |
901 UntracedMember& operator=(const Member<U>& other) | |
902 { | |
903 this->m_raw = other; | |
904 this->checkPointer(); | |
905 return *this; | |
906 } | |
907 | |
908 template<typename U> | |
909 UntracedMember& operator=(U* other) | |
910 { | |
911 this->m_raw = other; | |
912 this->checkPointer(); | |
913 return *this; | |
914 } | |
915 | |
916 UntracedMember& operator=(std::nullptr_t) | |
917 { | |
918 this->m_raw = nullptr; | |
919 return *this; | |
920 } | |
921 }; | |
922 | |
923 // Comparison operators between (Weak)Members, Persistents, and UntracedMembers. | |
924 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Member<U>& b) { return a.get() == b.get(); } | |
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 Persistent<T>& a,
const Persistent<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 | |
929 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } | |
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 Persistent<T>& a,
const Member<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 | |
934 template<typename T, bool = IsGarbageCollectedType<T>::value> | |
935 class RawPtrOrMemberTrait { | |
936 STATIC_ONLY(RawPtrOrMemberTrait) | |
937 public: | |
938 using Type = T*; | |
939 }; | |
940 | |
941 template<typename T> | |
942 class RawPtrOrMemberTrait<T, true> { | |
943 STATIC_ONLY(RawPtrOrMemberTrait) | |
944 public: | |
945 using Type = Member<T>; | |
946 }; | |
947 | |
948 // Abstraction for injecting calls to an object's 'dispose()' method | |
949 // on leaving a stack scope, ensuring earlier release of resources | |
950 // than waiting until the object is eventually GCed. | |
951 template<typename T, void (T::*Disposer)() = (&T::dispose)> | |
952 class ScopedDisposal { | |
953 STACK_ALLOCATED(); | |
954 public: | |
955 ScopedDisposal(T* object) | |
956 : m_object(object) | |
957 { | |
958 } | |
959 | |
960 ~ScopedDisposal() | |
961 { | |
962 if (m_object) | |
963 (m_object->*Disposer)(); | |
964 } | |
965 | |
966 void clear() { m_object.clear(); } | |
967 | |
968 private: | |
969 typename RawPtrOrMemberTrait<T>::Type m_object; | |
970 }; | |
971 | |
972 // SelfKeepAlive<Object> is the idiom to use for objects that have to keep | |
973 // themselves temporarily alive and cannot rely on there being some | |
974 // external reference in that interval: | |
975 // | |
976 // class Opener { | |
977 // public: | |
978 // ... | |
979 // void open() | |
980 // { | |
981 // // Retain a self-reference while in an open()ed state: | |
982 // m_keepAlive = this; | |
983 // .... | |
984 // } | |
985 // | |
986 // void close() | |
987 // { | |
988 // // Clear self-reference that ensured we were kept alive while opened. | |
989 // m_keepAlive.clear(); | |
990 // .... | |
991 // } | |
992 // | |
993 // private: | |
994 // ... | |
995 // SelfKeepAlive m_keepAlive; | |
996 // }; | |
997 // | |
998 // The responsibility to call clear() in a timely fashion resides with the imple
mentation | |
999 // of the object. | |
1000 // | |
1001 // | |
1002 template<typename Self> | |
1003 class SelfKeepAlive final { | |
1004 DISALLOW_NEW(); | |
1005 public: | |
1006 SelfKeepAlive() | |
1007 { | |
1008 } | |
1009 | |
1010 explicit SelfKeepAlive(Self* self) | |
1011 { | |
1012 assign(self); | |
1013 } | |
1014 | |
1015 SelfKeepAlive& operator=(Self* self) | |
1016 { | |
1017 assign(self); | |
1018 return *this; | |
1019 } | |
1020 | |
1021 void clear() | |
1022 { | |
1023 m_keepAlive.clear(); | |
1024 } | |
1025 | |
1026 typedef Persistent<Self> (SelfKeepAlive::*UnspecifiedBoolType); | |
1027 operator UnspecifiedBoolType() const { return m_keepAlive ? &SelfKeepAlive::
m_keepAlive : 0; } | |
1028 | |
1029 private: | |
1030 void assign(Self* self) | |
1031 { | |
1032 ASSERT(!m_keepAlive || m_keepAlive.get() == self); | |
1033 m_keepAlive = self; | |
1034 } | |
1035 | |
1036 GC_PLUGIN_IGNORE("420515") | |
1037 Persistent<Self> m_keepAlive; | |
1038 }; | |
1039 | |
1040 // 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 |
1041 // 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. |
1042 // | 634 // |
1043 // 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 |
1044 // (like CrossThreadWeakPersistent<>), drop the restriction on weak persistent | 636 // (like CrossThreadWeakPersistent<>), drop the restriction on weak persistent |
1045 // use by function closures (and rename this ad-hoc type.) | 637 // use by function closures (and rename this ad-hoc type.) |
1046 template<typename T> | 638 template<typename T> |
1047 class WeakPersistentThisPointer { | 639 class WeakPersistentThisPointer { |
1048 STACK_ALLOCATED(); | 640 STACK_ALLOCATED(); |
1049 public: | 641 public: |
(...skipping 18 matching lines...) Expand all Loading... |
1068 { | 660 { |
1069 return Persistent<T>(value); | 661 return Persistent<T>(value); |
1070 } | 662 } |
1071 | 663 |
1072 template <typename T> | 664 template <typename T> |
1073 CrossThreadPersistent<T> wrapCrossThreadPersistent(T* value) | 665 CrossThreadPersistent<T> wrapCrossThreadPersistent(T* value) |
1074 { | 666 { |
1075 return CrossThreadPersistent<T>(value); | 667 return CrossThreadPersistent<T>(value); |
1076 } | 668 } |
1077 | 669 |
1078 // LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the current scope | 670 // Comparison operators between (Weak)Members, Persistents, and UntracedMembers. |
1079 // 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(); } |
1080 // | 672 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Member<U>& b) { return a.get() != b.get(); } |
1081 // 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(); } |
1082 // 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(); } |
1083 #if defined(LEAK_SANITIZER) | |
1084 class LeakSanitizerDisableScope { | |
1085 STACK_ALLOCATED(); | |
1086 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisableScope); | |
1087 public: | |
1088 LeakSanitizerDisableScope() | |
1089 { | |
1090 __lsan_disable(); | |
1091 if (ThreadState::current()) | |
1092 ThreadState::current()->enterStaticReferenceRegistrationDisabledScop
e(); | |
1093 } | |
1094 | 675 |
1095 ~LeakSanitizerDisableScope() | 676 template<typename T, typename U> inline bool operator==(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() == b.get(); } |
1096 { | 677 template<typename T, typename U> inline bool operator!=(const Member<T>& a, cons
t Persistent<U>& b) { return a.get() != b.get(); } |
1097 __lsan_enable(); | 678 template<typename T, typename U> inline bool operator==(const Persistent<T>& a,
const Member<U>& b) { return a.get() == b.get(); } |
1098 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(); } |
1099 ThreadState::current()->leaveStaticReferenceRegistrationDisabledScop
e(); | |
1100 } | |
1101 }; | |
1102 #define LEAK_SANITIZER_DISABLED_SCOPE LeakSanitizerDisableScope lsanDisabledScop
e | |
1103 #else | |
1104 #define LEAK_SANITIZER_DISABLED_SCOPE | |
1105 #endif | |
1106 | 680 |
1107 } // namespace blink | 681 } // namespace blink |
1108 | 682 |
1109 namespace WTF { | 683 namespace WTF { |
1110 | 684 |
1111 template <typename T> | |
1112 struct MemberHash : PtrHash<T> { | |
1113 STATIC_ONLY(MemberHash); | |
1114 template <typename U> | |
1115 static unsigned hash(const U& key) { return PtrHash<T>::hash(key); } | |
1116 template <typename U, typename V> | |
1117 static bool equal(const U& a, const V& b) { return a == b; } | |
1118 }; | |
1119 | |
1120 template <typename T> | |
1121 struct WeakMemberHash : MemberHash<T> { | |
1122 STATIC_ONLY(WeakMemberHash); | |
1123 }; | |
1124 | |
1125 template <typename T> | |
1126 struct UntracedMemberHash : MemberHash<T> { | |
1127 STATIC_ONLY(UntracedMemberHash); | |
1128 }; | |
1129 | |
1130 // PtrHash is the default hash for hash tables with members. | |
1131 template <typename T> | |
1132 struct DefaultHash<blink::Member<T>> { | |
1133 STATIC_ONLY(DefaultHash); | |
1134 using Hash = MemberHash<T>; | |
1135 }; | |
1136 | |
1137 template <typename T> | |
1138 struct DefaultHash<blink::WeakMember<T>> { | |
1139 STATIC_ONLY(DefaultHash); | |
1140 using Hash = WeakMemberHash<T>; | |
1141 }; | |
1142 | |
1143 template <typename T> | |
1144 struct DefaultHash<blink::UntracedMember<T>> { | |
1145 STATIC_ONLY(DefaultHash); | |
1146 using Hash = UntracedMemberHash<T>; | |
1147 }; | |
1148 | |
1149 template<typename T> | |
1150 struct NeedsTracing<blink::Member<T>> { | |
1151 STATIC_ONLY(NeedsTracing); | |
1152 static const bool value = true; | |
1153 }; | |
1154 | |
1155 template<typename T> | |
1156 struct IsWeak<blink::WeakMember<T>> { | |
1157 STATIC_ONLY(IsWeak); | |
1158 static const bool value = true; | |
1159 }; | |
1160 | |
1161 template<typename T> | 685 template<typename T> |
1162 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { | 686 struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { |
1163 STATIC_ONLY(ParamStorageTraits); | 687 STATIC_ONLY(ParamStorageTraits); |
1164 static_assert(sizeof(T), "T must be fully defined"); | 688 static_assert(sizeof(T), "T must be fully defined"); |
1165 using StorageType = blink::WeakPersistent<T>; | 689 using StorageType = blink::WeakPersistent<T>; |
1166 | 690 |
1167 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) {
return value.value(); } | 691 static StorageType wrap(const blink::WeakPersistentThisPointer<T>& value) {
return value.value(); } |
1168 | 692 |
1169 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent | 693 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent |
1170 // into it. | 694 // into it. |
(...skipping 14 matching lines...) Expand all Loading... |
1185 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent | 709 // WTF::FunctionWrapper<> handles WeakPtr<>, so recast this weak persistent |
1186 // into it. | 710 // into it. |
1187 // | 711 // |
1188 // 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 |
1189 // CrossThreadWeakPersistent<>. | 713 // CrossThreadWeakPersistent<>. |
1190 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())); } |
1191 }; | 715 }; |
1192 | 716 |
1193 } // namespace WTF | 717 } // namespace WTF |
1194 | 718 |
1195 #endif | 719 #endif // Persistent_h |
OLD | NEW |