Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: third_party/WebKit/Source/platform/heap/Persistent.h

Issue 2000673003: Split out Members, Persistents and SelfKeepAlive in separate headers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Phase out blink::IsGarbageCollectedType<T> Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/Member.h ('k') | third_party/WebKit/Source/platform/heap/SelfKeepAlive.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698