Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (288806 => 288807)
--- trunk/Source/_javascript_Core/ChangeLog 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-01-31 08:48:47 UTC (rev 288807)
@@ -1,3 +1,37 @@
+2022-01-30 Yusuke Suzuki <[email protected]>
+
+ [WTF] Add GenericHashKey
+ https://bugs.webkit.org/show_bug.cgi?id=235872
+
+ Reviewed by Darin Adler.
+
+ Use GenericHashKey and WTF::HashSet / WTF::HashMap.
+
+ * dfg/DFGCommonData.h:
+ * dfg/DFGGraph.h:
+ * dfg/DFGIntegerCheckCombiningPhase.cpp:
+ (JSC::DFG::IntegerCheckCombiningPhase::RangeKey::Hash::hash):
+ (JSC::DFG::IntegerCheckCombiningPhase::RangeKey::Hash::equal):
+ (JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::addressOfDoubleConstant):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+ * runtime/DeferredWorkTimer.cpp:
+ * runtime/FunctionHasExecutedCache.cpp:
+ (JSC::FunctionHasExecutedCache::hasExecutedAtOffset):
+ (JSC::FunctionHasExecutedCache::insertUnexecutedRange):
+ (JSC::FunctionHasExecutedCache::removeUnexecutedRange):
+ (JSC::FunctionHasExecutedCache::getFunctionRanges):
+ * runtime/FunctionHasExecutedCache.h:
+ (JSC::FunctionHasExecutedCache::FunctionRange::Hash::hash):
+ (JSC::FunctionHasExecutedCache::FunctionRange::Hash::equal):
+ * runtime/TypeLocationCache.cpp:
+ (JSC::TypeLocationCache::getTypeLocation):
+ * runtime/TypeLocationCache.h:
+ (JSC::TypeLocationCache::LocationKey::Hash::hash):
+ (JSC::TypeLocationCache::LocationKey::Hash::equal):
+
2022-01-28 Diego Pino Garcia <[email protected]>
[WPE] Unreviewed, fix non-unified build after r288758
Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.h (288806 => 288807)
--- trunk/Source/_javascript_Core/dfg/DFGCommonData.h 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.h 2022-01-31 08:48:47 UTC (rev 288807)
@@ -140,7 +140,7 @@
bool hasVMTrapsBreakpointsInstalled { false };
#if USE(JSVALUE32_64)
- std::unique_ptr<Bag<double>> doubleConstants;
+ Bag<double> doubleConstants;
#endif
unsigned frameRegisterCount { std::numeric_limits<unsigned>::max() };
Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (288806 => 288807)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.h 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h 2022-01-31 08:48:47 UTC (rev 288807)
@@ -40,10 +40,10 @@
#include "JITScannable.h"
#include "MethodOfGettingAValueProfile.h"
#include <wtf/BitVector.h>
+#include <wtf/GenericHashKey.h>
#include <wtf/HashMap.h>
#include <wtf/StackCheck.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/StdUnorderedMap.h>
#include <wtf/Vector.h>
namespace WTF {
@@ -1179,8 +1179,8 @@
HashMap<const StringImpl*, String> m_copiedStrings;
#if USE(JSVALUE32_64)
- StdUnorderedMap<int64_t, double*> m_doubleConstantsMap;
- std::unique_ptr<Bag<double>> m_doubleConstants;
+ HashMap<GenericHashKey<int64_t>, double*> m_doubleConstantsMap;
+ Bag<double> m_doubleConstants;
#endif
OptimizationFixpointState m_fixpointState;
Modified: trunk/Source/_javascript_Core/dfg/DFGIntegerCheckCombiningPhase.cpp (288806 => 288807)
--- trunk/Source/_javascript_Core/dfg/DFGIntegerCheckCombiningPhase.cpp 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/dfg/DFGIntegerCheckCombiningPhase.cpp 2022-01-31 08:48:47 UTC (rev 288807)
@@ -52,6 +52,12 @@
};
struct RangeKey {
+ struct Hash {
+ static unsigned hash(const RangeKey& key) { return key.hash(); }
+ static bool equal(const RangeKey& a, const RangeKey& b) { return a == b; }
+ static constexpr bool safeToCompareToEmptyOrDeleted = false;
+ };
+
static RangeKey addition(Edge edge)
{
RangeKey result;
@@ -185,8 +191,8 @@
dataLog("For ", node, ": ", data, "\n");
if (!data)
continue;
-
- Range& range = m_map[data.m_key];
+
+ Range& range = m_map.add(data.m_key, Range { }).iterator->value;
if (DFGIntegerCheckCombiningPhaseInternal::verbose)
dataLog(" Range: ", range, "\n");
if (range.m_count) {
@@ -213,7 +219,7 @@
RangeKeyAndAddend data = ""
if (!data)
continue;
- Range range = m_map[data.m_key];
+ Range range = m_map.get(data.m_key);
if (!isValid(data.m_key, range))
continue;
@@ -260,7 +266,7 @@
nodeIndex, SpecNone, CheckInBounds, node->origin,
Edge(minNode, Int32Use), Edge(data.m_key.m_key, Int32Use));
}
- m_map[data.m_key].m_dependency = m_insertionSet.insertNode(
+ m_map.find(data.m_key)->value.m_dependency = m_insertionSet.insertNode(
nodeIndex, SpecNone, CheckInBounds, node->origin,
Edge(maxNode, Int32Use), Edge(data.m_key.m_key, Int32Use), Edge(minCheck, UntypedUse));
break;
@@ -271,7 +277,7 @@
}
m_changed = true;
- m_map[data.m_key].m_hoisted = true;
+ m_map.find(data.m_key)->value.m_hoisted = true;
}
// Do the elimination.
@@ -285,7 +291,7 @@
ASSERT(node->op() == CheckInBounds);
if (UNLIKELY(Options::validateBoundsCheckElimination()))
m_insertionSet.insertNode(nodeIndex, SpecNone, AssertInBounds, node->origin, node->child1(), node->child2());
- node->convertToIdentityOn(m_map[data.m_key].m_dependency);
+ node->convertToIdentityOn(m_map.get(data.m_key).m_dependency);
m_changed = true;
break;
@@ -378,7 +384,7 @@
nodeIndex, origin, jsNumber(addend), source.useKind()));
}
- using RangeMap = StdUnorderedMap<RangeKey, Range, HashMethod<RangeKey>>;
+ using RangeMap = HashMap<GenericHashKey<RangeKey, RangeKey::Hash>, Range>;
RangeMap m_map;
InsertionSet m_insertionSet;
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (288806 => 288807)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2022-01-31 08:48:47 UTC (rev 288807)
@@ -531,17 +531,11 @@
{
double value = node->asNumber();
int64_t valueBits = bitwise_cast<int64_t>(value);
- auto it = m_graph.m_doubleConstantsMap.find(valueBits);
- if (it != m_graph.m_doubleConstantsMap.end())
- return it->second;
-
- if (!m_graph.m_doubleConstants)
- m_graph.m_doubleConstants = makeUnique<Bag<double>>();
-
- double* addressInConstantPool = m_graph.m_doubleConstants->add();
- *addressInConstantPool = value;
- m_graph.m_doubleConstantsMap[valueBits] = addressInConstantPool;
- return addressInConstantPool;
+ return m_graph.m_doubleConstantsMap.ensure(valueBits, [&]{
+ double* addressInConstantPool = m_graph.m_doubleConstants.add();
+ *addressInConstantPool = value;
+ return addressInConstantPool;
+ }).iterator->value;
}
#endif
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (288806 => 288807)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2022-01-31 08:48:47 UTC (rev 288807)
@@ -101,8 +101,8 @@
#include "YarrJITRegisters.h"
#include <atomic>
#include <wtf/Box.h>
+#include <wtf/GenericHashKey.h>
#include <wtf/RecursableLambda.h>
-#include <wtf/StdUnorderedSet.h>
#undef RELEASE_ASSERT
#define RELEASE_ASSERT(assertion) do { \
@@ -17846,7 +17846,7 @@
Vector<SwitchCase> cases;
// These may be negative, or zero, or probably other stuff, too. We don't want to mess with HashSet's corner cases and we don't really care about throughput here.
- StdUnorderedSet<int32_t> alreadyHandled;
+ HashSet<GenericHashKey<int32_t>> alreadyHandled;
for (unsigned i = 0; i < data->cases.size(); ++i) {
// FIXME: The fact that we're using the bytecode's switch table means that the
// following DFG IR transformation would be invalid.
@@ -17884,7 +17884,7 @@
DFG_ASSERT(m_graph, m_node, iter != unlinkedTable.m_offsetTable.end());
// Use m_indexInTable instead of m_branchOffset to make Switch table dense.
- if (!alreadyHandled.insert(iter->value.m_indexInTable).second)
+ if (!alreadyHandled.add(iter->value.m_indexInTable).isNewEntry)
continue;
cases.append(SwitchCase(
Modified: trunk/Source/_javascript_Core/runtime/DeferredWorkTimer.cpp (288806 => 288807)
--- trunk/Source/_javascript_Core/runtime/DeferredWorkTimer.cpp 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/runtime/DeferredWorkTimer.cpp 2022-01-31 08:48:47 UTC (rev 288807)
@@ -34,7 +34,7 @@
namespace JSC {
namespace DeferredWorkTimerInternal {
-static const bool verbose = false;
+static constexpr bool verbose = false;
}
inline DeferredWorkTimer::TicketData::TicketData(VM& vm, JSObject* scriptExecutionOwner, Vector<Strong<JSCell>>&& dependencies)
Modified: trunk/Source/_javascript_Core/runtime/FunctionHasExecutedCache.cpp (288806 => 288807)
--- trunk/Source/_javascript_Core/runtime/FunctionHasExecutedCache.cpp 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/runtime/FunctionHasExecutedCache.cpp 2022-01-31 08:48:47 UTC (rev 288807)
@@ -32,16 +32,17 @@
bool FunctionHasExecutedCache::hasExecutedAtOffset(SourceID id, unsigned offset)
{
- if (m_rangeMap.find(id) == m_rangeMap.end())
+ auto iterator = m_rangeMap.find(id);
+ if (iterator == m_rangeMap.end())
return false;
- RangeMap& map = m_rangeMap.find(id)->second;
+ RangeMap& map = iterator->value;
unsigned distance = UINT_MAX;
bool hasExecuted = false;
for (auto& pair : map) {
- const FunctionRange& range = pair.first;
+ const FunctionRange& range = pair.key.key();
if (range.m_start <= offset && offset <= range.m_end && range.m_end - range.m_start < distance) {
- hasExecuted = pair.second;
+ hasExecuted = pair.value;
distance = range.m_end - range.m_start;
}
}
@@ -51,46 +52,41 @@
void FunctionHasExecutedCache::insertUnexecutedRange(SourceID id, unsigned start, unsigned end)
{
- if (m_rangeMap.find(id) == m_rangeMap.end()) {
- RangeMap map;
- m_rangeMap[id] = map;
- }
-
- RangeMap& map = m_rangeMap.find(id)->second;
+ RangeMap& map = m_rangeMap.add(id, RangeMap { }).iterator->value;
FunctionRange range;
range.m_start = start;
range.m_end = end;
// Only insert unexecuted ranges once for a given sourceID because we may run into a situation where an executable executes, then is GCed, and then is allocated again,
// and tries to reinsert itself, claiming it has never run, but this is false because it indeed already executed.
- if (map.find(range) == map.end())
- map[range] = false;
+ map.add(range, false);
}
void FunctionHasExecutedCache::removeUnexecutedRange(SourceID id, unsigned start, unsigned end)
{
// FIXME: We should never have an instance where we return here, but currently do in some situations. Find out why.
- if (m_rangeMap.find(id) == m_rangeMap.end())
+ auto iterator = m_rangeMap.find(id);
+ if (iterator == m_rangeMap.end())
return;
- RangeMap& map = m_rangeMap.find(id)->second;
+ RangeMap& map = iterator->value;
FunctionRange range;
range.m_start = start;
range.m_end = end;
- map[range] = true;
+ map.set(range, true);
}
Vector<std::tuple<bool, unsigned, unsigned>> FunctionHasExecutedCache::getFunctionRanges(SourceID id)
{
Vector<std::tuple<bool, unsigned, unsigned>> ranges(0);
- auto findResult = m_rangeMap.find(id);
- if (findResult == m_rangeMap.end())
+ auto iterator = m_rangeMap.find(id);
+ if (iterator == m_rangeMap.end())
return ranges;
- RangeMap& map = m_rangeMap.find(id)->second;
+ RangeMap& map = iterator->value;
for (auto& pair : map) {
- const FunctionRange& range = pair.first;
- bool hasExecuted = pair.second;
+ const FunctionRange& range = pair.key.key();
+ bool hasExecuted = pair.value;
ranges.append(std::tuple<bool, unsigned, unsigned>(hasExecuted, range.m_start, range.m_end));
}
Modified: trunk/Source/_javascript_Core/runtime/FunctionHasExecutedCache.h (288806 => 288807)
--- trunk/Source/_javascript_Core/runtime/FunctionHasExecutedCache.h 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/runtime/FunctionHasExecutedCache.h 2022-01-31 08:48:47 UTC (rev 288807)
@@ -26,8 +26,7 @@
#pragma once
#include "SourceID.h"
-#include <wtf/HashMethod.h>
-#include <wtf/StdUnorderedMap.h>
+#include <wtf/GenericHashKey.h>
#include <wtf/Vector.h>
namespace JSC {
@@ -35,6 +34,12 @@
class FunctionHasExecutedCache {
public:
struct FunctionRange {
+ struct Hash {
+ static unsigned hash(const FunctionRange& key) { return key.hash(); }
+ static bool equal(const FunctionRange& a, const FunctionRange& b) { return a == b; }
+ static constexpr bool safeToCompareToEmptyOrDeleted = false;
+ };
+
FunctionRange() {}
bool operator==(const FunctionRange& other) const
{
@@ -55,8 +60,8 @@
Vector<std::tuple<bool, unsigned, unsigned>> getFunctionRanges(SourceID);
private:
- using RangeMap = StdUnorderedMap<FunctionRange, bool, HashMethod<FunctionRange>>;
- using SourceIDToRangeMap = StdUnorderedMap<intptr_t, RangeMap>;
+ using RangeMap = HashMap<GenericHashKey<FunctionRange, FunctionRange::Hash>, bool>;
+ using SourceIDToRangeMap = HashMap<GenericHashKey<intptr_t>, RangeMap>;
SourceIDToRangeMap m_rangeMap;
};
Modified: trunk/Source/_javascript_Core/runtime/TypeLocationCache.cpp (288806 => 288807)
--- trunk/Source/_javascript_Core/runtime/TypeLocationCache.cpp 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/runtime/TypeLocationCache.cpp 2022-01-31 08:48:47 UTC (rev 288807)
@@ -41,22 +41,17 @@
key.m_start = start;
key.m_end = end;
- bool isNewLocation = false;
- if (m_locationMap.find(key) == m_locationMap.end()) {
+ auto result = m_locationMap.ensure(key, [&]{
ASSERT(vm->typeProfiler());
- TypeLocation* location = vm->typeProfiler()->nextTypeLocation();
+ auto* location = vm->typeProfiler()->nextTypeLocation();
location->m_globalVariableID = globalVariableID;
location->m_sourceID = sourceID;
location->m_divotStart = start;
location->m_divotEnd = end;
location->m_globalTypeSet = WTFMove(globalTypeSet);
-
- m_locationMap[key] = location;
- isNewLocation = true;
- }
-
- TypeLocation* location = m_locationMap.find(key)->second;
- return std::pair<TypeLocation*, bool>(location, isNewLocation);
+ return location;
+ });
+ return std::pair { result.iterator->value, result.isNewEntry };
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/TypeLocationCache.h (288806 => 288807)
--- trunk/Source/_javascript_Core/runtime/TypeLocationCache.h 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/_javascript_Core/runtime/TypeLocationCache.h 2022-01-31 08:48:47 UTC (rev 288807)
@@ -28,8 +28,7 @@
#include "SourceID.h"
#include "TypeLocation.h"
#include <wtf/FastMalloc.h>
-#include <wtf/HashMethod.h>
-#include <wtf/StdUnorderedMap.h>
+#include <wtf/GenericHashKey.h>
namespace JSC {
@@ -38,6 +37,12 @@
class TypeLocationCache {
public:
struct LocationKey {
+ struct Hash {
+ static unsigned hash(const LocationKey& key) { return key.hash(); }
+ static bool equal(const LocationKey& a, const LocationKey& b) { return a == b; }
+ static constexpr bool safeToCompareToEmptyOrDeleted = false;
+ };
+
LocationKey() {}
bool operator==(const LocationKey& other) const
{
@@ -60,7 +65,7 @@
std::pair<TypeLocation*, bool> getTypeLocation(GlobalVariableID, SourceID, unsigned start, unsigned end, RefPtr<TypeSet>&&, VM*);
private:
- using LocationMap = StdUnorderedMap<LocationKey, TypeLocation*, HashMethod<LocationKey>>;
+ using LocationMap = HashMap<GenericHashKey<LocationKey, LocationKey::Hash>, TypeLocation*>;
LocationMap m_locationMap;
};
Modified: trunk/Source/WTF/ChangeLog (288806 => 288807)
--- trunk/Source/WTF/ChangeLog 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/WTF/ChangeLog 2022-01-31 08:48:47 UTC (rev 288807)
@@ -1,3 +1,21 @@
+2022-01-30 Yusuke Suzuki <[email protected]>
+
+ [WTF] Add GenericHashKey
+ https://bugs.webkit.org/show_bug.cgi?id=235872
+
+ Reviewed by Darin Adler.
+
+ This patch adds GenericHashKey<T>, which can represent any HashTable's key
+ even if Key does not have Empty / Deleted values. Previously we were using
+ StdUnorderedSet / StdUnorderedMap instead. But, (1) they are doing similar
+ thing to GenericHashKey to keep empty or deleted values, and (2) by using
+ GenericHashKey we can consistently use WTF::HashMap etc. for all possible
+ cases.
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/CMakeLists.txt:
+ * wtf/GenericHashKey.h: Added.
+
2022-01-30 Diego Pino Garcia <[email protected]>
[WinCairo] 'fileSystemRepresentation' identifier not found in URL.cpp
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (288806 => 288807)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2022-01-31 08:48:47 UTC (rev 288807)
@@ -800,6 +800,7 @@
E3E158251EADA53C004A079D /* SystemFree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemFree.h; sourceTree = "<group>"; };
E3E64F0B22813428001E55B4 /* Nonmovable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Nonmovable.h; sourceTree = "<group>"; };
E3E8162F2764799300BAA45B /* RefCountedFixedVector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RefCountedFixedVector.h; sourceTree = "<group>"; };
+ E3FD6D6627A1F6AD00935000 /* GenericHashKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GenericHashKey.h; sourceTree = "<group>"; };
E419F2E623AB9E2300B26129 /* VectorHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorHash.h; sourceTree = "<group>"; };
E431CC4A21187ADB000C8A07 /* DispatchSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DispatchSPI.h; sourceTree = "<group>"; };
E4A0AD371A96245500536DF6 /* WorkQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkQueue.cpp; sourceTree = "<group>"; };
@@ -1115,6 +1116,7 @@
1A1D8B9D1731879800141DA4 /* FunctionDispatcher.cpp */,
1A1D8B9B173186CE00141DA4 /* FunctionDispatcher.h */,
53F1D98620477B9800EBC6BF /* FunctionTraits.h */,
+ E3FD6D6627A1F6AD00935000 /* GenericHashKey.h */,
E3831F922703101A00EF5EB3 /* GenericTimeMixin.h */,
A8A472A8151A825A004123FF /* GetPtr.h */,
0F5BF1741F23D49A0029D91D /* Gigacage.cpp */,
@@ -1149,9 +1151,9 @@
E33667492722550900259122 /* Int128.cpp */,
F6D67D3226F90142006E0349 /* Int128.h */,
33FD4811265CB38000ABE4F4 /* InterferenceGraph.h */,
- 5295B00427920C54006D746A /* IterationStatus.h */,
0F7EB85B1FA8FF4100F1ABCB /* IsoMalloc.h */,
0F7EB85C1FA8FF4200F1ABCB /* IsoMallocInlines.h */,
+ 5295B00427920C54006D746A /* IterationStatus.h */,
7CDD7FF7186D291E007433CD /* IteratorAdaptors.h */,
7CDD7FF9186D2A54007433CD /* IteratorRange.h */,
7A05093E1FB9DCC500B33FB8 /* JSONValues.cpp */,
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (288806 => 288807)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2022-01-31 08:48:47 UTC (rev 288807)
@@ -81,6 +81,7 @@
Function.h
FunctionDispatcher.h
FunctionTraits.h
+ GenericHashKey.h
GenericTimeMixin.h
GetPtr.h
Gigacage.h
Added: trunk/Source/WTF/wtf/GenericHashKey.h (0 => 288807)
--- trunk/Source/WTF/wtf/GenericHashKey.h (rev 0)
+++ trunk/Source/WTF/wtf/GenericHashKey.h 2022-01-31 08:48:47 UTC (rev 288807)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <variant>
+#include <wtf/Forward.h>
+
+namespace WTF {
+
+template<typename Key, typename HashArg = DefaultHash<Key>>
+class GenericHashKey final {
+ WTF_MAKE_FAST_ALLOCATED;
+
+ struct EmptyKey { };
+ struct DeletedKey { };
+
+public:
+ constexpr GenericHashKey(Key&& key)
+ : m_value(std::in_place_type_t<Key>(), WTFMove(key))
+ {
+ }
+
+ template<typename K>
+ constexpr GenericHashKey(K&& key)
+ : m_value(std::in_place_type_t<Key>(), std::forward<K>(key))
+ {
+ }
+
+ constexpr GenericHashKey(HashTableEmptyValueType)
+ : m_value(EmptyKey { })
+ {
+ }
+
+ constexpr GenericHashKey(HashTableDeletedValueType)
+ : m_value(DeletedKey { })
+ {
+ }
+
+ constexpr const Key& key() const { return std::get<Key>(m_value); }
+ constexpr unsigned hash() const
+ {
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(!isHashTableDeletedValue() && !isHashTableEmptyValue());
+ return HashArg::hash(key());
+ }
+
+ constexpr bool isHashTableDeletedValue() const { return std::holds_alternative<DeletedKey>(m_value); }
+ constexpr bool isHashTableEmptyValue() const { return std::holds_alternative<EmptyKey>(m_value); }
+
+ constexpr bool operator==(const GenericHashKey& other) const
+ {
+ if (m_value.index() != other.m_value.index())
+ return false;
+ if (!std::holds_alternative<Key>(m_value))
+ return true;
+ return HashArg::equal(key(), other.key());
+ }
+
+ constexpr bool operator!=(const GenericHashKey& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ std::variant<Key, EmptyKey, DeletedKey> m_value;
+};
+
+template<typename K, typename H> struct HashTraits<GenericHashKey<K, H>> : GenericHashTraits<GenericHashKey<K, H>> {
+ static GenericHashKey<K, H> emptyValue() { return GenericHashKey<K, H> { HashTableEmptyValue }; }
+ static void constructDeletedValue(GenericHashKey<K, H>& slot) { slot = GenericHashKey<K, H> { HashTableDeletedValue }; }
+ static bool isDeletedValue(const GenericHashKey<K, H>& value) { return value.isHashTableDeletedValue(); }
+};
+
+template<typename K, typename H> struct DefaultHash<GenericHashKey<K, H>> {
+ static unsigned hash(const GenericHashKey<K, H>& key) { return key.hash(); }
+ static bool equal(const GenericHashKey<K, H>& a, const GenericHashKey<K, H>& b) { return a == b; }
+ static constexpr bool safeToCompareToEmptyOrDeleted = false;
+};
+
+}
+
+using WTF::GenericHashKey;
Modified: trunk/Source/WebCore/ChangeLog (288806 => 288807)
--- trunk/Source/WebCore/ChangeLog 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/WebCore/ChangeLog 2022-01-31 08:48:47 UTC (rev 288807)
@@ -1,3 +1,15 @@
+2022-01-30 Yusuke Suzuki <[email protected]>
+
+ [WTF] Add GenericHashKey
+ https://bugs.webkit.org/show_bug.cgi?id=235872
+
+ Reviewed by Darin Adler.
+
+ No behavior change. We should use StdMap.
+ This should be StdMap since it requires ordered iterations by the key, so it should not be a HashMap.
+
+ * platform/graphics/avfoundation/objc/QueuedVideoOutput.h:
+
2022-01-30 Ryosuke Niwa <[email protected]>
Delete code for keygen element
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/QueuedVideoOutput.h (288806 => 288807)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/QueuedVideoOutput.h 2022-01-31 05:47:29 UTC (rev 288806)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/QueuedVideoOutput.h 2022-01-31 08:48:47 UTC (rev 288807)
@@ -33,6 +33,7 @@
#include <wtf/Observer.h>
#include <wtf/RefCounted.h>
#include <wtf/RetainPtr.h>
+#include <wtf/StdMap.h>
#include <wtf/WeakHashSet.h>
OBJC_CLASS AVPlayer;
@@ -67,7 +68,7 @@
using CurrentImageChangedObserver = Observer<void()>;
void addCurrentImageChangedObserver(const CurrentImageChangedObserver&);
- using ImageMap = std::map<MediaTime, RetainPtr<CVPixelBufferRef>>;
+ using ImageMap = StdMap<MediaTime, RetainPtr<CVPixelBufferRef>>;
void rateChanged(float);