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

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