Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (275839 => 275840)
--- trunk/Source/_javascript_Core/ChangeLog 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-04-12 22:01:09 UTC (rev 275840)
@@ -1,3 +1,85 @@
+2021-04-11 Yusuke Suzuki <[email protected]>
+
+ [JSC] Do not copy StringSwitchJumpTable
+ https://bugs.webkit.org/show_bug.cgi?id=224414
+
+ Reviewed by Keith Miller.
+
+ Previously, we were copying UnlinkedStringJumpTable to CodeBlock's StringJumpTable because we embed CodeLocation pointer
+ inside CodeBlock's StringJumpTable. This is copying a mostly identical hashtable to each CodeBlock even in DFG and FTL. This
+ even prevents us from inlining op_switch_string in DFG and FTL because (1) we don't want to copy this string tables collected from
+ each inlined CodeBlock into a new DFG / FTL CodeBlock and (2) we cannot ref/deref StringImpl inside DFG / FTL compilers so copying
+ these tables in the compiler threads need additional "DesiredStringSwitchJumpTable" etc.
+
+ In this patch, we stop copying StringSwitchJumpTable. We decouple CodeLocation pointers from the hashtable so that we can use
+ UnlinkedStringJumpTable in UnlinkedCodeBlock. UnlinkedStringJumpTable's hashtable inclues m_indexInTable in each entry so that
+ we can have array of CodeLocation pointers in CodeBlock's JITData to have JIT jump targets separately. This design prevents us
+ from copying unnecessary hashtables, and even this paves the way to inlining switch_string in DFG and FTL.
+
+ * bytecode/BytecodeDumper.cpp:
+ (JSC::CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finishCreation):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::stringSwitchJumpTable):
+ (JSC::CodeBlock::numberOfUnlinkedStringSwitchJumpTables const):
+ (JSC::CodeBlock::unlinkedStringSwitchJumpTable):
+ (JSC::CodeBlock::numberOfStringSwitchJumpTables const): Deleted.
+ * bytecode/JumpTable.h:
+ (JSC::StringJumpTable::ctiForValue const):
+ (JSC::StringJumpTable::offsetForValue): Deleted.
+ (JSC::StringJumpTable::ctiForValue): Deleted.
+ (JSC::StringJumpTable::clear): Deleted.
+ * bytecode/PreciseJumpTargetsInlines.h:
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedStringJumpTable::offsetForValue const):
+ (JSC::UnlinkedCodeBlock::numberOfUnlinkedStringSwitchJumpTables const):
+ (JSC::UnlinkedCodeBlock::unlinkedStringSwitchJumpTable):
+ (JSC::UnlinkedStringJumpTable::offsetForValue): Deleted.
+ (JSC::UnlinkedCodeBlock::numberOfStringSwitchJumpTables const): Deleted.
+ (JSC::UnlinkedCodeBlock::stringSwitchJumpTable): Deleted.
+ * bytecode/UnlinkedCodeBlockGenerator.cpp:
+ (JSC::UnlinkedCodeBlockGenerator::finalize):
+ * bytecode/UnlinkedCodeBlockGenerator.h:
+ (JSC::UnlinkedCodeBlockGenerator::numberOfUnlinkedStringSwitchJumpTables const):
+ (JSC::UnlinkedCodeBlockGenerator::addUnlinkedStringSwitchJumpTable):
+ (JSC::UnlinkedCodeBlockGenerator::unlinkedStringSwitchJumpTable):
+ (JSC::UnlinkedCodeBlockGenerator::numberOfStringSwitchJumpTables const): Deleted.
+ (JSC::UnlinkedCodeBlockGenerator::addStringSwitchJumpTable): Deleted.
+ (JSC::UnlinkedCodeBlockGenerator::stringSwitchJumpTable): Deleted.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::beginSwitch):
+ (JSC::prepareJumpTableForStringSwitch):
+ (JSC::BytecodeGenerator::endSwitch):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::link):
+ * dfg/DFGOperations.cpp:
+ (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::switchStringSlow):
+ * ftl/FTLOperations.cpp:
+ (JSC::FTL::JSC_DEFINE_JIT_OPERATION):
+ * jit/JIT.cpp:
+ (JSC::JIT::link):
+ * jit/JIT.h:
+ (JSC::SwitchRecord::SwitchRecord):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_switch_string):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_switch_string):
+ * jit/JITOperations.cpp:
+ (JSC::JSC_DEFINE_JIT_OPERATION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/CachedTypes.cpp:
+ (JSC::CachedStringJumpTable::encode):
+ (JSC::CachedStringJumpTable::decode const):
+ (JSC::CachedCodeBlockRareData::encode):
+ (JSC::CachedCodeBlockRareData::decode const):
+
2021-04-10 Yusuke Suzuki <[email protected]>
[JSC] B3 reduce-double-to-float should reduce only when constant double is canonical one to reduced float value
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -196,15 +196,13 @@
template<class Block>
void CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables()
{
- if (unsigned count = this->block()->numberOfStringSwitchJumpTables()) {
+ if (unsigned count = this->block()->numberOfUnlinkedStringSwitchJumpTables()) {
this->m_out.printf("\nString Switch Jump Tables:\n");
unsigned i = 0;
do {
this->m_out.printf(" %1d = {\n", i);
- const auto& stringSwitchJumpTable = this->block()->stringSwitchJumpTable(i);
- auto end = stringSwitchJumpTable.offsetTable.end();
- for (auto iter = stringSwitchJumpTable.offsetTable.begin(); iter != end; ++iter)
- this->m_out.printf("\t\t\"%s\" => %04d\n", iter->key->utf8().data(), iter->value.branchOffset);
+ for (const auto& entry : this->block()->unlinkedStringSwitchJumpTable(i).m_offsetTable)
+ this->m_out.printf("\t\t\"%s\" => %04d\n", entry.key->utf8().data(), entry.value.m_branchOffset);
this->m_out.printf(" }\n");
++i;
} while (i < count);
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -327,7 +327,6 @@
m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers;
m_rareData->m_switchJumpTables = other.m_rareData->m_switchJumpTables;
- m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
}
}
@@ -419,7 +418,7 @@
m_functionExprs[i].set(vm, this, unlinkedExecutable->link(vm, topLevelExecutable, ownerExecutable->source(), WTF::nullopt, NoIntrinsic, ownerExecutable->isInsideOrdinaryFunction()));
}
- if (unlinkedCodeBlock->hasRareData()) {
+ if (unlinkedCodeBlock->numberOfExceptionHandlers() || unlinkedCodeBlock->numberOfSwitchJumpTables()) {
createRareDataIfNecessary();
if (size_t count = unlinkedCodeBlock->numberOfExceptionHandlers()) {
@@ -436,19 +435,6 @@
}
}
- if (size_t count = unlinkedCodeBlock->numberOfStringSwitchJumpTables()) {
- m_rareData->m_stringSwitchJumpTables.resizeToFit(count);
- for (size_t i = 0; i < count; i++) {
- UnlinkedStringJumpTable::StringOffsetTable::iterator ptr = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.begin();
- UnlinkedStringJumpTable::StringOffsetTable::iterator end = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.end();
- for (; ptr != end; ++ptr) {
- OffsetLocation offset;
- offset.branchOffset = ptr->value.branchOffset;
- m_rareData->m_stringSwitchJumpTables[i].offsetTable.add(ptr->key, offset);
- }
- }
- }
-
if (size_t count = unlinkedCodeBlock->numberOfSwitchJumpTables()) {
m_rareData->m_switchJumpTables.resizeToFit(count);
for (size_t i = 0; i < count; i++) {
@@ -2141,10 +2127,8 @@
m_constantsSourceCodeRepresentation.shrinkToFit();
if (shrinkMode == ShrinkMode::EarlyShrink) {
- if (m_rareData) {
+ if (m_rareData)
m_rareData->m_switchJumpTables.shrinkToFit();
- m_rareData->m_stringSwitchJumpTables.shrinkToFit();
- }
} // else don't shrink these, because we would have already pointed pointers into these tables.
}
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2021-04-12 22:01:09 UTC (rev 275840)
@@ -278,6 +278,7 @@
SentinelLinkedList<CallLinkInfo, PackedRawSentinelNode<CallLinkInfo>> m_incomingCalls;
SentinelLinkedList<PolymorphicCallNode, PackedRawSentinelNode<PolymorphicCallNode>> m_incomingPolymorphicCalls;
FixedVector<RareCaseProfile> m_rareCaseProfiles;
+ FixedVector<StringJumpTable> m_stringSwitchJumpTables;
std::unique_ptr<PCToCodeOriginMap> m_pcToCodeOriginMap;
std::unique_ptr<RegisterAtOffsetList> m_calleeSaveRegisters;
JITCodeMap m_jitCodeMap;
@@ -630,8 +631,15 @@
}
#endif
- size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
- StringJumpTable& stringSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
+#if ENABLE(JIT)
+ StringJumpTable& stringSwitchJumpTable(int tableIndex)
+ {
+ RELEASE_ASSERT(m_jitData);
+ return m_jitData->m_stringSwitchJumpTables[tableIndex];
+ }
+#endif
+ size_t numberOfUnlinkedStringSwitchJumpTables() const { return m_unlinkedCode->numberOfUnlinkedStringSwitchJumpTables(); }
+ const UnlinkedStringJumpTable& unlinkedStringSwitchJumpTable(int tableIndex) { return m_unlinkedCode->unlinkedStringSwitchJumpTable(tableIndex); }
DirectEvalCodeCache& directEvalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_directEvalCodeCache; }
@@ -883,7 +891,6 @@
// Jump Tables
Vector<SimpleJumpTable> m_switchJumpTables;
- Vector<StringJumpTable> m_stringSwitchJumpTables;
Vector<std::unique_ptr<ValueProfileAndVirtualRegisterBuffer>> m_catchProfiles;
Modified: trunk/Source/_javascript_Core/bytecode/JumpTable.h (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/JumpTable.h 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/JumpTable.h 2021-04-12 22:01:09 UTC (rev 275840)
@@ -30,6 +30,7 @@
#pragma once
#include "CodeLocation.h"
+#include "UnlinkedCodeBlock.h"
#include <wtf/RobinHoodHashMap.h>
#include <wtf/Vector.h>
#include <wtf/text/StringImpl.h>
@@ -36,45 +37,20 @@
namespace JSC {
- struct OffsetLocation {
- int32_t branchOffset;
#if ENABLE(JIT)
- CodeLocationLabel<JSSwitchPtrTag> ctiOffset;
-#endif
- };
-
struct StringJumpTable {
- using StringOffsetTable = MemoryCompactLookupOnlyRobinHoodHashMap<RefPtr<StringImpl>, OffsetLocation>;
- StringOffsetTable offsetTable;
-#if ENABLE(JIT)
- CodeLocationLabel<JSSwitchPtrTag> ctiDefault; // FIXME: it should not be necessary to store this.
-#endif
+ FixedVector<CodeLocationLabel<JSSwitchPtrTag>> m_ctiOffsets;
+ CodeLocationLabel<JSSwitchPtrTag> m_ctiDefault; // FIXME: it should not be necessary to store this.
- inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
+ inline CodeLocationLabel<JSSwitchPtrTag> ctiForValue(const UnlinkedStringJumpTable& unlinkedTable, StringImpl* value) const
{
- StringOffsetTable::const_iterator end = offsetTable.end();
- StringOffsetTable::const_iterator loc = offsetTable.find(value);
- if (loc == end)
- return defaultOffset;
- return loc->value.branchOffset;
+ auto loc = unlinkedTable.m_offsetTable.find(value);
+ if (loc == unlinkedTable.m_offsetTable.end())
+ return m_ctiDefault;
+ return m_ctiOffsets[loc->value.m_indexInTable];
}
-
-#if ENABLE(JIT)
- inline CodeLocationLabel<JSSwitchPtrTag> ctiForValue(StringImpl* value)
- {
- StringOffsetTable::const_iterator end = offsetTable.end();
- StringOffsetTable::const_iterator loc = offsetTable.find(value);
- if (loc == end)
- return ctiDefault;
- return loc->value.ctiOffset;
- }
+ };
#endif
-
- void clear()
- {
- offsetTable.clear();
- }
- };
struct SimpleJumpTable {
// FIXME: The two Vectors can be combined into one Vector<OffsetLocation>
Modified: trunk/Source/_javascript_Core/bytecode/PreciseJumpTargetsInlines.h (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/PreciseJumpTargetsInlines.h 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/PreciseJumpTargetsInlines.h 2021-04-12 22:01:09 UTC (rev 275840)
@@ -77,11 +77,9 @@
} \
case op_switch_string: { \
auto bytecode = instruction->as<OpSwitchString>(); \
- auto& table = codeBlock->stringSwitchJumpTable(bytecode.m_tableIndex); \
- auto iter = table.offsetTable.begin(); \
- auto end = table.offsetTable.end(); \
- for (; iter != end; ++iter) \
- SWITCH_CASE(iter->value.branchOffset); \
+ auto& table = codeBlock->unlinkedStringSwitchJumpTable(bytecode.m_tableIndex); \
+ for (auto& entry : table.m_offsetTable) \
+ SWITCH_CASE(entry.value.m_branchOffset); \
SWITCH_DEFAULT_OFFSET(OpSwitchString); \
break; \
} \
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2021-04-12 22:01:09 UTC (rev 275840)
@@ -77,19 +77,19 @@
struct UnlinkedStringJumpTable {
struct OffsetLocation {
- int32_t branchOffset;
+ int32_t m_branchOffset;
+ unsigned m_indexInTable;
};
using StringOffsetTable = MemoryCompactLookupOnlyRobinHoodHashMap<RefPtr<StringImpl>, OffsetLocation>;
- StringOffsetTable offsetTable;
+ StringOffsetTable m_offsetTable;
- inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
+ inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset) const
{
- StringOffsetTable::const_iterator end = offsetTable.end();
- StringOffsetTable::const_iterator loc = offsetTable.find(value);
- if (loc == end)
+ auto loc = m_offsetTable.find(value);
+ if (loc == m_offsetTable.end())
return defaultOffset;
- return loc->value.branchOffset;
+ return loc->value.m_branchOffset;
}
};
@@ -188,8 +188,8 @@
size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
- size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
- UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
+ size_t numberOfUnlinkedStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_unlinkedStringSwitchJumpTables.size() : 0; }
+ const UnlinkedStringJumpTable& unlinkedStringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_unlinkedStringSwitchJumpTables[tableIndex]; }
UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
@@ -400,7 +400,7 @@
// Jump Tables
FixedVector<UnlinkedSimpleJumpTable> m_switchJumpTables;
- FixedVector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
+ FixedVector<UnlinkedStringJumpTable> m_unlinkedStringSwitchJumpTables;
FixedVector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -133,7 +133,7 @@
if (!m_codeBlock->m_rareData) {
if (!m_exceptionHandlers.isEmpty()
|| !m_switchJumpTables.isEmpty()
- || !m_stringSwitchJumpTables.isEmpty()
+ || !m_unlinkedStringSwitchJumpTables.isEmpty()
|| !m_expressionInfoFatPositions.isEmpty()
|| !m_typeProfilerInfoMap.isEmpty()
|| !m_opProfileControlFlowBytecodeOffsets.isEmpty()
@@ -144,7 +144,7 @@
if (m_codeBlock->m_rareData) {
m_codeBlock->m_rareData->m_exceptionHandlers = WTFMove(m_exceptionHandlers);
m_codeBlock->m_rareData->m_switchJumpTables = WTFMove(m_switchJumpTables);
- m_codeBlock->m_rareData->m_stringSwitchJumpTables = WTFMove(m_stringSwitchJumpTables);
+ m_codeBlock->m_rareData->m_unlinkedStringSwitchJumpTables = WTFMove(m_unlinkedStringSwitchJumpTables);
m_codeBlock->m_rareData->m_expressionInfoFatPositions = WTFMove(m_expressionInfoFatPositions);
m_codeBlock->m_rareData->m_typeProfilerInfoMap = WTFMove(m_typeProfilerInfoMap);
m_codeBlock->m_rareData->m_opProfileControlFlowBytecodeOffsets = WTFMove(m_opProfileControlFlowBytecodeOffsets);
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.h (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.h 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.h 2021-04-12 22:01:09 UTC (rev 275840)
@@ -94,9 +94,9 @@
UnlinkedSimpleJumpTable& addSwitchJumpTable() { m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_switchJumpTables.last(); }
UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { return m_switchJumpTables[tableIndex]; }
- size_t numberOfStringSwitchJumpTables() const { return m_stringSwitchJumpTables.size(); }
- UnlinkedStringJumpTable& addStringSwitchJumpTable() { m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_stringSwitchJumpTables.last(); }
- UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { return m_stringSwitchJumpTables[tableIndex]; }
+ size_t numberOfUnlinkedStringSwitchJumpTables() const { return m_unlinkedStringSwitchJumpTables.size(); }
+ UnlinkedStringJumpTable& addUnlinkedStringSwitchJumpTable() { m_unlinkedStringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_unlinkedStringSwitchJumpTables.last(); }
+ UnlinkedStringJumpTable& unlinkedStringSwitchJumpTable(int tableIndex) { return m_unlinkedStringSwitchJumpTables[tableIndex]; }
size_t numberOfExceptionHandlers() const { return m_exceptionHandlers.size(); }
UnlinkedHandlerInfo& exceptionHandler(int index) { return m_exceptionHandlers[index]; }
@@ -205,7 +205,7 @@
// In RareData.
Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
Vector<UnlinkedSimpleJumpTable> m_switchJumpTables;
- Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
+ Vector<UnlinkedStringJumpTable> m_unlinkedStringSwitchJumpTables;
Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
HashMap<unsigned, UnlinkedCodeBlock::RareData::TypeProfilerExpressionRange> m_typeProfilerInfoMap;
Vector<InstructionStream::Offset> m_opProfileControlFlowBytecodeOffsets;
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -4048,8 +4048,8 @@
break;
}
case SwitchInfo::SwitchString: {
- size_t tableIndex = m_codeBlock->numberOfStringSwitchJumpTables();
- m_codeBlock->addStringSwitchJumpTable();
+ size_t tableIndex = m_codeBlock->numberOfUnlinkedStringSwitchJumpTables();
+ m_codeBlock->addUnlinkedStringSwitchJumpTable();
OpSwitchString::emit(this, tableIndex, BoundLabel(), scrutineeRegister);
break;
}
@@ -4111,7 +4111,9 @@
ASSERT(nodes[i]->isString());
StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl();
- jumpTable.offsetTable.add(clause, UnlinkedStringJumpTable::OffsetLocation { labels[i]->bind(switchAddress) });
+ auto result = jumpTable.m_offsetTable.add(clause, UnlinkedStringJumpTable::OffsetLocation { labels[i]->bind(switchAddress), 0 });
+ if (result.isNewEntry)
+ result.iterator->value.m_indexInTable = jumpTable.m_offsetTable.size() - 1;
}
}
@@ -4152,7 +4154,7 @@
return BoundLabel();
});
- UnlinkedStringJumpTable& jumpTable = m_codeBlock->stringSwitchJumpTable(ref->as<OpSwitchString>().m_tableIndex);
+ UnlinkedStringJumpTable& jumpTable = m_codeBlock->unlinkedStringSwitchJumpTable(ref->as<OpSwitchString>().m_tableIndex);
prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -6913,15 +6913,13 @@
data.kind = SwitchString;
data.switchTableIndex = bytecode.m_tableIndex;
data.fallThrough.setBytecodeIndex(m_currentIndex.offset() + jumpTarget(bytecode.m_defaultOffset));
- StringJumpTable& table = m_codeBlock->stringSwitchJumpTable(data.switchTableIndex);
- StringJumpTable::StringOffsetTable::iterator iter;
- StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
- for (iter = table.offsetTable.begin(); iter != end; ++iter) {
- unsigned target = m_currentIndex.offset() + iter->value.branchOffset;
+ const UnlinkedStringJumpTable& table = m_codeBlock->unlinkedStringSwitchJumpTable(data.switchTableIndex);
+ for (const auto& entry : table.m_offsetTable) {
+ unsigned target = m_currentIndex.offset() + entry.value.m_branchOffset;
if (target == data.fallThrough.bytecodeIndex())
continue;
data.cases.append(
- SwitchCase::withBytecodeIndex(LazyJSValue::knownStringImpl(iter->key.get()), target));
+ SwitchCase::withBytecodeIndex(LazyJSValue::knownStringImpl(entry.key.get()), target));
}
addToGraph(Switch, OpInfo(&data), get(bytecode.m_scrutinee));
flushIfTerminal(data);
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -176,6 +176,11 @@
m_graph.registerFrozenValues();
+ if (m_codeBlock->numberOfUnlinkedStringSwitchJumpTables()) {
+ ConcurrentJSLocker locker(m_codeBlock->m_lock);
+ m_codeBlock->ensureJITData(locker).m_stringSwitchJumpTables = FixedVector<StringJumpTable>(m_codeBlock->numberOfUnlinkedStringSwitchJumpTables());
+ }
+
BitVector usedJumpTables;
for (Bag<SwitchData>::iterator iter = m_graph.m_switchData.begin(); !!iter; ++iter) {
SwitchData& data = ""
@@ -218,18 +223,18 @@
if (data.kind != SwitchString)
continue;
- StringJumpTable& table = m_codeBlock->stringSwitchJumpTable(data.switchTableIndex);
+ const UnlinkedStringJumpTable& unlinkedTable = m_codeBlock->unlinkedStringSwitchJumpTable(data.switchTableIndex);
+ StringJumpTable& linkedTable = m_codeBlock->stringSwitchJumpTable(data.switchTableIndex);
+ linkedTable.m_ctiDefault = linkBuffer.locationOf<JSSwitchPtrTag>(m_blockHeads[data.fallThrough.block->index]);
+ linkedTable.m_ctiOffsets = FixedVector<CodeLocationLabel<JSSwitchPtrTag>>(unlinkedTable.m_offsetTable.size());
- table.ctiDefault = linkBuffer.locationOf<JSSwitchPtrTag>(m_blockHeads[data.fallThrough.block->index]);
- StringJumpTable::StringOffsetTable::iterator iter;
- StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
- for (iter = table.offsetTable.begin(); iter != end; ++iter)
- iter->value.ctiOffset = table.ctiDefault;
+ for (auto& entry : linkedTable.m_ctiOffsets)
+ entry = linkedTable.m_ctiDefault;
for (unsigned j = data.cases.size(); j--;) {
SwitchCase& myCase = data.cases[j];
- iter = table.offsetTable.find(myCase.value.stringImpl());
- RELEASE_ASSERT(iter != end);
- iter->value.ctiOffset = linkBuffer.locationOf<JSSwitchPtrTag>(m_blockHeads[myCase.target.block->index]);
+ auto iter = unlinkedTable.m_offsetTable.find(myCase.value.stringImpl());
+ RELEASE_ASSERT(iter != unlinkedTable.m_offsetTable.end());
+ linkedTable.m_ctiOffsets[iter->value.m_indexInTable] = linkBuffer.locationOf<JSSwitchPtrTag>(m_blockHeads[myCase.target.block->index]);
}
}
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -2716,8 +2716,10 @@
StringImpl* strImpl = string->value(globalObject).impl();
RETURN_IF_EXCEPTION(throwScope, nullptr);
-
- return callFrame->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(strImpl).executableAddress<char*>();
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ const StringJumpTable& linkedTable = codeBlock->stringSwitchJumpTable(tableIndex);
+ const UnlinkedStringJumpTable& unlinkedTable = codeBlock->unlinkedStringSwitchJumpTable(tableIndex);
+ return linkedTable.ctiForValue(unlinkedTable, strImpl).executableAddress<char*>();
}
JSC_DEFINE_JIT_OPERATION(operationCompareStringImplLess, uintptr_t, (StringImpl* a, StringImpl* b))
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -16747,7 +16747,7 @@
Int32, operationSwitchStringAndGetBranchOffset,
weakPointer(globalObject), m_out.constIntPtr(data->switchTableIndex), string);
- StringJumpTable& table = codeBlock()->stringSwitchJumpTable(data->switchTableIndex);
+ const UnlinkedStringJumpTable& table = codeBlock()->unlinkedStringSwitchJumpTable(data->switchTableIndex);
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.
@@ -16785,15 +16785,14 @@
// https://bugs.webkit.org/show_bug.cgi?id=144635
DFG::SwitchCase myCase = data->cases[i];
- StringJumpTable::StringOffsetTable::iterator iter =
- table.offsetTable.find(myCase.value.stringImpl());
- DFG_ASSERT(m_graph, m_node, iter != table.offsetTable.end());
+ auto iter = table.m_offsetTable.find(myCase.value.stringImpl());
+ DFG_ASSERT(m_graph, m_node, iter != table.m_offsetTable.end());
- if (!alreadyHandled.insert(iter->value.branchOffset).second)
+ if (!alreadyHandled.insert(iter->value.m_branchOffset).second)
continue;
cases.append(SwitchCase(
- m_out.constInt32(iter->value.branchOffset),
+ m_out.constInt32(iter->value.m_branchOffset),
lowBlock(myCase.target.block), Weight(myCase.target.count)));
}
Modified: trunk/Source/_javascript_Core/ftl/FTLOperations.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/ftl/FTLOperations.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/ftl/FTLOperations.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -709,7 +709,7 @@
RETURN_IF_EXCEPTION(throwScope, 0);
- return callFrame->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(strImpl, std::numeric_limits<int32_t>::min());
+ return callFrame->codeBlock()->unlinkedStringSwitchJumpTable(tableIndex).offsetForValue(strImpl, std::numeric_limits<int32_t>::min());
}
JSC_DEFINE_JIT_OPERATION(operationTypeOfObjectAsTypeofType, int32_t, (JSGlobalObject* globalObject, JSCell* object))
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -857,6 +857,11 @@
if (patchBuffer.didFailToAllocate())
return CompilationFailed;
+ if (m_codeBlock->numberOfUnlinkedStringSwitchJumpTables()) {
+ ConcurrentJSLocker locker(m_codeBlock->m_lock);
+ m_codeBlock->ensureJITData(locker).m_stringSwitchJumpTables = FixedVector<StringJumpTable>(m_codeBlock->numberOfUnlinkedStringSwitchJumpTables());
+ }
+
// Translate vPC offsets into addresses in JIT generated code, for switch tables.
for (auto& record : m_switches) {
unsigned bytecodeOffset = record.bytecodeIndex.offset();
@@ -877,15 +882,17 @@
} else {
ASSERT(record.type == SwitchRecord::String);
- auto* stringJumpTable = record.jumpTable.stringJumpTable;
- stringJumpTable->ctiDefault =
- patchBuffer.locationOf<JSSwitchPtrTag>(m_labels[bytecodeOffset + record.defaultOffset]);
+ unsigned tableIndex = record.jumpTable.tableIndex;
+ const UnlinkedStringJumpTable& unlinkedTable = m_codeBlock->unlinkedStringSwitchJumpTable(tableIndex);
+ StringJumpTable& linkedTable = m_codeBlock->stringSwitchJumpTable(tableIndex);
+ linkedTable.m_ctiDefault = patchBuffer.locationOf<JSSwitchPtrTag>(m_labels[bytecodeOffset + record.defaultOffset]);
+ linkedTable.m_ctiOffsets = FixedVector<CodeLocationLabel<JSSwitchPtrTag>>(unlinkedTable.m_offsetTable.size());
- for (auto& location : stringJumpTable->offsetTable.values()) {
- unsigned offset = location.branchOffset;
- location.ctiOffset = offset
+ for (auto& location : unlinkedTable.m_offsetTable.values()) {
+ unsigned offset = location.m_branchOffset;
+ linkedTable.m_ctiOffsets[location.m_indexInTable] = offset
? patchBuffer.locationOf<JSSwitchPtrTag>(m_labels[bytecodeOffset + offset])
- : stringJumpTable->ctiDefault;
+ : linkedTable.m_ctiDefault;
}
}
}
Modified: trunk/Source/_javascript_Core/jit/JIT.h (275839 => 275840)
--- trunk/Source/_javascript_Core/jit/JIT.h 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2021-04-12 22:01:09 UTC (rev 275840)
@@ -128,7 +128,7 @@
union {
SimpleJumpTable* simpleJumpTable;
- StringJumpTable* stringJumpTable;
+ unsigned tableIndex;
} jumpTable;
BytecodeIndex bytecodeIndex;
@@ -142,12 +142,12 @@
this->jumpTable.simpleJumpTable = jumpTable;
}
- SwitchRecord(StringJumpTable* jumpTable, BytecodeIndex bytecodeIndex, unsigned defaultOffset)
- : type(String)
+ SwitchRecord(unsigned tableIndex, BytecodeIndex bytecodeIndex, unsigned defaultOffset, Type type)
+ : type(type)
, bytecodeIndex(bytecodeIndex)
, defaultOffset(defaultOffset)
{
- this->jumpTable.stringJumpTable = jumpTable;
+ this->jumpTable.tableIndex = tableIndex;
}
};
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -934,8 +934,7 @@
VirtualRegister scrutinee = bytecode.m_scrutinee;
// create jump table for switch destinations, track this switch statement.
- StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
- m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
+ m_switches.append(SwitchRecord(tableIndex, m_bytecodeIndex, defaultOffset, SwitchRecord::String));
emitGetVirtualRegister(scrutinee, regT0);
callOperation(operationSwitchStringWithUnknownKeyType, TrustedImmPtr(m_codeBlock->globalObject()), regT0, tableIndex);
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -1028,8 +1028,7 @@
VirtualRegister scrutinee = bytecode.m_scrutinee;
// create jump table for switch destinations, track this switch statement.
- StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
- m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
+ m_switches.append(SwitchRecord(tableIndex, m_bytecodeIndex, defaultOffset, SwitchRecord::String));
emitLoad(scrutinee, regT1, regT0);
callOperation(operationSwitchStringWithUnknownKeyType, m_codeBlock->globalObject(), JSValueRegs(regT1, regT0), tableIndex);
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -2845,7 +2845,7 @@
auto throwScope = DECLARE_THROW_SCOPE(vm);
void* result;
- StringJumpTable& jumpTable = codeBlock->stringSwitchJumpTable(tableIndex);
+ const StringJumpTable& linkedTable = codeBlock->stringSwitchJumpTable(tableIndex);
if (key.isString()) {
StringImpl* value = asString(key)->value(globalObject).impl();
@@ -2852,9 +2852,10 @@
RETURN_IF_EXCEPTION(throwScope, nullptr);
- result = jumpTable.ctiForValue(value).executableAddress();
+ const UnlinkedStringJumpTable& unlinkedTable = codeBlock->unlinkedStringSwitchJumpTable(tableIndex);
+ result = linkedTable.ctiForValue(unlinkedTable, value).executableAddress();
} else
- result = jumpTable.ctiDefault.executableAddress();
+ result = linkedTable.m_ctiDefault.executableAddress();
assertIsTaggedWith<JSSwitchPtrTag>(result);
return reinterpret_cast<char*>(result);
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -1630,7 +1630,7 @@
LLINT_CHECK_EXCEPTION();
- JUMP_TO(codeBlock->stringSwitchJumpTable(bytecode.m_tableIndex).offsetForValue(scrutineeStringImpl, defaultOffset));
+ JUMP_TO(codeBlock->unlinkedStringSwitchJumpTable(bytecode.m_tableIndex).offsetForValue(scrutineeStringImpl, defaultOffset));
}
LLINT_END();
}
Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (275839 => 275840)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2021-04-12 21:28:41 UTC (rev 275839)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2021-04-12 22:01:09 UTC (rev 275840)
@@ -884,12 +884,12 @@
public:
void encode(Encoder& encoder, const UnlinkedStringJumpTable& jumpTable)
{
- m_offsetTable.encode(encoder, jumpTable.offsetTable);
+ m_offsetTable.encode(encoder, jumpTable.m_offsetTable);
}
void decode(Decoder& decoder, UnlinkedStringJumpTable& jumpTable) const
{
- m_offsetTable.decode(decoder, jumpTable.offsetTable);
+ m_offsetTable.decode(decoder, jumpTable.m_offsetTable);
}
private:
@@ -951,7 +951,7 @@
{
m_exceptionHandlers.encode(encoder, rareData.m_exceptionHandlers);
m_switchJumpTables.encode(encoder, rareData.m_switchJumpTables);
- m_stringSwitchJumpTables.encode(encoder, rareData.m_stringSwitchJumpTables);
+ m_unlinkedStringSwitchJumpTables.encode(encoder, rareData.m_unlinkedStringSwitchJumpTables);
m_expressionInfoFatPositions.encode(encoder, rareData.m_expressionInfoFatPositions);
m_typeProfilerInfoMap.encode(encoder, rareData.m_typeProfilerInfoMap);
m_opProfileControlFlowBytecodeOffsets.encode(encoder, rareData.m_opProfileControlFlowBytecodeOffsets);
@@ -966,7 +966,7 @@
UnlinkedCodeBlock::RareData* rareData = new UnlinkedCodeBlock::RareData { };
m_exceptionHandlers.decode(decoder, rareData->m_exceptionHandlers);
m_switchJumpTables.decode(decoder, rareData->m_switchJumpTables);
- m_stringSwitchJumpTables.decode(decoder, rareData->m_stringSwitchJumpTables);
+ m_unlinkedStringSwitchJumpTables.decode(decoder, rareData->m_unlinkedStringSwitchJumpTables);
m_expressionInfoFatPositions.decode(decoder, rareData->m_expressionInfoFatPositions);
m_typeProfilerInfoMap.decode(decoder, rareData->m_typeProfilerInfoMap);
m_opProfileControlFlowBytecodeOffsets.decode(decoder, rareData->m_opProfileControlFlowBytecodeOffsets);
@@ -980,7 +980,7 @@
private:
CachedVector<UnlinkedHandlerInfo> m_exceptionHandlers;
CachedVector<CachedSimpleJumpTable> m_switchJumpTables;
- CachedVector<CachedStringJumpTable> m_stringSwitchJumpTables;
+ CachedVector<CachedStringJumpTable> m_unlinkedStringSwitchJumpTables;
CachedVector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
CachedHashMap<unsigned, UnlinkedCodeBlock::RareData::TypeProfilerExpressionRange> m_typeProfilerInfoMap;
CachedVector<InstructionStream::Offset> m_opProfileControlFlowBytecodeOffsets;