| 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 |