Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (291514 => 291515)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2022-03-19 00:46:37 UTC (rev 291514)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2022-03-19 00:55:48 UTC (rev 291515)
@@ -2703,28 +2703,24 @@
SpeculateCellOperand globalObject(this, node->child1());
SpeculateCellOperand base(this, node->child2());
- GPRReg globalObjectGPR = globalObject.gpr();
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR;
- GPRFlushedCallResult result(this);
- GPRReg resultGPR = result.gpr();
+
GPRTemporary stringImpl(this);
GPRTemporary stringData(this);
GPRTemporary strLength(this);
GPRTemporary output(this);
- GPRTemporary result2(this);
GPRTemporary temp0(this);
GPRTemporary temp1(this);
- GPRTemporary temp2;
+ std::optional<GPRTemporary> temp2;
+
+ GPRReg globalObjectGPR = globalObject.gpr();
+ GPRReg baseGPR = base.gpr();
GPRReg stringImplGPR = stringImpl.gpr();
GPRReg stringDataGPR = stringData.gpr();
GPRReg outputGPR = output.gpr();
GPRReg strLengthGPR = strLength.gpr();
- GPRReg result2GPR = result2.gpr();
GPRReg temp0GPR = temp0.gpr();
GPRReg temp1GPR = temp1.gpr();
GPRReg temp2GPR = InvalidGPRReg;
- GPRReg swapReg = InvalidGPRReg;
auto jitCodeBlock = regExp->getRegExpJITCodeBlock();
ASSERT(jitCodeBlock);
@@ -2732,44 +2728,31 @@
#if !CPU(X86_64)
if (inlineCodeStats8Bit.needsTemp2()) {
- GPRTemporary realTemp2(this);
- temp2.adopt(realTemp2);
- temp2GPR = temp2.gpr();
+ temp2.emplace(this);
+ temp2GPR = temp2->gpr();
}
#endif
speculateRegExpObject(node->child2(), baseGPR);
- MacroAssembler::JumpList done;
- MacroAssembler::JumpList operationCases;
+ CCallHelpers::JumpList slowCases;
- auto swapRegIfNeeded = [&] {
- if (globalObjectGPR == resultGPR) {
- swapReg = allocate();
- m_jit.move(globalObjectGPR, swapReg);
- globalObjectGPR = swapReg;
- } else if (baseGPR == resultGPR) {
- swapReg = allocate();
- m_jit.move(baseGPR, swapReg);
- baseGPR = swapReg;
- } else if (argumentGPR == resultGPR) {
- swapReg = allocate();
- m_jit.move(argumentGPR, swapReg);
- argumentGPR = swapReg;
- }
- };
+ auto regExpTestInlineCase = [&](GPRReg argumentGPR, CCallHelpers::JumpList& slowCases) {
+ m_jit.loadPtr(MacroAssembler::Address(argumentGPR, JSString::offsetOfValue()), stringImplGPR);
+ // If the string is a rope or 16 bit, we call the operation.
+ slowCases.append(m_jit.branchIfRopeStringImpl(stringImplGPR));
+ slowCases.append(m_jit.branchTest32(
+ MacroAssembler::Zero,
+ MacroAssembler::Address(stringImplGPR, StringImpl::flagsOffset()),
+ TrustedImm32(StringImpl::flagIs8Bit())));
- auto regExpTestInlineCase = [&] {
m_jit.loadPtr(MacroAssembler::Address(stringImplGPR, StringImpl::dataOffset()), stringDataGPR);
m_jit.load32(MacroAssembler::Address(stringImplGPR, StringImpl::lengthMemoryOffset()), strLengthGPR);
- GPRReg indexGPR = stringImplGPR;
-
- m_jit.move(TrustedImm32(0), indexGPR);
-
+ // Clobbering input registers is OK since we already called flushRegisters.
Yarr::YarrJITRegisters yarrRegisters;
yarrRegisters.input = stringDataGPR;
- yarrRegisters.index = indexGPR;
+ yarrRegisters.index = stringImplGPR;
yarrRegisters.length = strLengthGPR;
yarrRegisters.output = outputGPR;
yarrRegisters.regT0 = temp0GPR;
@@ -2780,20 +2763,20 @@
if (inlineCodeStats8Bit.needsTemp2())
yarrRegisters.regT2 = temp2GPR;
- yarrRegisters.returnRegister = resultGPR;
- yarrRegisters.returnRegister2 = result2GPR;
+ yarrRegisters.returnRegister = temp0GPR;
+ yarrRegisters.returnRegister2 = stringDataGPR;
auto commonData = m_jit.jitCode()->dfgCommon();
+ m_jit.move(TrustedImm32(0), yarrRegisters.index);
Yarr::jitCompileInlinedTest(&m_graph.m_stackChecker, regExp->pattern(), regExp->flags(), Yarr::CharSize::Char8, &vm(), commonData->m_boyerMooreData, m_jit, yarrRegisters);
- auto failedMatch = m_jit.branch32(MacroAssembler::LessThan, resultGPR, TrustedImm32(0));
+ auto failedMatch = m_jit.branch32(MacroAssembler::LessThan, yarrRegisters.returnRegister, TrustedImm32(0));
// Saved cached result
#if CPU(X86_64)
if (inlineCodeStats8Bit.needsTemp2()) {
// Since we reused globalObjectGPR for temp2, let's restore the global object.
- JSGlobalObject* globalObjectConst = jsCast<JSGlobalObject*>(node->cellOperand()->value());
- m_jit.move(CCallHelpers::TrustedImmPtr(globalObjectConst), globalObjectGPR);
+ m_jit.move(TrustedImmPtr::weakPointer(m_graph, jsCast<JSGlobalObject*>(node->cellOperand()->value())), globalObjectGPR);
}
#endif
@@ -2801,80 +2784,56 @@
m_jit.storePtr(TrustedImmPtr::weakPointer(m_graph, regExp), JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfLastRegExp()));
m_jit.storePtr(argumentGPR, JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfLastInput()));
- m_jit.store32(resultGPR, JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, start)));
- m_jit.store32(result2GPR, JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, end)));
+ m_jit.store32(yarrRegisters.returnRegister, JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, start)));
+ m_jit.store32(yarrRegisters.returnRegister2, JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, end)));
m_jit.store8(TrustedImm32(0), JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfReified()));
- if (swapReg != InvalidGPRReg)
- unlock(swapReg);
+ CCallHelpers::JumpList doneCases;
- m_jit.move(TrustedImm32(1), resultGPR);
- done.append(m_jit.jump());
+ m_jit.move(TrustedImm32(1), temp0GPR);
+ doneCases.append(m_jit.jump());
failedMatch.link(&m_jit);
- m_jit.move(TrustedImm32(0), resultGPR);
- done.append(m_jit.jump());
+ m_jit.move(TrustedImm32(0), temp0GPR);
+ doneCases.append(m_jit.jump());
+
+ return doneCases;
};
if (node->child3().useKind() == StringUse) {
SpeculateCellOperand argument(this, node->child3());
- argumentGPR = argument.gpr();
+ GPRReg argumentGPR = argument.gpr();
speculateString(node->child3(), argumentGPR);
flushRegisters();
- swapRegIfNeeded();
+ auto doneCases = regExpTestInlineCase(argumentGPR, slowCases);
- m_jit.loadPtr(MacroAssembler::Address(argumentGPR, JSString::offsetOfValue()), stringImplGPR);
- // If the string is a rope or 16 bit, we call the operation.
- operationCases.append(m_jit.branchIfRopeStringImpl(stringImplGPR));
- operationCases.append(m_jit.branchTest32(
- MacroAssembler::Zero,
- MacroAssembler::Address(stringImplGPR, StringImpl::flagsOffset()),
- TrustedImm32(StringImpl::flagIs8Bit())));
-
- regExpTestInlineCase();
-
- operationCases.link(&m_jit);
-
- callOperation(operationRegExpTestString, resultGPR, globalObjectGPR, baseGPR, argumentGPR);
-
+ slowCases.link(&m_jit);
+ callOperation(operationRegExpTestString, temp0GPR, globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
- done.link(&m_jit);
- unblessedBooleanResult(resultGPR, node);
-
+ doneCases.link(&m_jit);
+ unblessedBooleanResult(temp0GPR, node);
return;
}
JSValueOperand argument(this, node->child3());
- argumentGPR = argument.gpr();
+ GPRReg argumentGPR = argument.gpr();
flushRegisters();
- swapRegIfNeeded();
+ slowCases.append(m_jit.branchIfNotCell(argumentGPR));
+ slowCases.append(m_jit.branchIfNotString(argumentGPR));
- operationCases.append(m_jit.branchIfNotCell(argumentGPR));
- operationCases.append(m_jit.branchIfNotString(argumentGPR));
+ auto doneCases = regExpTestInlineCase(argumentGPR, slowCases);
- m_jit.loadPtr(MacroAssembler::Address(argumentGPR, JSString::offsetOfValue()), stringImplGPR);
- // If the string is a rope or 16 bit, we call the operation.
- operationCases.append(m_jit.branchIfRopeStringImpl(stringImplGPR));
- operationCases.append(m_jit.branchTest32(
- MacroAssembler::Zero,
- MacroAssembler::Address(stringImplGPR, StringImpl::flagsOffset()),
- TrustedImm32(StringImpl::flagIs8Bit())));
-
- regExpTestInlineCase();
-
- operationCases.link(&m_jit);
-
- callOperation(operationRegExpTest, resultGPR, globalObjectGPR, baseGPR, argumentGPR);
-
- done.link(&m_jit);
+ slowCases.link(&m_jit);
+ callOperation(operationRegExpTest, temp0GPR, globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
- unblessedBooleanResult(resultGPR, node);
+ doneCases.link(&m_jit);
+ unblessedBooleanResult(temp0GPR, node);
}
#else
void SpeculativeJIT::compileRegExpTestInline(Node* node)
Modified: trunk/Source/_javascript_Core/yarr/YarrJIT.cpp (291514 => 291515)
--- trunk/Source/_javascript_Core/yarr/YarrJIT.cpp 2022-03-19 00:46:37 UTC (rev 291514)
+++ trunk/Source/_javascript_Core/yarr/YarrJIT.cpp 2022-03-19 00:55:48 UTC (rev 291515)
@@ -2443,6 +2443,7 @@
// slot, and return. In the case of pattern with a fixed size, we will
// not have yet set the value in the first
ASSERT(m_regs.index != m_regs.returnRegister);
+ ASSERT(m_regs.output != m_regs.returnRegister);
if (m_pattern.m_body->m_hasFixedSize) {
if (priorAlternative->m_minimumSize)
m_jit.sub32(m_regs.index, MacroAssembler::Imm32(priorAlternative->m_minimumSize), m_regs.returnRegister);
@@ -4033,6 +4034,7 @@
#if CPU(X86_64)
#if OS(WINDOWS)
// Store the return value in the allocated space pointed by rcx.
+ ASSERT(noOverlap(X86Registers::ecx, m_regs.returnRegister, m_regs.returnRegister2));
m_jit.pop(X86Registers::ecx);
m_jit.store64(m_regs.returnRegister, MacroAssembler::Address(X86Registers::ecx));
m_jit.store64(m_regs.returnRegister2, MacroAssembler::Address(X86Registers::ecx, sizeof(void*)));
@@ -4750,6 +4752,8 @@
Yarr::ErrorCode errorCode;
Yarr::YarrPattern pattern(patternString, flags, errorCode);
+ jitRegisters.validate();
+
YarrGenerator<YarrJITRegisters> yarrGenerator(jit, vm, &boyerMooreData, jitRegisters, pattern, patternString, charSize, JITCompileMode::InlineTest);
yarrGenerator.setStackChecker(m_compilationThreadStackChecker);
yarrGenerator.compileInline(boyerMooreData);
Modified: trunk/Source/_javascript_Core/yarr/YarrJITRegisters.h (291514 => 291515)
--- trunk/Source/_javascript_Core/yarr/YarrJITRegisters.h 2022-03-19 00:46:37 UTC (rev 291514)
+++ trunk/Source/_javascript_Core/yarr/YarrJITRegisters.h 2022-03-19 00:55:48 UTC (rev 291515)
@@ -175,8 +175,30 @@
#if ENABLE(YARR_JIT_REGEXP_TEST_INLINE)
class YarrJITRegisters {
public:
- YarrJITRegisters()
+ YarrJITRegisters() = default;
+
+ void validate()
{
+#if ASSERT_ENABLED
+ ASSERT(input != InvalidGPRReg);
+ ASSERT(index != InvalidGPRReg);
+ ASSERT(length != InvalidGPRReg);
+ ASSERT(output != InvalidGPRReg);
+
+ ASSERT(returnRegister != InvalidGPRReg);
+ ASSERT(returnRegister2 != InvalidGPRReg);
+
+ ASSERT(regT0 != InvalidGPRReg);
+ ASSERT(regT1 != InvalidGPRReg);
+
+ ASSERT(noOverlap(input, index, length, output, regT0, regT1));
+ ASSERT(noOverlap(returnRegister, returnRegister2));
+ ASSERT(noOverlap(index, output, returnRegister));
+
+#if CPU(X86_64) && OS(WINDOWS)
+ ASSERT(noOverlap(X86Registers::ecx, returnRegister, m_regs.returnRegister2));
+#endif
+#endif
}
// Argument registers
@@ -184,6 +206,7 @@
GPRReg index { InvalidGPRReg };
GPRReg length { InvalidGPRReg };
GPRReg output { InvalidGPRReg };
+
GPRReg matchingContext { InvalidGPRReg };
GPRReg freelistRegister { InvalidGPRReg };
GPRReg freelistSizeRegister { InvalidGPRReg };