Skip to content

Commit cb619a3

Browse files
committed
[JSC] Enable JIT compiling by DFG for String#codePointAt on ARMv7
https://bugs.webkit.org/show_bug.cgi?id=295149 Reviewed by Justin Michaud. String#codePointAt is only JIT compiled on 64-bit architectures. This patch enables JIT compilation on ARMv7 by moving the compileStringCodePointAt function from DFGSpeculativeJIT64.cpp to the shared DFGSpeculativeJIT.cpp file. The implementation itself remains unchanged, making it available to both 32-bit and 64-bit architectures without any functional modifications. * Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleIntrinsicCall): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileStringCodePointAt): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compileStringCodePointAt): Deleted. Canonical link: https://commits.webkit.org/296841@main
1 parent e2d0e14 commit cb619a3

File tree

4 files changed

+54
-53
lines changed

4 files changed

+54
-53
lines changed

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,9 +2977,6 @@ auto ByteCodeParser::handleIntrinsicCall(Node* callee, Operand resultOperand, Ca
29772977
}
29782978

29792979
case StringPrototypeCodePointAtIntrinsic: {
2980-
if (!is64Bit())
2981-
return CallOptimizationResult::DidNothing;
2982-
29832980
if (argumentCountIncludingThis < 1)
29842981
return CallOptimizationResult::DidNothing;
29852982

Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,55 @@ void SpeculativeJIT::compileToLowerCase(Node* node)
18611861
cellResult(lengthGPR, node);
18621862
}
18631863

