Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (291934 => 291935)
--- trunk/Source/_javascript_Core/ChangeLog 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-03-26 11:38:22 UTC (rev 291935)
@@ -1,3 +1,50 @@
+2022-03-26 Yusuke Suzuki <[email protected]>
+
+ [JSC] Include argumentRegisters in identity of SlowPathCallKey when clobberAllRegsInFTLICSlowPath is enabled
+ https://bugs.webkit.org/show_bug.cgi?id=238411
+
+ Reviewed by Mark Lam.
+
+ While SlowPathCallKey includes argumentRegisters, it is not used for its identity check. But this argumentRegisters
+ is effectual on the resulting code in FTLThunks if Options::clobberAllRegsInFTLICSlowPath is set. This causes
+ x64 Debug JSC test failures after enabling DataIC because the same FTLThunks should not be picked for different
+ argument registers when Options::clobberAllRegsInFTLICSlowPath is true.
+
+ However, always including argumentRegisters in the identity check will cause a code size regression since we will
+ lose a chance to duplicate thunks when argumentRegisters is ineffectual. Note that Options::clobberAllRegsInFTLICSlowPath
+ is only set for debugging use cases. Hence, argumentRegisters is normally not effectual.
+
+ In this patch, we include argumentRegisters in SlowPathCallKey's identity check only when Options::clobberAllRegsInFTLICSlowPath
+ is set. And we also refactor SlowPathCallKey to reduce size of it from 40 to 24.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * assembler/MacroAssemblerCodeRef.h:
+ (JSC::CFunctionPtr::CFunctionPtr):
+ (JSC::FunctionPtr::FunctionPtr):
+ * ftl/FTLSlowPathCall.cpp:
+ (JSC::FTL::SlowPathCallContext::keyWithTarget const):
+ * ftl/FTLSlowPathCallKey.cpp:
+ (JSC::FTL::SlowPathCallKey::dump const):
+ * ftl/FTLSlowPathCallKey.h:
+ (JSC::FTL::SlowPathCallKey::SlowPathCallKey):
+ (JSC::FTL::SlowPathCallKey::callTarget const):
+ (JSC::FTL::SlowPathCallKey::usedRegisters const):
+ (JSC::FTL::SlowPathCallKey::argumentRegistersIfClobberingCheckIsEnabled const):
+ (JSC::FTL::SlowPathCallKey::indirectOffset const):
+ (JSC::FTL::SlowPathCallKey::withCallTarget):
+ (JSC::FTL::SlowPathCallKey::isEmptyValue const):
+ (JSC::FTL::SlowPathCallKey::isDeletedValue const):
+ (JSC::FTL::SlowPathCallKey::operator== const):
+ (JSC::FTL::SlowPathCallKey::hash const):
+ (JSC::FTL::SlowPathCallKey::argumentRegisters const): Deleted.
+ * ftl/FTLThunks.cpp:
+ (JSC::FTL::registerClobberCheck):
+ (JSC::FTL::slowPathCallThunkGenerator):
+ * jit/HashableRegisterSet.h: Removed.
+ * jit/RegisterSet.h:
+ (JSC::RegisterSetHash::hash):
+ (JSC::RegisterSetHash::equal):
+
2022-03-25 Yusuke Suzuki <[email protected]>
[JSC] Clean up DataIC polymorphic call code for OptimizingCallLinkInfo
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (291934 => 291935)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2022-03-26 11:38:22 UTC (rev 291935)
@@ -517,7 +517,6 @@
0FB4FB751BC843140025CA5A /* FTLLazySlowPathCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4FB721BC843140025CA5A /* FTLLazySlowPathCall.h */; };
0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0FB57069267A642E0080FA8B /* HashableRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB57068267A642E0080FA8B /* HashableRegisterSet.h */; };
0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB7F39615ED8E4600F167B2 /* ArrayStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3161,7 +3160,6 @@
0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyOperandValueProfile.cpp; sourceTree = "<group>"; };
0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodOfGettingAValueProfile.h; sourceTree = "<group>"; };
0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MethodOfGettingAValueProfile.cpp; sourceTree = "<group>"; };
- 0FB57068267A642E0080FA8B /* HashableRegisterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashableRegisterSet.h; sourceTree = "<group>"; };
0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayConventions.h; sourceTree = "<group>"; };
0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayStorage.h; sourceTree = "<group>"; };
0FB7F38B15ED8E3800F167B2 /* Butterfly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Butterfly.h; sourceTree = "<group>"; };
@@ -6571,7 +6569,6 @@
0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */,
0F93274C1C1F66AA00CF6564 /* GPRInfo.cpp */,
0F24E53F17EA9F5900ABB217 /* GPRInfo.h */,
- 0FB57068267A642E0080FA8B /* HashableRegisterSet.h */,
DC2143051CA32E52000A8869 /* ICStats.cpp */,
DC2143061CA32E52000A8869 /* ICStats.h */,
DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */,
@@ -10429,7 +10426,6 @@
0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
142E3136134FF0A600AFADB5 /* HandleSet.h in Headers */,
1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */,
- 0FB57069267A642E0080FA8B /* HashableRegisterSet.h in Headers */,
79A090801D768465008B889B /* HashMapImpl.h in Headers */,
FEF5B4232628A0EE0016E776 /* HashMapImplInlines.h in Headers */,
79DFCBDB1D88C59600527D03 /* HasOwnPropertyCache.h in Headers */,
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.h (291934 => 291935)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.h 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.h 2022-03-26 11:38:22 UTC (rev 291935)
@@ -68,8 +68,8 @@
public:
using Ptr = void(*)();
- CFunctionPtr() { }
- CFunctionPtr(std::nullptr_t) { }
+ constexpr CFunctionPtr() = default;
+ constexpr CFunctionPtr(std::nullptr_t) { }
template<typename ReturnType, typename... Arguments>
constexpr CFunctionPtr(ReturnType(&ptr)(Arguments...))
@@ -135,8 +135,8 @@
template<PtrTag tag = CFunctionPtrTag>
class FunctionPtr {
public:
- FunctionPtr() { }
- FunctionPtr(std::nullptr_t) { }
+ constexpr FunctionPtr() = default;
+ constexpr FunctionPtr(std::nullptr_t) { }
template<typename ReturnType, typename... Arguments>
FunctionPtr(ReturnType(*value)(Arguments...))
Modified: trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.cpp (291934 => 291935)
--- trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.cpp 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.cpp 2022-03-26 11:38:22 UTC (rev 291935)
@@ -116,12 +116,18 @@
SlowPathCallKey SlowPathCallContext::keyWithTarget(FunctionPtr<CFunctionPtrTag> callTarget) const
{
- return SlowPathCallKey(m_thunkSaveSet, callTarget, m_argumentRegisters, m_offset, 0);
+ uint8_t numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled = 0;
+ if (UNLIKELY(Options::clobberAllRegsInFTLICSlowPath()))
+ numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled = std::min(NUMBER_OF_ARGUMENT_REGISTERS, m_numArgs);
+ return SlowPathCallKey(m_thunkSaveSet, callTarget, numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled, m_offset, 0);
}
SlowPathCallKey SlowPathCallContext::keyWithTarget(CCallHelpers::Address address) const
{
- return SlowPathCallKey(m_thunkSaveSet, nullptr, m_argumentRegisters, m_offset, address.offset);
+ uint8_t numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled = 0;
+ if (UNLIKELY(Options::clobberAllRegsInFTLICSlowPath()))
+ numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled = std::min(NUMBER_OF_ARGUMENT_REGISTERS, m_numArgs);
+ return SlowPathCallKey(m_thunkSaveSet, nullptr, numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled, m_offset, address.offset);
}
SlowPathCall SlowPathCallContext::makeCall(VM& vm, FunctionPtr<CFunctionPtrTag> callTarget)
Modified: trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.h (291934 => 291935)
--- trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.h 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.h 2022-03-26 11:38:22 UTC (rev 291935)
@@ -74,7 +74,7 @@
size_t m_offsetToSavingArea;
size_t m_stackBytesNeeded;
RegisterSet m_thunkSaveSet;
- ptrdiff_t m_offset;
+ size_t m_offset;
};
template<typename... ArgumentTypes>
Modified: trunk/Source/_javascript_Core/ftl/FTLSlowPathCallKey.cpp (291934 => 291935)
--- trunk/Source/_javascript_Core/ftl/FTLSlowPathCallKey.cpp 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/ftl/FTLSlowPathCallKey.cpp 2022-03-26 11:38:22 UTC (rev 291935)
@@ -32,7 +32,10 @@
void SlowPathCallKey::dump(PrintStream& out) const
{
- out.print("<usedRegisters = ", m_usedRegisters, ", offset = ", m_offset, ", indirectOffset = ", m_indirectOffset, ", callTarget = ", RawPointer(m_callTarget.executableAddress()), ", argumentRegisters = ", m_argumentRegisters, ">");
+ out.print("<usedRegisters = ", m_usedRegisters, ", offset = ", m_offset, ", indirectOffset = ", m_indirectOffset, ", callTarget = ", RawPointer(m_callTarget.executableAddress()));
+ if (Options::clobberAllRegsInFTLICSlowPath())
+ out.print(", argumentRegisters = ", argumentRegistersIfClobberingCheckIsEnabled());
+ out.print(">");
}
} } // namespace JSC::FTL
Modified: trunk/Source/_javascript_Core/ftl/FTLSlowPathCallKey.h (291934 => 291935)
--- trunk/Source/_javascript_Core/ftl/FTLSlowPathCallKey.h 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/ftl/FTLSlowPathCallKey.h 2022-03-26 11:38:22 UTC (rev 291935)
@@ -27,8 +27,8 @@
#if ENABLE(FTL_JIT)
-#include "HashableRegisterSet.h"
#include "MacroAssemblerCodeRef.h"
+#include "RegisterSet.h"
namespace JSC { namespace FTL {
@@ -44,31 +44,62 @@
class SlowPathCallKey {
public:
- SlowPathCallKey()
- : m_offset(0)
+ // Keep it within 2 bits.
+ enum class Type : uint8_t {
+ // For HashTables.
+ Empty,
+ Deleted,
+
+ Direct,
+ Indirect,
+ };
+
+ SlowPathCallKey() = default;
+
+ SlowPathCallKey(const RegisterSet& set, FunctionPtr<CFunctionPtrTag> callTarget, uint8_t numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled, size_t offset, int32_t indirectOffset)
+ : m_numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled(numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled)
+ , m_offset(offset)
+ , m_usedRegisters(set)
{
+ if (callTarget) {
+ m_type = static_cast<unsigned>(Type::Direct);
+ ASSERT(Type::Direct == this->type());
+ m_callTarget = callTarget.retagged<OperationPtrTag>();
+ ASSERT(!indirectOffset);
+ } else {
+ m_type = static_cast<unsigned>(Type::Indirect);
+ ASSERT(Type::Indirect == this->type());
+ m_indirectOffset = indirectOffset;
+ }
+ ASSERT(offset == m_offset);
}
- SlowPathCallKey(
- const RegisterSet& set, FunctionPtr<CFunctionPtrTag> callTarget, const RegisterSet& argumentRegisters,
- ptrdiff_t offset, int32_t indirectOffset)
- : m_usedRegisters(set)
- , m_callTarget(callTarget.retagged<OperationPtrTag>())
- , m_argumentRegisters(argumentRegisters)
- , m_offset(offset)
- , m_indirectOffset(indirectOffset)
+ FunctionPtr<OperationPtrTag> callTarget() const
{
+ if (type() == Type::Direct)
+ return m_callTarget;
+ return nullptr;
}
-
+ size_t offset() const { return m_offset; }
const RegisterSet& usedRegisters() const { return m_usedRegisters; }
- FunctionPtr<OperationPtrTag> callTarget() const { return m_callTarget; }
- const RegisterSet& argumentRegisters() const { return m_argumentRegisters; }
- ptrdiff_t offset() const { return m_offset; }
- int32_t indirectOffset() const { return m_indirectOffset; }
+ RegisterSet argumentRegistersIfClobberingCheckIsEnabled() const
+ {
+ RELEASE_ASSERT(Options::clobberAllRegsInFTLICSlowPath());
+ RegisterSet argumentRegisters;
+ for (uint8_t i = 0; i < numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled(); ++i)
+ argumentRegisters.set(GPRInfo::toArgumentRegister(i));
+ return argumentRegisters;
+ }
+ int32_t indirectOffset() const
+ {
+ if (type() == Type::Indirect)
+ return m_indirectOffset;
+ return 0;
+ }
SlowPathCallKey withCallTarget(FunctionPtr<CFunctionPtrTag> callTarget)
{
- return SlowPathCallKey(usedRegisters(), callTarget, argumentRegisters(), offset(), indirectOffset());
+ return SlowPathCallKey(usedRegisters(), callTarget, numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled(), offset(), indirectOffset());
}
void dump(PrintStream&) const;
@@ -77,38 +108,53 @@
enum DeletedValueTag { DeletedValue };
SlowPathCallKey(EmptyValueTag)
- : m_usedRegisters(HashableRegisterSet::EmptyValue)
+ : m_type(static_cast<unsigned>(Type::Empty))
{
+ ASSERT(Type::Empty == this->type());
}
SlowPathCallKey(DeletedValueTag)
- : m_usedRegisters(HashableRegisterSet::DeletedValue)
+ : m_type(static_cast<unsigned>(Type::Deleted))
{
+ ASSERT(Type::Deleted == this->type());
}
- bool isEmptyValue() const { return m_usedRegisters.isEmptyValue(); }
- bool isDeletedValue() const { return m_usedRegisters.isDeletedValue(); }
+ bool isEmptyValue() const { return type() == Type::Empty; }
+ bool isDeletedValue() const { return type() == Type::Deleted; }
bool operator==(const SlowPathCallKey& other) const
{
- return m_usedRegisters == other.m_usedRegisters
- && m_callTarget == other.m_callTarget
- && m_offset == other.m_offset
- && m_indirectOffset == other.m_indirectOffset;
+ return m_offset == other.m_offset
+ && m_usedRegisters == other.m_usedRegisters
+ && numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled() == other.numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled()
+ && type() == other.type()
+ && callTarget() == other.callTarget()
+ && indirectOffset() == other.indirectOffset();
}
unsigned hash() const
{
- return m_usedRegisters.hash() + PtrHash<void*>::hash(m_callTarget.executableAddress()) + m_offset + m_indirectOffset;
+ // m_numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled is intentionally not included because it will always be 0
+ // unless Options::clobberAllRegsInFTLICSlowPath() is set, and Options::clobberAllRegsInFTLICSlowPath() is only set in debugging use cases.
+ return PtrHash<void*>::hash(callTarget().executableAddress()) + m_offset + m_usedRegisters.hash() + indirectOffset() + static_cast<unsigned>(type());
}
private:
- HashableRegisterSet m_usedRegisters;
- FunctionPtr<OperationPtrTag> m_callTarget;
- RegisterSet m_argumentRegisters;
- ptrdiff_t m_offset { 0 };
- int32_t m_indirectOffset { 0 };
+ static_assert(NUMBER_OF_ARGUMENT_REGISTERS <= std::numeric_limits<uint8_t>::max());
+
+ uint8_t numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled() const { return m_numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled; }
+ Type type() const { return static_cast<Type>(m_type); }
+
+ union {
+ FunctionPtr<OperationPtrTag> m_callTarget { };
+ int32_t m_indirectOffset;
+ };
+ size_t m_numberOfUsedArgumentRegistersIfClobberingCheckIsEnabled : 8 { 0 };
+ size_t m_type : 2 { static_cast<size_t>(Type::Empty) };
+ size_t m_offset : 54 { 0 };
+ RegisterSet m_usedRegisters;
};
+
struct SlowPathCallKeyHash {
static unsigned hash(const SlowPathCallKey& key) { return key.hash(); }
static bool equal(const SlowPathCallKey& a, const SlowPathCallKey& b) { return a == b; }
Modified: trunk/Source/_javascript_Core/ftl/FTLThunks.cpp (291934 => 291935)
--- trunk/Source/_javascript_Core/ftl/FTLThunks.cpp 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/ftl/FTLThunks.cpp 2022-03-26 11:38:22 UTC (rev 291935)
@@ -139,9 +139,7 @@
static void registerClobberCheck(AssemblyHelpers& jit, RegisterSet dontClobber)
{
- if (!Options::clobberAllRegsInFTLICSlowPath())
- return;
-
+ ASSERT(Options::clobberAllRegsInFTLICSlowPath());
RegisterSet clobber = RegisterSet::allRegisters();
clobber.exclude(RegisterSet::reservedHardwareRegisters());
clobber.exclude(RegisterSet::stackRegisters());
@@ -202,10 +200,12 @@
jit.storePtr(GPRInfo::nonArgGPR1, AssemblyHelpers::Address(MacroAssembler::stackPointerRegister, key.offset()));
jit.prepareCallOperation(vm);
- RegisterSet dontClobber = key.argumentRegisters();
- if (!key.callTarget())
- dontClobber.set(GPRInfo::nonArgGPR0);
- registerClobberCheck(jit, WTFMove(dontClobber));
+ if (UNLIKELY(Options::clobberAllRegsInFTLICSlowPath())) {
+ RegisterSet dontClobber = key.argumentRegistersIfClobberingCheckIsEnabled();
+ if (!key.callTarget())
+ dontClobber.set(GPRInfo::nonArgGPR0);
+ registerClobberCheck(jit, WTFMove(dontClobber));
+ }
AssemblyHelpers::Call call;
if (key.callTarget())
Deleted: trunk/Source/_javascript_Core/jit/HashableRegisterSet.h (291934 => 291935)
--- trunk/Source/_javascript_Core/jit/HashableRegisterSet.h 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/jit/HashableRegisterSet.h 2022-03-26 11:38:22 UTC (rev 291935)
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2021 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
-
-#if !ENABLE(C_LOOP)
-
-#include "RegisterSet.h"
-
-namespace JSC {
-
-class HashableRegisterSet : public RegisterSet {
- enum State {
- Normal,
- Empty,
- Deleted
- };
-
-public:
- constexpr HashableRegisterSet() { }
-
- template<typename... Regs>
- constexpr explicit HashableRegisterSet(Regs... regs)
- : RegisterSet(regs...)
- {
- }
-
- enum EmptyValueTag { EmptyValue };
- enum DeletedValueTag { DeletedValue };
-
- HashableRegisterSet(EmptyValueTag)
- : m_state(Empty)
- {
- }
-
- HashableRegisterSet(DeletedValueTag)
- : m_state(Deleted)
- {
- }
-
- bool isEmptyValue() const
- {
- return m_state == Empty;
- }
-
- bool isDeletedValue() const
- {
- return m_state == Deleted;
- }
-
-private:
- State m_state { Normal };
-};
-
-struct RegisterSetHash {
- static unsigned hash(const HashableRegisterSet& set) { return set.hash(); }
- static bool equal(const HashableRegisterSet& a, const HashableRegisterSet& b) { return a == b; }
- static constexpr bool safeToCompareToEmptyOrDeleted = false;
-};
-
-} // namespace JSC
-
-namespace WTF {
-
-template<typename T> struct DefaultHash;
-template<> struct DefaultHash<JSC::HashableRegisterSet> : JSC::RegisterSetHash { };
-
-template<typename T> struct HashTraits;
-template<> struct HashTraits<JSC::HashableRegisterSet> : public CustomHashTraits<JSC::HashableRegisterSet> { };
-
-} // namespace WTF
-
-#endif // !ENABLE(C_LOOP)
-
Modified: trunk/Source/_javascript_Core/jit/RegisterSet.h (291934 => 291935)
--- trunk/Source/_javascript_Core/jit/RegisterSet.h 2022-03-26 09:17:21 UTC (rev 291934)
+++ trunk/Source/_javascript_Core/jit/RegisterSet.h 2022-03-26 11:38:22 UTC (rev 291935)
@@ -202,6 +202,19 @@
RegisterBitmap m_bits;
};
+struct RegisterSetHash {
+ static unsigned hash(const RegisterSet& set) { return set.hash(); }
+ static bool equal(const RegisterSet& a, const RegisterSet& b) { return a == b; }
+ static constexpr bool safeToCompareToEmptyOrDeleted = false;
+};
+
} // namespace JSC
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::RegisterSet> : JSC::RegisterSetHash { };
+
+} // namespace WTF
+
#endif // !ENABLE(C_LOOP)