Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (291874 => 291875)
--- trunk/Source/_javascript_Core/ChangeLog 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-03-25 19:08:48 UTC (rev 291875)
@@ -1,3 +1,54 @@
+2022-03-24 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Use Data CallIC in unlinked DFG
+ https://bugs.webkit.org/show_bug.cgi?id=238176
+
+ Reviewed by Saam Barati.
+
+ This patch enables Data CallIC when Options::useDataICInOptimizingJIT() is true
+ to pave the way to introducing unlinked DFG.
+
+ The most complicated part is DFG tail call handling. We load CallLinkInfo in one
+ non-callee-save register, and we set up CallFrameShuffleData to keep this value
+ in the same register even after call frame shuffling for the tail call. This must
+ be non-callee-save register since callee-save registers are restored to values
+ of the one-level upper caller for the tail-call.
+
+ We also clean up CallLinkInfo code so that many functions work well with DataIC.
+ Currently, direct calls are not supported, and we will not emit direct calls when
+ unlinked DFG is used.
+
+ * bytecode/AccessCase.cpp:
+ (JSC::AccessCase::generateImpl):
+ * bytecode/CallLinkInfo.cpp:
+ (JSC::BaselineCallLinkInfo::initialize):
+ (JSC::OptimizingCallLinkInfo::emitFastPath):
+ (JSC::OptimizingCallLinkInfo::emitTailCallFastPath):
+ (JSC::OptimizingCallLinkInfo::slowPathStart):
+ (JSC::OptimizingCallLinkInfo::emitDirectFastPath):
+ (JSC::OptimizingCallLinkInfo::emitDirectTailCallFastPath):
+ * bytecode/CallLinkInfo.h:
+ (JSC::CallLinkInfo::isDataIC const):
+ (JSC::CallLinkInfo::useDataIC const):
+ (JSC::CallLinkInfo::CallLinkInfo):
+ (JSC::CallLinkInfo::setUsesDataICs): Deleted.
+ * bytecode/Repatch.cpp:
+ (JSC::linkPolymorphicCall):
+ * dfg/DFGCommonData.h:
+ (JSC::DFG::CommonData::addCallLinkInfo):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ * dfg/DFGStrengthReductionPhase.cpp:
+ (JSC::DFG::StrengthReductionPhase::handleNode):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+ * jit/CCallHelpers.h:
+ (JSC::CCallHelpers::prepareForTailCallSlow):
+ * wasm/js/WasmToJS.cpp:
+ (JSC::Wasm::wasmToJS):
+
2022-03-25 Keith Miller <keith_mil...@apple.com>
Remove unused JITOperation, operationTryOSREnterAtCatch.
Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -1999,7 +1999,7 @@
state.setSpillStateForJSGetterSetter(spillState);
RELEASE_ASSERT(!access.callLinkInfo());
- auto* callLinkInfo = state.m_callLinkInfos.add(stubInfo.codeOrigin);
+ auto* callLinkInfo = state.m_callLinkInfos.add(stubInfo.codeOrigin, codeBlock->useDataIC() ? CallLinkInfo::UseDataIC::Yes : CallLinkInfo::UseDataIC::No);
access.m_callLinkInfo = callLinkInfo;
// FIXME: If we generated a polymorphic call stub that jumped back to the getter
@@ -2074,7 +2074,7 @@
virtualRegisterForArgumentIncludingThis(1).offset() * sizeof(Register)));
}
- auto slowCase = access.callLinkInfo()->emitFastPath(jit, loadedValueGPR, loadedValueGPR == GPRInfo::regT2 ? GPRInfo::regT0 : GPRInfo::regT2, JITCode::isOptimizingJIT(codeBlock->jitType()) ? CallLinkInfo::UseDataIC::No : CallLinkInfo::UseDataIC::Yes);
+ auto slowCase = access.callLinkInfo()->emitFastPath(jit, loadedValueGPR, loadedValueGPR == GPRInfo::regT2 ? GPRInfo::regT0 : GPRInfo::regT2);
auto doneLocation = jit.label();
if (m_type == Getter)
Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -314,6 +314,8 @@
UNUSED_PARAM(frameShuffleData);
m_type = static_cast<unsigned>(Type::Baseline);
ASSERT(Type::Baseline == type());
+ m_useDataIC = static_cast<unsigned>(UseDataIC::Yes);
+ ASSERT(UseDataIC::Yes == useDataIC());
m_codeOrigin = CodeOrigin(bytecodeIndex);
m_callType = callType;
#if ENABLE(JIT)
@@ -322,7 +324,6 @@
m_frameShuffleData = makeUnique<CallFrameShuffleData>(*frameShuffleData);
}
#endif
- setUsesDataICs(UseDataIC::Yes);
setSlowPathCallDestination(vm.getCTILinkCall().code());
// If JIT is disabled, we should not support dynamically generated call IC.
if (!Options::useJIT())
@@ -424,10 +425,9 @@
jit.call(CCallHelpers::Address(GPRInfo::regT2, offsetOfSlowPathCallDestination()), JSEntryPtrTag);
}
-CCallHelpers::JumpList OptimizingCallLinkInfo::emitFastPath(CCallHelpers& jit, GPRReg calleeGPR, GPRReg callLinkInfoGPR, UseDataIC useDataIC)
+CCallHelpers::JumpList OptimizingCallLinkInfo::emitFastPath(CCallHelpers& jit, GPRReg calleeGPR, GPRReg callLinkInfoGPR)
{
RELEASE_ASSERT(!isTailCall());
- setUsesDataICs(useDataIC);
if (isDataIC()) {
RELEASE_ASSERT(callLinkInfoGPR != GPRReg::InvalidGPRReg);
@@ -435,15 +435,22 @@
setCallLinkInfoGPR(callLinkInfoGPR);
}
- return emitFastPathImpl(this, jit, calleeGPR, callLinkInfoGPR, useDataIC, isTailCall(), nullptr);
+ return emitFastPathImpl(this, jit, calleeGPR, callLinkInfoGPR, useDataIC(), isTailCall(), nullptr);
}
-MacroAssembler::JumpList OptimizingCallLinkInfo::emitTailCallFastPath(CCallHelpers& jit, GPRReg calleeGPR, ScopedLambda<void()>&& prepareForTailCall)
+MacroAssembler::JumpList OptimizingCallLinkInfo::emitTailCallFastPath(CCallHelpers& jit, GPRReg calleeGPR, GPRReg callLinkInfoGPR, ScopedLambda<void()>&& prepareForTailCall)
{
RELEASE_ASSERT(isTailCall());
- setUsesDataICs(UseDataIC::No);
- return emitFastPathImpl(this, jit, calleeGPR, InvalidGPRReg, UseDataIC::No, isTailCall(), WTFMove(prepareForTailCall));
+
+ if (isDataIC()) {
+ RELEASE_ASSERT(callLinkInfoGPR != GPRReg::InvalidGPRReg);
+ jit.move(CCallHelpers::TrustedImmPtr(this), callLinkInfoGPR);
+ setCallLinkInfoGPR(callLinkInfoGPR);
+ }
+
+ return emitFastPathImpl(this, jit, calleeGPR, callLinkInfoGPR, useDataIC(), isTailCall(), WTFMove(prepareForTailCall));
}
+
void OptimizingCallLinkInfo::emitSlowPath(VM& vm, CCallHelpers& jit)
{
setSlowPathCallDestination(vm.getCTILinkCall().code());
@@ -453,7 +460,7 @@
CodeLocationLabel<JSInternalPtrTag> OptimizingCallLinkInfo::slowPathStart()
{
- RELEASE_ASSERT(!isDataIC());
+ RELEASE_ASSERT(isDirect() && !isDataIC());
return m_slowPathStart;
}
@@ -465,9 +472,9 @@
void OptimizingCallLinkInfo::emitDirectFastPath(CCallHelpers& jit)
{
- RELEASE_ASSERT(!isTailCall());
+ RELEASE_ASSERT(isDirect() && !isTailCall());
- setUsesDataICs(UseDataIC::No);
+ ASSERT(UseDataIC::No == this->useDataIC());
auto call = jit.nearCall();
jit.addLinkTask([=, this] (LinkBuffer& linkBuffer) {
@@ -480,9 +487,9 @@
void OptimizingCallLinkInfo::emitDirectTailCallFastPath(CCallHelpers& jit, ScopedLambda<void()>&& prepareForTailCall)
{
- RELEASE_ASSERT(isTailCall());
+ RELEASE_ASSERT(isDirect() && isTailCall());
- setUsesDataICs(UseDataIC::No);
+ ASSERT(UseDataIC::No == this->useDataIC());
auto fastPathStart = jit.label();
jit.addLinkTask([=, this] (LinkBuffer& linkBuffer) {
Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h (291874 => 291875)
--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h 2022-03-25 19:08:48 UTC (rev 291875)
@@ -187,8 +187,8 @@
void revertCallToStub();
- bool isDataIC() const { return static_cast<UseDataIC>(m_useDataIC) == UseDataIC::Yes; }
- void setUsesDataICs(UseDataIC useDataIC) { m_useDataIC = static_cast<unsigned>(useDataIC); }
+ bool isDataIC() const { return useDataIC() == UseDataIC::Yes; }
+ UseDataIC useDataIC() const { return static_cast<UseDataIC>(m_useDataIC); }
bool allowStubs() const { return m_allowStubs; }
@@ -376,7 +376,7 @@
Type type() const { return static_cast<Type>(m_type); }
protected:
- CallLinkInfo(Type type, CodeOrigin codeOrigin)
+ CallLinkInfo(Type type, CodeOrigin codeOrigin, UseDataIC useDataIC)
: m_codeOrigin(codeOrigin)
, m_hasSeenShouldRepatch(false)
, m_hasSeenClosure(false)
@@ -385,17 +385,13 @@
, m_allowStubs(true)
, m_clearedByJettison(false)
, m_callType(None)
- , m_useDataIC(static_cast<unsigned>(UseDataIC::Yes))
+ , m_useDataIC(static_cast<unsigned>(useDataIC))
, m_type(static_cast<unsigned>(type))
{
ASSERT(type == this->type());
+ ASSERT(useDataIC == this->useDataIC());
}
- CallLinkInfo(Type type)
- : CallLinkInfo(type, CodeOrigin { })
- {
- }
-
#if ENABLE(JIT)
void setCallLinkInfoGPR(GPRReg);
#endif
@@ -443,7 +439,7 @@
class BaselineCallLinkInfo final : public CallLinkInfo {
public:
BaselineCallLinkInfo()
- : CallLinkInfo(Type::Baseline)
+ : CallLinkInfo(Type::Baseline, CodeOrigin { }, UseDataIC::Yes)
{
}
@@ -477,8 +473,8 @@
public:
friend class CallLinkInfo;
- OptimizingCallLinkInfo(CodeOrigin codeOrigin)
- : CallLinkInfo(Type::Optimizing, codeOrigin)
+ OptimizingCallLinkInfo(CodeOrigin codeOrigin, UseDataIC useDataIC)
+ : CallLinkInfo(Type::Optimizing, codeOrigin, useDataIC)
{
}
@@ -510,8 +506,8 @@
void setDirectCallTarget(CodeLocationLabel<JSEntryPtrTag>);
void emitSlowPath(VM&, CCallHelpers&);
- MacroAssembler::JumpList emitFastPath(CCallHelpers&, GPRReg calleeGPR, GPRReg callLinkInfoGPR, UseDataIC) WARN_UNUSED_RETURN;
- MacroAssembler::JumpList emitTailCallFastPath(CCallHelpers&, GPRReg calleeGPR, ScopedLambda<void()>&& prepareForTailCall) WARN_UNUSED_RETURN;
+ MacroAssembler::JumpList emitFastPath(CCallHelpers&, GPRReg calleeGPR, GPRReg callLinkInfoGPR) WARN_UNUSED_RETURN;
+ MacroAssembler::JumpList emitTailCallFastPath(CCallHelpers&, GPRReg calleeGPR, GPRReg callLinkInfoGPR, ScopedLambda<void()>&& prepareForTailCall) WARN_UNUSED_RETURN;
private:
CodeLocationNearCall<JSInternalPtrTag> m_callLocation;
Modified: trunk/Source/_javascript_Core/bytecode/Repatch.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/bytecode/Repatch.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/bytecode/Repatch.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -1861,15 +1861,33 @@
} else {
// FIXME: We are not doing a real tail-call in this case. We leave stack entries in the caller, and we are not running prepareForTailCall, thus,
// we will return to the caller after the callee finishes. We should make it a real tail-call for this slow path case.
- if (callLinkInfo.isTailCall()) {
+ switch (callLinkInfo.type()) {
+ case CallLinkInfo::Type::Baseline: {
#if ASSERT_ENABLED
// It needs to be LLInt or Baseline since we are using returnFromBaselineGenerator.
if (!isWebAssembly)
ASSERT(!JITCode::isOptimizingJIT(callerCodeBlock->jitType()));
#endif
- stubJit.move(CCallHelpers::TrustedImmPtr(vm.getCTIStub(JIT::returnFromBaselineGenerator).code().untaggedExecutableAddress()), GPRInfo::regT4);
+ if (callLinkInfo.isTailCall()) {
+ stubJit.move(CCallHelpers::TrustedImmPtr(vm.getCTIStub(JIT::returnFromBaselineGenerator).code().untaggedExecutableAddress()), GPRInfo::regT4);
+ stubJit.restoreReturnAddressBeforeReturn(GPRInfo::regT4);
+ }
+ break;
+ }
+ case CallLinkInfo::Type::Optimizing: {
+ // While Baseline / LLInt shares BaselineCallLinkInfo, OptimizingCallLinkInfo is exclusively used for one JIT code.
+ // Thus, we can safely use doneLocation.
+ if (!callLinkInfo.isTailCall()) {
+ // We were called from the fast path, get rid of any remnants of that
+ // which may exist. This really only matters for x86, which adjusts
+ // SP for calls.
+ stubJit.preserveReturnAddressAfterCall(GPRInfo::regT4);
+ }
+ stubJit.move(CCallHelpers::TrustedImmPtr(callLinkInfo.doneLocation().untaggedExecutableAddress()), GPRInfo::regT4);
stubJit.restoreReturnAddressBeforeReturn(GPRInfo::regT4);
+ break;
}
+ }
}
AssemblyHelpers::Jump slow = stubJit.jump();
Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.h (291874 => 291875)
--- trunk/Source/_javascript_Core/dfg/DFGCommonData.h 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.h 2022-03-25 19:08:48 UTC (rev 291875)
@@ -111,9 +111,9 @@
void clearWatchpoints();
- OptimizingCallLinkInfo* addCallLinkInfo(CodeOrigin codeOrigin)
+ OptimizingCallLinkInfo* addCallLinkInfo(CodeOrigin codeOrigin, CallLinkInfo::UseDataIC useDataIC = CallLinkInfo::UseDataIC::No)
{
- return m_callLinkInfos.add(codeOrigin);
+ return m_callLinkInfos.add(codeOrigin, useDataIC);
}
RefPtr<InlineCallFrameSet> inlineCallFrames;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -783,7 +783,7 @@
isEmulatedTail ? *staticInlineCallFrame->getCallerSkippingTailCalls() : staticOrigin;
CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(dynamicOrigin, m_stream->size());
- auto* info = m_jit.jitCode()->common.addCallLinkInfo(node->origin.semantic);
+ auto* info = m_jit.jitCode()->common.addCallLinkInfo(node->origin.semantic, CallLinkInfo::UseDataIC::No);
info->setUpCall(callType, calleePayloadGPR);
auto setResultAndResetStack = [&] () {
@@ -825,7 +825,10 @@
// This is the part where we meant to make a normal call. Oops.
m_jit.addPtr(TrustedImm32(requiredBytes), JITCompiler::stackPointerRegister);
m_jit.loadValue(JITCompiler::calleeFrameSlot(CallFrameSlot::callee), JSValueRegs { GPRInfo::regT1, GPRInfo::regT0 });
- m_jit.emitVirtualCall(vm(), globalObject, info);
+ m_jit.move(TrustedImmPtr(info), GPRInfo::regT2);
+ m_jit.move(TrustedImmPtr::weakPointer(m_graph, globalObject), GPRInfo::regT3);
+ m_jit.emitVirtualCallWithoutMovingGlobalObject(vm(), GPRInfo::regT2, CallMode::Regular);
+ ASSERT(info->callMode() == CallMode::Regular);
done.link(&m_jit);
setResultAndResetStack();
@@ -888,7 +891,7 @@
CCallHelpers::JumpList slowCases;
if (isTail) {
- slowCases = info->emitTailCallFastPath(m_jit, calleePayloadGPR, scopedLambda<void()>([&]{
+ slowCases = info->emitTailCallFastPath(m_jit, calleePayloadGPR, InvalidGPRReg, scopedLambda<void()>([&]{
if (node->op() == TailCall) {
info->setFrameShuffleData(shuffleData);
CallFrameShuffler(m_jit, shuffleData).prepareForTailCall();
@@ -898,7 +901,7 @@
}
}));
} else
- slowCases = info->emitFastPath(m_jit, calleePayloadGPR, InvalidGPRReg, CallLinkInfo::UseDataIC::No);
+ slowCases = info->emitFastPath(m_jit, calleePayloadGPR, InvalidGPRReg);
JITCompiler::Jump done = m_jit.jump();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -696,6 +696,7 @@
}
GPRReg calleeGPR = InvalidGPRReg;
+ GPRReg callLinkInfoGPR = InvalidGPRReg;
CallFrameShuffleData shuffleData;
JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
@@ -708,6 +709,8 @@
unsigned numPassedArgs = 0;
unsigned numAllocatedArgs = 0;
+
+ auto* callLinkInfo = m_jit.jitCode()->common.addCallLinkInfo(m_currentNode->origin.semantic, JITCode::useDataIC(JITType::DFGJIT) ? CallLinkInfo::UseDataIC::Yes : CallLinkInfo::UseDataIC::No);
// Gotta load the arguments somehow. Varargs is trickier.
if (isVarargs || isForwardVarargs) {
@@ -825,6 +828,17 @@
Edge calleeEdge = m_jit.graph().child(node, 0);
JSValueOperand callee(this, calleeEdge);
calleeGPR = callee.gpr();
+
+ // callLinkInfoGPR must be non callee-save register. Otherwise, tail-call preparation will fill it
+ // with saved callee-save. Also, it should not be the same to calleeGPR and regT0 since both will
+ // be used later differently.
+ // We also do not keep GPRTemporary (it is immediately destroyed) because
+ // 1. We do not want to keep the register locked in the following sequence of the Call.
+ // 2. This must be the last register allocation from DFG register bank, so it is OK (otherwise, callee.use() is wrong).
+ if (callLinkInfo->isDataIC()) {
+ GPRTemporary callLinkInfoTemp(this, JITCompiler::selectScratchGPR(calleeGPR, GPRInfo::regT0));
+ callLinkInfoGPR = callLinkInfoTemp.gpr();
+ }
if (!isDirect)
callee.use();
@@ -846,6 +860,8 @@
for (unsigned i = numPassedArgs; i < numAllocatedArgs; ++i)
shuffleData.args[i] = ValueRecovery::constant(jsUndefined());
+ if (callLinkInfo->isDataIC())
+ shuffleData.registers[callLinkInfoGPR] = ValueRecovery::inGPR(callLinkInfoGPR, DataFormatJS);
shuffleData.setupCalleeSaveRegisters(&RegisterAtOffsetList::dfgCalleeSaveRegisters());
} else {
m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), JITCompiler::calleeFramePayloadSlot(CallFrameSlot::argumentCountIncludingThis));
@@ -868,6 +884,18 @@
Edge calleeEdge = m_jit.graph().child(node, 0);
JSValueOperand callee(this, calleeEdge);
calleeGPR = callee.gpr();
+
+ // callLinkInfoGPR must be non callee-save register. Otherwise, tail-call preparation will fill it
+ // with saved callee-save. Also, it should not be the same to calleeGPR and regT0 since both will
+ // be used later differently.
+ // We also do not keep GPRTemporary (it is immediately destroyed) because
+ // 1. We do not want to keep the register locked in the following sequence of the Call.
+ // 2. This must be the last register allocation from DFG register bank, so it is OK (otherwise, callee.use() is wrong).
+ if (callLinkInfo->isDataIC()) {
+ GPRTemporary callLinkInfoTemp(this, JITCompiler::selectScratchGPR(calleeGPR, GPRInfo::regT0));
+ callLinkInfoGPR = callLinkInfoTemp.gpr();
+ }
+
callee.use();
m_jit.store64(calleeGPR, JITCompiler::calleeFrameSlot(CallFrameSlot::callee));
@@ -896,7 +924,6 @@
m_jit.addPtr(TrustedImm32(m_jit.graph().stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, JITCompiler::stackPointerRegister);
};
- auto* callLinkInfo = m_jit.jitCode()->common.addCallLinkInfo(m_currentNode->origin.semantic);
callLinkInfo->setUpCall(callType, calleeGPR);
if (node->op() == CallEval) {
@@ -925,7 +952,10 @@
// This is the part where we meant to make a normal call. Oops.
m_jit.addPtr(TrustedImm32(requiredBytes), JITCompiler::stackPointerRegister);
m_jit.load64(JITCompiler::calleeFrameSlot(CallFrameSlot::callee), GPRInfo::regT0);
- m_jit.emitVirtualCall(vm(), globalObject, callLinkInfo);
+ m_jit.move(TrustedImmPtr(callLinkInfo), GPRInfo::regT2);
+ m_jit.move(TrustedImmPtr::weakPointer(m_graph, globalObject), GPRInfo::regT3);
+ m_jit.emitVirtualCallWithoutMovingGlobalObject(vm(), GPRInfo::regT2, CallMode::Regular);
+ ASSERT(callLinkInfo->callMode() == CallMode::Regular);
done.link(&m_jit);
setResultAndResetStack();
@@ -985,17 +1015,17 @@
CCallHelpers::JumpList slowCases;
if (isTail) {
- slowCases = callLinkInfo->emitTailCallFastPath(m_jit, calleeGPR, scopedLambda<void()>([&]{
+ slowCases = callLinkInfo->emitTailCallFastPath(m_jit, calleeGPR, callLinkInfoGPR, scopedLambda<void()>([&]{
if (node->op() == TailCall) {
callLinkInfo->setFrameShuffleData(shuffleData);
CallFrameShuffler(m_jit, shuffleData).prepareForTailCall();
} else {
m_jit.emitRestoreCalleeSaves();
- m_jit.prepareForTailCallSlow();
+ m_jit.prepareForTailCallSlow(callLinkInfoGPR);
}
}));
} else
- slowCases = callLinkInfo->emitFastPath(m_jit, calleeGPR, InvalidGPRReg, CallLinkInfo::UseDataIC::No);
+ slowCases = callLinkInfo->emitFastPath(m_jit, calleeGPR, callLinkInfoGPR);
JITCompiler::Jump done = m_jit.jump();
slowCases.link(&m_jit);
Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -1021,6 +1021,12 @@
if (!executable)
break;
+ if (m_graph.m_plan.isUnlinked())
+ break;
+
+ if (JITCode::useDataIC(m_graph.m_plan.isFTL() ? JITType::FTLJIT : JITType::DFGJIT))
+ break;
+
// FIXME: Support wasm IC.
// DirectCall to wasm function has suboptimal implementation. We avoid using DirectCall if we know that function is a wasm function.
// https://bugs.webkit.org/show_bug.cgi?id=220339
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -10282,7 +10282,7 @@
callLinkInfo->setUpCall(
nodeOp == Construct ? CallLinkInfo::Construct : CallLinkInfo::Call, GPRInfo::regT0);
- auto slowPath = callLinkInfo->emitFastPath(jit, GPRInfo::regT0, InvalidGPRReg, CallLinkInfo::UseDataIC::No);
+ auto slowPath = callLinkInfo->emitFastPath(jit, GPRInfo::regT0, InvalidGPRReg);
CCallHelpers::Jump done = jit.jump();
slowPath.link(&jit);
@@ -10575,7 +10575,7 @@
auto* callLinkInfo = state->jitCode->common.addCallLinkInfo(codeOrigin);
callLinkInfo->setUpCall(CallLinkInfo::TailCall, GPRInfo::regT0);
- auto slowPath = callLinkInfo->emitTailCallFastPath(jit, GPRInfo::regT0, scopedLambda<void()>([&]{
+ auto slowPath = callLinkInfo->emitTailCallFastPath(jit, GPRInfo::regT0, InvalidGPRReg, scopedLambda<void()>([&]{
callLinkInfo->setFrameShuffleData(shuffleData);
CallFrameShuffler(jit, shuffleData).prepareForTailCall();
}));
@@ -10918,12 +10918,12 @@
CCallHelpers::JumpList slowPath;
CCallHelpers::Jump done;
if (isTailCall) {
- slowPath = callLinkInfo->emitTailCallFastPath(jit, GPRInfo::regT0, scopedLambda<void()>([&]{
+ slowPath = callLinkInfo->emitTailCallFastPath(jit, GPRInfo::regT0, InvalidGPRReg, scopedLambda<void()>([&]{
jit.emitRestoreCalleeSavesFor(state->jitCode->calleeSaveRegisters());
jit.prepareForTailCallSlow();
}));
} else {
- slowPath = callLinkInfo->emitFastPath(jit, GPRInfo::regT0, InvalidGPRReg, CallLinkInfo::UseDataIC::No);
+ slowPath = callLinkInfo->emitFastPath(jit, GPRInfo::regT0, InvalidGPRReg);
done = jit.jump();
}
@@ -11199,12 +11199,12 @@
CCallHelpers::JumpList slowPath;
CCallHelpers::Jump done;
if (isTailCall) {
- slowPath = callLinkInfo->emitTailCallFastPath(jit, GPRInfo::regT0, scopedLambda<void()>([&]{
+ slowPath = callLinkInfo->emitTailCallFastPath(jit, GPRInfo::regT0, InvalidGPRReg, scopedLambda<void()>([&]{
jit.emitRestoreCalleeSavesFor(state->jitCode->calleeSaveRegisters());
jit.prepareForTailCallSlow();
}));
} else {
- slowPath = callLinkInfo->emitFastPath(jit, GPRInfo::regT0, InvalidGPRReg, CallLinkInfo::UseDataIC::No);
+ slowPath = callLinkInfo->emitFastPath(jit, GPRInfo::regT0, InvalidGPRReg);
done = jit.jump();
}
Modified: trunk/Source/_javascript_Core/jit/CCallHelpers.h (291874 => 291875)
--- trunk/Source/_javascript_Core/jit/CCallHelpers.h 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/jit/CCallHelpers.h 2022-03-25 19:08:48 UTC (rev 291875)
@@ -744,11 +744,11 @@
farJump(GPRInfo::regT1, ExceptionHandlerPtrTag);
}
- void prepareForTailCallSlow(GPRReg calleeGPR = InvalidGPRReg)
+ void prepareForTailCallSlow(GPRReg preservedGPR = InvalidGPRReg)
{
- GPRReg temp1 = calleeGPR == GPRInfo::regT0 ? GPRInfo::regT3 : GPRInfo::regT0;
- GPRReg temp2 = calleeGPR == GPRInfo::regT1 ? GPRInfo::regT3 : GPRInfo::regT1;
- GPRReg temp3 = calleeGPR == GPRInfo::regT2 ? GPRInfo::regT3 : GPRInfo::regT2;
+ GPRReg temp1 = preservedGPR == GPRInfo::regT0 ? GPRInfo::regT3 : GPRInfo::regT0;
+ GPRReg temp2 = preservedGPR == GPRInfo::regT1 ? GPRInfo::regT3 : GPRInfo::regT1;
+ GPRReg temp3 = preservedGPR == GPRInfo::regT2 ? GPRInfo::regT3 : GPRInfo::regT2;
GPRReg newFramePointer = temp1;
GPRReg newFrameSizeGPR = temp2;
Modified: trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp (291874 => 291875)
--- trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp 2022-03-25 19:00:11 UTC (rev 291874)
+++ trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp 2022-03-25 19:08:48 UTC (rev 291875)
@@ -261,9 +261,9 @@
// FIXME Tail call if the wasm return type is void and no registers were spilled. https://bugs.webkit.org/show_bug.cgi?id=165488
- auto* callLinkInfo = callLinkInfos.add(CodeOrigin());
+ auto* callLinkInfo = callLinkInfos.add(CodeOrigin(), CallLinkInfo::UseDataIC::No);
callLinkInfo->setUpCall(CallLinkInfo::Call, importJSCellGPRReg);
- auto slowPath = callLinkInfo->emitFastPath(jit, importJSCellGPRReg, InvalidGPRReg, CallLinkInfo::UseDataIC::No);
+ auto slowPath = callLinkInfo->emitFastPath(jit, importJSCellGPRReg, InvalidGPRReg);
JIT::Jump done = jit.jump();
slowPath.link(&jit);