1864+
void SpeculativeJIT::compileStringCodePointAt(Node* node)
1865+
{
1866+
// And CheckArray also ensures that this String is not a rope.
1867+
SpeculateCellOperand string(this, node->child1());
1868+
SpeculateStrictInt32Operand index(this, node->child2());
1869+
GPRTemporary scratch1(this);
1870+
GPRTemporary scratch2(this);
1871+
GPRTemporary scratch3(this);
1872+
GPRTemporary scratch4(this);
1873+
1874+
GPRReg stringGPR = string.gpr();
1875+
GPRReg indexGPR = index.gpr();
1876+
GPRReg scratch1GPR = scratch1.gpr();
1877+
GPRReg scratch2GPR = scratch2.gpr();
1878+
GPRReg scratch3GPR = scratch3.gpr();
1879+
GPRReg scratch4GPR = scratch4.gpr();
1880+
1881+
loadPtr(Address(stringGPR, JSString::offsetOfValue()), scratch1GPR);
1882+
load32(Address(scratch1GPR, StringImpl::lengthMemoryOffset()), scratch2GPR);
1883+
1884+
// unsigned comparison so we can filter out negative indices and indices that are too large
1885+
speculationCheck(Uncountable, JSValueRegs(), nullptr, branch32(AboveOrEqual, indexGPR, scratch2GPR));
1886+
1887+
// Load the character into scratch1GPR
1888+
loadPtr(Address(scratch1GPR, StringImpl::dataOffset()), scratch4GPR);
1889+
auto is16Bit = branchTest32(Zero, Address(scratch1GPR, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
1890+
1891+
JumpList done;
1892+
1893+
load8(BaseIndex(scratch4GPR, indexGPR, TimesOne, 0), scratch1GPR);
1894+
done.append(jump());
1895+
1896+
is16Bit.link(this);
1897+
load16(BaseIndex(scratch4GPR, indexGPR, TimesTwo, 0), scratch1GPR);
1898+
// This is ok. indexGPR must be positive int32_t here and adding 1 never causes overflow if we treat indexGPR as uint32_t.
1899+
add32(TrustedImm32(1), indexGPR, scratch3GPR);
1900+
done.append(branch32(AboveOrEqual, scratch3GPR, scratch2GPR));
1901+
and32(TrustedImm32(0xfffffc00), scratch1GPR, scratch2GPR);
1902+
done.append(branch32(NotEqual, scratch2GPR, TrustedImm32(0xd800)));
1903+
load16(BaseIndex(scratch4GPR, scratch3GPR, TimesTwo, 0), scratch3GPR);
1904+
and32(TrustedImm32(0xfffffc00), scratch3GPR, scratch2GPR);
1905+
done.append(branch32(NotEqual, scratch2GPR, TrustedImm32(0xdc00)));
1906+
lshift32(TrustedImm32(10), scratch1GPR);
1907+
getEffectiveAddress(BaseIndex(scratch1GPR, scratch3GPR, TimesOne, -U16_SURROGATE_OFFSET), scratch1GPR);
1908+
done.link(this);
1909+
1910+
strictInt32Result(scratch1GPR, m_currentNode);
1911+
}
1912+
18641913
void SpeculativeJIT::compilePeepHoleInt32Branch(Node* node, Node* branchNode, RelationalCondition condition)
18651914
{
18661915
BasicBlock* taken = branchNode->branchData()->taken.block;

Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2586,6 +2586,11 @@ void SpeculativeJIT::compile(Node* node)
25862586
break;
25872587
}
25882588

2589+
case StringCodePointAt: {
2590+
compileStringCodePointAt(node);
2591+
break;
2592+
}
2593+
25892594
case StringAt:
25902595
case StringCharAt: {
25912596
// Relies on StringCharAt and StringAt node having same basic layout as GetByVal
@@ -4437,7 +4442,6 @@ void SpeculativeJIT::compile(Node* node)
44374442
case DateGetInt32OrNaN:
44384443
case DateGetTime:
44394444
case DateSetTime:
4440-
case StringCodePointAt:
44414445
case CallWasm:
44424446
case FunctionBind:
44434447
case NewBoundFunction:

Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6708,55 +6708,6 @@ void SpeculativeJIT::compileArithRandom(Node* node)
67086708
doubleResult(result.fpr(), node);
67096709
}
67106710

6711-
void SpeculativeJIT::compileStringCodePointAt(Node* node)
6712-
{
6713-
// We emit CheckArray on this node as we do in StringCharCodeAt node so that we do not need to check SpecString here.
6714-
// And CheckArray also ensures that this String is not a rope.
6715-
SpeculateCellOperand string(this, node->child1());
6716-
SpeculateStrictInt32Operand index(this, node->child2());
6717-
GPRTemporary scratch1(this);
6718-
GPRTemporary scratch2(this);
6719-
GPRTemporary scratch3(this);
6720-
GPRTemporary scratch4(this);
6721-
6722-
GPRReg stringGPR = string.gpr();
6723-
GPRReg indexGPR = index.gpr();
6724-
GPRReg scratch1GPR = scratch1.gpr();
6725-
GPRReg scratch2GPR = scratch2.gpr();
6726-
GPRReg scratch3GPR = scratch3.gpr();
6727-
GPRReg scratch4GPR = scratch4.gpr();
6728-
6729-
loadPtr(Address(stringGPR, JSString::offsetOfValue()), scratch1GPR);
6730-
load32(Address(scratch1GPR, StringImpl::lengthMemoryOffset()), scratch2GPR);
6731-
6732-
// unsigned comparison so we can filter out negative indices and indices that are too large
6733-
speculationCheck(Uncountable, JSValueRegs(), nullptr, branch32(AboveOrEqual, indexGPR, scratch2GPR));
6734-
6735-
// Load the character into scratch1GPR
6736-
loadPtr(Address(scratch1GPR, StringImpl::dataOffset()), scratch4GPR);
6737-
auto is16Bit = branchTest32(Zero, Address(scratch1GPR, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
6738-
6739-
JumpList done;
6740-
6741-
load8(BaseIndex(scratch4GPR, indexGPR, TimesOne, 0), scratch1GPR);
6742-
done.append(jump());
6743-
6744-
is16Bit.link(this);
6745-
load16(BaseIndex(scratch4GPR, indexGPR, TimesTwo, 0), scratch1GPR);
6746-
// This is ok. indexGPR must be positive int32_t here and adding 1 never causes overflow if we treat indexGPR as uint32_t.
6747-
add32(TrustedImm32(1), indexGPR, scratch3GPR);
6748-
done.append(branch32(AboveOrEqual, scratch3GPR, scratch2GPR));
6749-
and32(TrustedImm32(0xfffffc00), scratch1GPR, scratch2GPR);
6750-
done.append(branch32(NotEqual, scratch2GPR, TrustedImm32(0xd800)));
6751-
load16(BaseIndex(scratch4GPR, scratch3GPR, TimesTwo, 0), scratch3GPR);
6752-
and32(TrustedImm32(0xfffffc00), scratch3GPR, scratch2GPR);
6753-
done.append(branch32(NotEqual, scratch2GPR, TrustedImm32(0xdc00)));
6754-
lshift32(TrustedImm32(10), scratch1GPR);
6755-
getEffectiveAddress(BaseIndex(scratch1GPR, scratch3GPR, TimesOne, -U16_SURROGATE_OFFSET), scratch1GPR);
6756-
done.link(this);
6757-
6758-
strictInt32Result(scratch1GPR, m_currentNode);
6759-
}
67606711

67616712
void SpeculativeJIT::compileDateGet(Node* node)
67626713
{

0 commit comments

Comments
 (0)