DDLifetimes.h (4592B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef DDLifetimes_h_ 8 #define DDLifetimes_h_ 9 10 #include <type_traits> 11 12 #include "DDLifetime.h" 13 #include "DDLoggedTypeTraits.h" 14 #include "nsClassHashtable.h" 15 #include "nsTArray.h" 16 17 namespace mozilla { 18 19 // Managed list of lifetimes. 20 class DDLifetimes { 21 public: 22 // DDLifetime for a given aObject, that exists at the aIndex time; 23 // otherwise nullptr. 24 DDLifetime* FindLifetime(const DDLogObject& aObject, 25 const DDMessageIndex& aIndex); 26 27 // DDLifetime for a given aObject, that exists at the aIndex time; 28 // otherwise nullptr. 29 const DDLifetime* FindLifetime(const DDLogObject& aObject, 30 const DDMessageIndex& aIndex) const; 31 32 // Create a lifetime with the given object and construction index&time. 33 DDLifetime& CreateLifetime(const DDLogObject& aObject, DDMessageIndex aIndex, 34 const DDTimeStamp& aConstructionTimeStamp); 35 36 // Remove an existing lifetime (assumed to just have been found by 37 // FindLifetime()). 38 void RemoveLifetime(const DDLifetime* aLifetime); 39 40 // Remove all lifetimes associated with the given HTMLMediaElement. 41 void RemoveLifetimesFor(const dom::HTMLMediaElement* aMediaElement); 42 43 // Remove all lifetimes. 44 void Clear(); 45 46 // Visit all lifetimes associated with an HTMLMediaElement and run 47 // `aF(const DDLifetime&)` on each one. 48 // If aOnlyHTMLMediaElement is true, only run aF once of that element. 49 template <typename F> 50 void Visit(const dom::HTMLMediaElement* aMediaElement, F&& aF, 51 bool aOnlyHTMLMediaElement = false) const { 52 for (const auto& lifetimes : mLifetimes.Values()) { 53 for (const DDLifetime& lifetime : *lifetimes) { 54 if (lifetime.mMediaElement == aMediaElement) { 55 if (aOnlyHTMLMediaElement) { 56 if (lifetime.mObject.Pointer() == aMediaElement && 57 lifetime.mObject.TypeName() == 58 DDLoggedTypeTraits<dom::HTMLMediaElement>::Name()) { 59 aF(lifetime); 60 break; 61 } 62 continue; 63 } 64 static_assert(std::is_same_v<decltype(aF(lifetime)), void>, ""); 65 aF(lifetime); 66 } 67 } 68 } 69 } 70 71 // Visit all lifetimes associated with an HTMLMediaElement and run 72 // `aF(const DDLifetime&)` on each one. 73 // If aF() returns false, the loop continues. 74 // If aF() returns true, the loop stops, and true is returned immediately. 75 // If all aF() calls have returned false, false is returned at the end. 76 template <typename F> 77 bool VisitBreakable(const dom::HTMLMediaElement* aMediaElement, 78 F&& aF) const { 79 for (const auto& lifetimes : mLifetimes.Values()) { 80 for (const DDLifetime& lifetime : *lifetimes) { 81 if (lifetime.mMediaElement == aMediaElement) { 82 static_assert(std::is_same_v<decltype(aF(lifetime)), bool>, ""); 83 if (aF(lifetime)) { 84 return true; 85 } 86 } 87 } 88 } 89 return false; 90 } 91 92 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; 93 94 private: 95 // Hashtable key to use for each DDLogObject. 96 class DDLogObjectHashKey : public PLDHashEntryHdr { 97 public: 98 typedef const DDLogObject& KeyType; 99 typedef const DDLogObject* KeyTypePointer; 100 101 explicit DDLogObjectHashKey(KeyTypePointer aKey) : mValue(*aKey) {} 102 DDLogObjectHashKey(const DDLogObjectHashKey& aToCopy) 103 : mValue(aToCopy.mValue) {} 104 ~DDLogObjectHashKey() = default; 105 106 KeyType GetKey() const { return mValue; } 107 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; } 108 109 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 110 static PLDHashNumber HashKey(KeyTypePointer aKey) { 111 return HashBytes(aKey, sizeof(DDLogObject)); 112 } 113 enum { ALLOW_MEMMOVE = true }; 114 115 private: 116 const DDLogObject mValue; 117 }; 118 119 // Array of all DDLifetimes for a given DDLogObject; they should be 120 // distinguished by their construction&destruction times. 121 using LifetimesForObject = nsTArray<DDLifetime>; 122 123 // For each DDLogObject, we store an array of all objects that have used this 124 // pointer and type. 125 nsClassHashtable<DDLogObjectHashKey, LifetimesForObject> mLifetimes; 126 }; 127 128 } // namespace mozilla 129 130 #endif // DDLifetimes_h_