Skip to content

Commit 6fbae40

Browse files
committed
[JSC] Use StringSwitch with resolved rope strings in FTL
https://bugs.webkit.org/show_bug.cgi?id=322144 rdar://185366501 Reviewed by Yijia Huang. FTL StringSwitch is really efficient for non atom strings, so let's use it even for resolved rope strings. When we encounter a rope string, we call a function and resolve them. If it is 8bit string, then returning a data pointer so that we can use FTL StringSwitch with it. * Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): * Source/JavaScriptCore/ftl/FTLOperations.cpp: (JSC::FTL::JSC_DEFINE_NOEXCEPT_JIT_OPERATION): * Source/JavaScriptCore/ftl/FTLOperations.h: Canonical link: https://commits.webkit.org/319501@main
1 parent c8f6b5d commit 6fbae40

3 files changed

Lines changed: 33 additions & 4 deletions

File tree

‎Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp‎

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23849,12 +23849,16 @@ IGNORE_CLANG_WARNINGS_END
2384923849
return;
2385023850
}
2385123851

23852+
JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
23853+
2385223854
LBasicBlock hasImplBlock = m_out.newBlock();
2385323855
LBasicBlock is8BitBlock = m_out.newBlock();
2385423856
LBasicBlock isRopeBlock = m_out.newBlock();
2385523857
LBasicBlock isSubstringBlock = m_out.newBlock();
2385623858
LBasicBlock substringBlock = m_out.newBlock();
2385723859
LBasicBlock concatRopeBlock = m_out.newBlock();
23860+
LBasicBlock resolveConcatRopeBlock = m_out.newBlock();
23861+
LBasicBlock resolvedConcatRopeBlock = m_out.newBlock();
2385823862
LBasicBlock binarySwitchBlock = m_out.newBlock();
2385923863
LBasicBlock slowBlock = m_out.newBlock();
2386023864

@@ -23904,18 +23908,27 @@ IGNORE_CLANG_WARNINGS_END
2390423908
ValueFromBlock substringLength = m_out.anchor(m_out.load32NonNegative(string, m_heaps.JSRopeString_length));
2390523909
m_out.jump(binarySwitchBlock);
2390623910

23907-
m_out.appendTo(concatRopeBlock, binarySwitchBlock);
23911+
m_out.appendTo(concatRopeBlock, resolveConcatRopeBlock);
2390823912
const UnlinkedStringJumpTable& unlinkedTable = m_graph.unlinkedStringSwitchJumpTable(data->switchTableIndex);
2390923913
LValue ropeLength;
2391023914
if (auto stringLength = tryGetConstantStringLength(edge))
2391123915
ropeLength = m_out.constInt32(*stringLength);
2391223916
else
2391323917
ropeLength = m_out.load32NonNegative(string, m_heaps.JSRopeString_length);
23914-
m_out.branch(m_out.belowOrEqual(m_out.sub(ropeLength, m_out.constInt32(unlinkedTable.minLength())), m_out.constInt32(unlinkedTable.maxLength() - unlinkedTable.minLength())), unsure(slowBlock), unsure(lowBlock(data->fallThrough.block)));
23918+
m_out.branch(m_out.belowOrEqual(m_out.sub(ropeLength, m_out.constInt32(unlinkedTable.minLength())), m_out.constInt32(unlinkedTable.maxLength() - unlinkedTable.minLength())), unsure(resolveConcatRopeBlock), unsure(lowBlock(data->fallThrough.block)));
23919+
23920+
m_out.appendTo(resolveConcatRopeBlock, resolvedConcatRopeBlock);
23921+
LValue resolvedRopeCharacters = vmCall(pointerType(), operationSwitchStringResolveRopeAndGetCharacters8, weakPointer(globalObject), string);
23922+
m_out.branch(m_out.isNull(resolvedRopeCharacters), rarely(slowBlock), usually(resolvedConcatRopeBlock));
23923+
23924+
m_out.appendTo(resolvedConcatRopeBlock, binarySwitchBlock);
23925+
ValueFromBlock resolvedRopeBuffer = m_out.anchor(resolvedRopeCharacters);
23926+
ValueFromBlock resolvedRopeLength = m_out.anchor(ropeLength);
23927+
m_out.jump(binarySwitchBlock);
2391523928

2391623929
m_out.appendTo(binarySwitchBlock, slowBlock);
23917-
LValue buffer = m_out.phi(pointerType(), resolvedBuffer, substringBuffer);
23918-
LValue switchLength = m_out.phi(Int32, resolvedLength, substringLength);
23930+
LValue buffer = m_out.phi(pointerType(), resolvedBuffer, substringBuffer, resolvedRopeBuffer);
23931+
LValue switchLength = m_out.phi(Int32, resolvedLength, substringLength, resolvedRopeLength);
2391923932

2392023933
// FIXME: We should propagate branch weight data to the cases of this switch.
2392123934
// https://bugs.webkit.org/show_bug.cgi?id=144368

‎Source/JavaScriptCore/ftl/FTLOperations.cpp‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,21 @@ JSC_DEFINE_NOEXCEPT_JIT_OPERATION(operationSwitchStringAndGetIndex, UCPUStrictIn
922922
return toUCPUStrictInt32(unlinkedTable->indexForValue(str->impl(), std::numeric_limits<unsigned>::max()));
923923
}
924924

925+
JSC_DEFINE_NOEXCEPT_JIT_OPERATION(operationSwitchStringResolveRopeAndGetCharacters8, const Latin1Character*, (JSGlobalObject* globalObject, JSString* string))
926+
{
927+
VM& vm = globalObject->vm();
928+
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
929+
JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
930+
931+
// We intentionally use tryGetValue here instead of value() function not to throw OOM error.
932+
// When failing, we will just return a nullptr, and going to the slow path.
933+
auto value = string->tryGetValue();
934+
StringImpl* impl = value.data.impl();
935+
if (!impl || !impl->is8Bit())
936+
return nullptr;
937+
return impl->span8().data();
938+
}
939+
925940
JSC_DEFINE_NOEXCEPT_JIT_OPERATION(operationTypeOfObjectAsTypeofType, UCPUStrictInt32, (JSGlobalObject* globalObject, JSCell* object))
926941
{
927942
VM& vm = globalObject->vm();

‎Source/JavaScriptCore/ftl/FTLOperations.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ JSC_DECLARE_NOEXCEPT_JIT_OPERATION(operationPopulateObjectInOSR, void, (JSGlobal
4545
JSC_DECLARE_NOEXCEPT_JIT_OPERATION(operationCompileFTLLazySlowPath, void*, (CallFrame*, unsigned));
4646

4747
JSC_DECLARE_NOEXCEPT_JIT_OPERATION(operationSwitchStringAndGetIndex, UCPUStrictInt32, (JSGlobalObject*, const UnlinkedStringJumpTable*, JSString*));
48+
JSC_DECLARE_NOEXCEPT_JIT_OPERATION(operationSwitchStringResolveRopeAndGetCharacters8, const Latin1Character*, (JSGlobalObject*, JSString*));
4849
JSC_DECLARE_NOEXCEPT_JIT_OPERATION(operationTypeOfObjectAsTypeofType, UCPUStrictInt32, (JSGlobalObject*, JSCell*));
4950

5051
JSC_DECLARE_NOEXCEPT_JIT_OPERATION(operationReportBoundsCheckEliminationErrorAndCrash, void, (intptr_t codeBlockAsIntPtr, int32_t, int32_t, int32_t, int32_t, int32_t));

0 commit comments

Comments
 (0)