You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
371 lines
13 KiB
371 lines
13 KiB
diff --git a/Source/WebCore/dom/ElementIdentifier.h b/Source/WebCore/dom/ElementIdentifier.h |
|
index 2ed378242a4c..5cea026d9362 100644 |
|
--- a/Source/WebCore/dom/ElementIdentifier.h |
|
+++ b/Source/WebCore/dom/ElementIdentifier.h |
|
@@ -25,11 +25,150 @@ |
|
|
|
#pragma once |
|
|
|
-#include <wtf/ObjectIdentifier.h> |
|
+#include <atomic> |
|
+#include <mutex> |
|
+#include <wtf/HashTraits.h> |
|
+#include <wtf/NeverDestroyed.h> |
|
+#include <wtf/text/TextStream.h> |
|
+#include <wtf/text/WTFString.h> |
|
|
|
namespace WebCore { |
|
|
|
enum ElementIdentifierType { }; |
|
-using ElementIdentifier = ObjectIdentifier<ElementIdentifierType>; |
|
|
|
+class ElementIdentifierBase { |
|
+protected: |
|
+ WTF_EXPORT_PRIVATE static uint64_t generateIdentifierInternal(); |
|
+ WTF_EXPORT_PRIVATE static uint64_t generateThreadSafeIdentifierInternal(); |
|
+}; |
|
+ |
|
+class ElementIdentifier : private ElementIdentifierBase { |
|
+public: |
|
+ static ElementIdentifier generate() |
|
+ { |
|
+ RELEASE_ASSERT(!m_generationProtected); |
|
+ return ElementIdentifier { generateIdentifierInternal() }; |
|
+ } |
|
+ |
|
+ static ElementIdentifier generateThreadSafe() |
|
+ { |
|
+ RELEASE_ASSERT(!m_generationProtected); |
|
+ return ElementIdentifier { generateThreadSafeIdentifierInternal() }; |
|
+ } |
|
+ |
|
+ static void enableGenerationProtection() |
|
+ { |
|
+ m_generationProtected = true; |
|
+ } |
|
+ |
|
+ ElementIdentifier() = default; |
|
+ |
|
+ ElementIdentifier(WTF::HashTableDeletedValueType) : m_identifier(hashTableDeletedValue()) { } |
|
+ bool isHashTableDeletedValue() const { return m_identifier == hashTableDeletedValue(); } |
|
+ |
|
+ template<typename Encoder> void encode(Encoder& encoder) const |
|
+ { |
|
+ ASSERT(isValidIdentifier(m_identifier)); |
|
+ encoder << m_identifier; |
|
+ } |
|
+ template<typename Decoder> static Optional<ElementIdentifier> decode(Decoder& decoder) |
|
+ { |
|
+ Optional<uint64_t> identifier; |
|
+ decoder >> identifier; |
|
+ if (!identifier || !isValidIdentifier(*identifier)) |
|
+ return WTF::nullopt; |
|
+ return ElementIdentifier { *identifier }; |
|
+ } |
|
+ |
|
+ bool operator==(const ElementIdentifier& other) const |
|
+ { |
|
+ return m_identifier == other.m_identifier; |
|
+ } |
|
+ |
|
+ bool operator!=(const ElementIdentifier& other) const |
|
+ { |
|
+ return m_identifier != other.m_identifier; |
|
+ } |
|
+ |
|
+ operator uint64_t() const { return m_identifier; } |
|
+ uint64_t toUInt64() const { return m_identifier; } |
|
+ explicit operator bool() const { return m_identifier; } |
|
+ |
|
+ String loggingString() const |
|
+ { |
|
+ return String::number(m_identifier); |
|
+ } |
|
+ |
|
+ struct MarkableTraits { |
|
+ static bool isEmptyValue(ElementIdentifier identifier) |
|
+ { |
|
+ return !identifier.m_identifier; |
|
+ } |
|
+ |
|
+ static constexpr ElementIdentifier emptyValue() |
|
+ { |
|
+ return ElementIdentifier(); |
|
+ } |
|
+ }; |
|
+ |
|
+private: |
|
+ friend ElementIdentifier makeElementIdentifier(uint64_t); |
|
+ friend struct HashTraits<ElementIdentifier>; |
|
+ friend struct ElementIdentifierHash; |
|
+ |
|
+ static uint64_t hashTableDeletedValue() { return std::numeric_limits<uint64_t>::max(); } |
|
+ static bool isValidIdentifier(uint64_t identifier) { return identifier && identifier != hashTableDeletedValue(); } |
|
+ |
|
+ explicit constexpr ElementIdentifier(uint64_t identifier) |
|
+ : m_identifier(identifier) |
|
+ { |
|
+ } |
|
+ |
|
+ uint64_t m_identifier { 0 }; |
|
+ inline static bool m_generationProtected { false }; |
|
+}; |
|
+ |
|
+inline ElementIdentifier makeElementIdentifier(uint64_t identifier) |
|
+{ |
|
+ return ElementIdentifier { identifier }; |
|
+} |
|
+ |
|
+struct ElementIdentifierHash { |
|
+ static unsigned hash(const ElementIdentifier& identifier) { return WTF::intHash(identifier.m_identifier); } |
|
+ static bool equal(const ElementIdentifier& a, const ElementIdentifier& b) { return a == b; } |
|
+ static constexpr bool safeToCompareToEmptyOrDeleted = true; |
|
+}; |
|
+ |
|
+inline TextStream& operator<<(TextStream& ts, const ElementIdentifier& identifier) |
|
+{ |
|
+ ts << identifier.toUInt64(); |
|
+ return ts; |
|
+} |
|
+ |
|
+inline uint64_t ElementIdentifierBase::generateIdentifierInternal() |
|
+{ |
|
+ static uint64_t current; |
|
+ return ++current; |
|
} |
|
+ |
|
+inline uint64_t ElementIdentifierBase::generateThreadSafeIdentifierInternal() |
|
+{ |
|
+ static LazyNeverDestroyed<std::atomic<uint64_t>> current; |
|
+ static std::once_flag initializeCurrentIdentifier; |
|
+ std::call_once(initializeCurrentIdentifier, [] { |
|
+ current.construct(0); |
|
+ }); |
|
+ return ++current.get(); |
|
+} |
|
+ |
|
+} // namespace WebCore |
|
+ |
|
+namespace WTF { |
|
+ |
|
+template<> struct HashTraits<WebCore::ElementIdentifier> : SimpleClassHashTraits<WebCore::ElementIdentifier> { }; |
|
+ |
|
+template<> struct DefaultHash<WebCore::ElementIdentifier> { |
|
+ typedef WebCore::ElementIdentifierHash Hash; |
|
+}; |
|
+ |
|
+} // namespace WTF |
|
diff --git a/Source/WebCore/page/PageIdentifier.h b/Source/WebCore/page/PageIdentifier.h |
|
index 44d5f8d29756..07f7f2750af2 100644 |
|
--- a/Source/WebCore/page/PageIdentifier.h |
|
+++ b/Source/WebCore/page/PageIdentifier.h |
|
@@ -25,11 +25,150 @@ |
|
|
|
#pragma once |
|
|
|
-#include <wtf/ObjectIdentifier.h> |
|
+#include <atomic> |
|
+#include <mutex> |
|
+#include <wtf/HashTraits.h> |
|
+#include <wtf/NeverDestroyed.h> |
|
+#include <wtf/text/TextStream.h> |
|
+#include <wtf/text/WTFString.h> |
|
|
|
namespace WebCore { |
|
|
|
enum PageIdentifierType { }; |
|
-using PageIdentifier = ObjectIdentifier<PageIdentifierType>; |
|
|
|
+class PageIdentifierBase { |
|
+protected: |
|
+ WTF_EXPORT_PRIVATE static uint64_t generateIdentifierInternal(); |
|
+ WTF_EXPORT_PRIVATE static uint64_t generateThreadSafeIdentifierInternal(); |
|
+}; |
|
+ |
|
+class PageIdentifier : private PageIdentifierBase { |
|
+public: |
|
+ static PageIdentifier generate() |
|
+ { |
|
+ RELEASE_ASSERT(!m_generationProtected); |
|
+ return PageIdentifier { generateIdentifierInternal() }; |
|
+ } |
|
+ |
|
+ static PageIdentifier generateThreadSafe() |
|
+ { |
|
+ RELEASE_ASSERT(!m_generationProtected); |
|
+ return PageIdentifier { generateThreadSafeIdentifierInternal() }; |
|
+ } |
|
+ |
|
+ static void enableGenerationProtection() |
|
+ { |
|
+ m_generationProtected = true; |
|
+ } |
|
+ |
|
+ PageIdentifier() = default; |
|
+ |
|
+ PageIdentifier(WTF::HashTableDeletedValueType) : m_identifier(hashTableDeletedValue()) { } |
|
+ bool isHashTableDeletedValue() const { return m_identifier == hashTableDeletedValue(); } |
|
+ |
|
+ template<typename Encoder> void encode(Encoder& encoder) const |
|
+ { |
|
+ ASSERT(isValidIdentifier(m_identifier)); |
|
+ encoder << m_identifier; |
|
+ } |
|
+ template<typename Decoder> static Optional<PageIdentifier> decode(Decoder& decoder) |
|
+ { |
|
+ Optional<uint64_t> identifier; |
|
+ decoder >> identifier; |
|
+ if (!identifier || !isValidIdentifier(*identifier)) |
|
+ return WTF::nullopt; |
|
+ return PageIdentifier { *identifier }; |
|
+ } |
|
+ |
|
+ bool operator==(const PageIdentifier& other) const |
|
+ { |
|
+ return m_identifier == other.m_identifier; |
|
+ } |
|
+ |
|
+ bool operator!=(const PageIdentifier& other) const |
|
+ { |
|
+ return m_identifier != other.m_identifier; |
|
+ } |
|
+ |
|
+ operator uint64_t() const { return m_identifier; } |
|
+ uint64_t toUInt64() const { return m_identifier; } |
|
+ explicit operator bool() const { return m_identifier; } |
|
+ |
|
+ String loggingString() const |
|
+ { |
|
+ return String::number(m_identifier); |
|
+ } |
|
+ |
|
+ struct MarkableTraits { |
|
+ static bool isEmptyValue(PageIdentifier identifier) |
|
+ { |
|
+ return !identifier.m_identifier; |
|
+ } |
|
+ |
|
+ static constexpr PageIdentifier emptyValue() |
|
+ { |
|
+ return PageIdentifier(); |
|
+ } |
|
+ }; |
|
+ |
|
+private: |
|
+ friend PageIdentifier makePageIdentifier(uint64_t); |
|
+ friend struct HashTraits<PageIdentifier>; |
|
+ friend struct PageIdentifierHash; |
|
+ |
|
+ static uint64_t hashTableDeletedValue() { return std::numeric_limits<uint64_t>::max(); } |
|
+ static bool isValidIdentifier(uint64_t identifier) { return identifier && identifier != hashTableDeletedValue(); } |
|
+ |
|
+ explicit constexpr PageIdentifier(uint64_t identifier) |
|
+ : m_identifier(identifier) |
|
+ { |
|
+ } |
|
+ |
|
+ uint64_t m_identifier { 0 }; |
|
+ inline static bool m_generationProtected { false }; |
|
+}; |
|
+ |
|
+inline PageIdentifier makePageIdentifier(uint64_t identifier) |
|
+{ |
|
+ return PageIdentifier { identifier }; |
|
+} |
|
+ |
|
+struct PageIdentifierHash { |
|
+ static unsigned hash(const PageIdentifier& identifier) { return WTF::intHash(identifier.m_identifier); } |
|
+ static bool equal(const PageIdentifier& a, const PageIdentifier& b) { return a == b; } |
|
+ static constexpr bool safeToCompareToEmptyOrDeleted = true; |
|
+}; |
|
+ |
|
+inline TextStream& operator<<(TextStream& ts, const PageIdentifier& identifier) |
|
+{ |
|
+ ts << identifier.toUInt64(); |
|
+ return ts; |
|
+} |
|
+ |
|
+inline uint64_t PageIdentifierBase::generateIdentifierInternal() |
|
+{ |
|
+ static uint64_t current; |
|
+ return ++current; |
|
} |
|
+ |
|
+inline uint64_t PageIdentifierBase::generateThreadSafeIdentifierInternal() |
|
+{ |
|
+ static LazyNeverDestroyed<std::atomic<uint64_t>> current; |
|
+ static std::once_flag initializeCurrentIdentifier; |
|
+ std::call_once(initializeCurrentIdentifier, [] { |
|
+ current.construct(0); |
|
+ }); |
|
+ return ++current.get(); |
|
+} |
|
+ |
|
+} // namespace WebCore |
|
+ |
|
+namespace WTF { |
|
+ |
|
+template<> struct HashTraits<WebCore::PageIdentifier> : SimpleClassHashTraits<WebCore::PageIdentifier> { }; |
|
+ |
|
+template<> struct DefaultHash<WebCore::PageIdentifier> { |
|
+ typedef WebCore::PageIdentifierHash Hash; |
|
+}; |
|
+ |
|
+} // namespace WTF |
|
diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCache.h b/Source/WebKit/NetworkProcess/cache/NetworkCache.h |
|
index 04d7d6af73bc..d7bfee11b030 100644 |
|
--- a/Source/WebKit/NetworkProcess/cache/NetworkCache.h |
|
+++ b/Source/WebKit/NetworkProcess/cache/NetworkCache.h |
|
@@ -225,7 +225,7 @@ struct GlobalFrameIDHash { |
|
template<> struct HashTraits<WebKit::NetworkCache::GlobalFrameID> : GenericHashTraits<WebKit::NetworkCache::GlobalFrameID> { |
|
static WebKit::NetworkCache::GlobalFrameID emptyValue() { return { }; } |
|
|
|
- static void constructDeletedValue(WebKit::NetworkCache::GlobalFrameID& slot) { slot.webPageID = makeObjectIdentifier<WebCore::PageIdentifierType>(std::numeric_limits<uint64_t>::max()); } |
|
+ static void constructDeletedValue(WebKit::NetworkCache::GlobalFrameID& slot) { slot.webPageID = WebCore::makePageIdentifier(std::numeric_limits<uint64_t>::max()); } |
|
|
|
static bool isDeletedValue(const WebKit::NetworkCache::GlobalFrameID& slot) { return slot.webPageID.toUInt64() == std::numeric_limits<uint64_t>::max(); } |
|
}; |
|
diff --git a/Source/WebKit/UIProcess/gtk/WaylandCompositor.cpp b/Source/WebKit/UIProcess/gtk/WaylandCompositor.cpp |
|
index b34d13b865c5..26083eda5486 100644 |
|
--- a/Source/WebKit/UIProcess/gtk/WaylandCompositor.cpp |
|
+++ b/Source/WebKit/UIProcess/gtk/WaylandCompositor.cpp |
|
@@ -388,7 +388,7 @@ static const struct wl_webkitgtk_interface webkitgtkInterface = { |
|
return; |
|
|
|
auto* compositor = static_cast<WaylandCompositor*>(wl_resource_get_user_data(resource)); |
|
- compositor->bindSurfaceToWebPage(surface, makeObjectIdentifier<PageIdentifierType>(pageID)); |
|
+ compositor->bindSurfaceToWebPage(surface, WebCore::makePageIdentifier(pageID)); |
|
} |
|
}; |
|
|
|
diff --git a/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp b/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp |
|
index 5f3cca93e3ac..b52c36838dcd 100644 |
|
--- a/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp |
|
+++ b/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp |
|
@@ -98,7 +98,7 @@ void NetworkProcessConnection::didReceiveMessage(IPC::Connection& connection, IP |
|
return; |
|
} |
|
if (decoder.messageReceiverName() == Messages::WebPage::messageReceiverName()) { |
|
- if (auto* webPage = WebProcess::singleton().webPage(makeObjectIdentifier<PageIdentifierType>(decoder.destinationID()))) |
|
+ if (auto* webPage = WebProcess::singleton().webPage(WebCore::makePageIdentifier(decoder.destinationID()))) |
|
webPage->didReceiveWebPageMessage(connection, decoder); |
|
return; |
|
} |
|
@@ -152,7 +152,7 @@ void NetworkProcessConnection::didReceiveMessage(IPC::Connection& connection, IP |
|
|
|
#if ENABLE(APPLE_PAY_REMOTE_UI) |
|
if (decoder.messageReceiverName() == Messages::WebPaymentCoordinator::messageReceiverName()) { |
|
- if (auto webPage = WebProcess::singleton().webPage(makeObjectIdentifier<PageIdentifierType>(decoder.destinationID()))) |
|
+ if (auto webPage = WebProcess::singleton().webPage(WebCore::makePageIdentifier(decoder.destinationID()))) |
|
webPage->paymentCoordinator()->didReceiveMessage(connection, decoder); |
|
return; |
|
} |
|
@@ -174,7 +174,7 @@ void NetworkProcessConnection::didReceiveSyncMessage(IPC::Connection& connection |
|
|
|
#if ENABLE(APPLE_PAY_REMOTE_UI) |
|
if (decoder.messageReceiverName() == Messages::WebPaymentCoordinator::messageReceiverName()) { |
|
- if (auto webPage = WebProcess::singleton().webPage(makeObjectIdentifier<PageIdentifierType>(decoder.destinationID()))) |
|
+ if (auto webPage = WebProcess::singleton().webPage(WebCore::makePageIdentifier(decoder.destinationID()))) |
|
webPage->paymentCoordinator()->didReceiveSyncMessage(connection, decoder, replyEncoder); |
|
return; |
|
}
|
|
|