Diff
Modified: branches/safari-612-branch/JSTests/ChangeLog (285541 => 285542)
--- branches/safari-612-branch/JSTests/ChangeLog 2021-11-10 00:29:58 UTC (rev 285541)
+++ branches/safari-612-branch/JSTests/ChangeLog 2021-11-10 00:38:06 UTC (rev 285542)
@@ -1,3 +1,14 @@
+2021-10-25 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Don't branch around register allocation in DFG enumerator get by val
+ https://bugs.webkit.org/show_bug.cgi?id=232260
+ rdar://84544469
+
+ Reviewed by Robin Morisset.
+
+ * stress/dont-branch-around-regalloc-enumerator-get-by-val-float.js: Added.
+ (foo):
+
2021-11-02 Saam Barati <sbar...@apple.com>
EnumeratorGetByVal for IndexedMode+OwnStructureMode doesn't always recover the property name
Added: branches/safari-612-branch/JSTests/stress/dont-branch-around-regalloc-enumerator-get-by-val-float.js (0 => 285542)
--- branches/safari-612-branch/JSTests/stress/dont-branch-around-regalloc-enumerator-get-by-val-float.js (rev 0)
+++ branches/safari-612-branch/JSTests/stress/dont-branch-around-regalloc-enumerator-get-by-val-float.js 2021-11-10 00:38:06 UTC (rev 285542)
@@ -0,0 +1,10 @@
+function foo(o) {
+ for (let p in o) {
+ o[p];
+ }
+}
+
+for (let i = 0; i < 10000; i++) {
+ foo(new Float32Array());
+ foo({o: undefined});
+}
Modified: branches/safari-612-branch/Source/_javascript_Core/ChangeLog (285541 => 285542)
--- branches/safari-612-branch/Source/_javascript_Core/ChangeLog 2021-11-10 00:29:58 UTC (rev 285541)
+++ branches/safari-612-branch/Source/_javascript_Core/ChangeLog 2021-11-10 00:38:06 UTC (rev 285542)
@@ -1,3 +1,28 @@
+2021-10-25 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Don't branch around register allocation in DFG enumerator get by val
+ https://bugs.webkit.org/show_bug.cgi?id=232260
+ rdar://84544469
+
+ Reviewed by Robin Morisset.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithString):
+ (JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithSymbol):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
+ (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+
2021-11-02 Saam Barati <sbar...@apple.com>
EnumeratorGetByVal for IndexedMode+OwnStructureMode doesn't always recover the property name
Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (285541 => 285542)
--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2021-11-10 00:29:58 UTC (rev 285541)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2021-11-10 00:38:06 UTC (rev 285542)
@@ -2593,7 +2593,7 @@
strictInt32Result(scratchReg, m_currentNode);
}
-void SpeculativeJIT::compileGetByValOnString(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByValOnString(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
SpeculateCellOperand base(this, m_graph.child(node, 0));
SpeculateStrictInt32Operand property(this, m_graph.child(node, 1));
@@ -2604,7 +2604,7 @@
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(node->arrayMode().isOutOfBounds() ? DataFormatJS : DataFormatCell);
+ std::tie(resultRegs, format, std::ignore) = prefix(node->arrayMode().isOutOfBounds() ? DataFormatJS : DataFormatCell);
GPRReg scratchReg = resultRegs.payloadGPR();
// unsigned comparison so we can filter out negative indices and indices that are too large
@@ -3388,7 +3388,7 @@
doubleResult(resultFPR, node);
}
-void SpeculativeJIT::compileGetByValOnIntTypedArray(Node* node, TypedArrayType type, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByValOnIntTypedArray(Node* node, TypedArrayType type, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
ASSERT(isInt(type));
@@ -3411,7 +3411,7 @@
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(DataFormatInt32);
+ std::tie(resultRegs, format, std::ignore) = prefix(DataFormatInt32);
bool shouldBox = format == DataFormatJS;
emitTypedArrayBoundsCheck(node, baseReg, propertyReg, scratchGPR);
@@ -3656,7 +3656,7 @@
noResult(node);
}
-void SpeculativeJIT::compileGetByValOnFloatTypedArray(Node* node, TypedArrayType type, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByValOnFloatTypedArray(Node* node, TypedArrayType type, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
ASSERT(isFloat(type));
@@ -3664,18 +3664,18 @@
SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
StorageOperand storage(this, m_graph.varArgChild(node, 2));
GPRTemporary scratch(this);
+ FPRTemporary result(this);
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
GPRReg scratchGPR = scratch.gpr();
+ FPRReg resultReg = result.fpr();
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(DataFormatDouble);
+ std::tie(resultRegs, format, std::ignore) = prefix(DataFormatDouble);
- FPRTemporary result(this);
- FPRReg resultReg = result.fpr();
emitTypedArrayBoundsCheck(node, baseReg, propertyReg, scratchGPR);
switch (elementSize(type)) {
case 4:
@@ -3737,7 +3737,7 @@
noResult(node);
}
-void SpeculativeJIT::compileGetByValForObjectWithString(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByValForObjectWithString(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
SpeculateCellOperand arg1(this, m_graph.varArgChild(node, 0));
SpeculateCellOperand arg2(this, m_graph.varArgChild(node, 1));
@@ -3746,19 +3746,25 @@
GPRReg arg2GPR = arg2.gpr();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ CanUseFlush canUseFlush = CanUseFlush::Yes;
+ std::tie(resultRegs, std::ignore, canUseFlush) = prefix(DataFormatJS);
speculateObject(m_graph.varArgChild(node, 0), arg1GPR);
speculateString(m_graph.varArgChild(node, 1), arg2GPR);
- flushRegisters();
+ if (canUseFlush == CanUseFlush::No)
+ silentSpillAllRegisters(resultRegs);
+ else
+ flushRegisters();
callOperation(operationGetByValObjectString, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), arg1GPR, arg2GPR);
+ if (canUseFlush == CanUseFlush::No)
+ silentFillAllRegisters();
m_jit.exceptionCheck();
jsValueResult(resultRegs, node);
}
-void SpeculativeJIT::compileGetByValForObjectWithSymbol(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByValForObjectWithSymbol(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
SpeculateCellOperand arg1(this, m_graph.varArgChild(node, 0));
SpeculateCellOperand arg2(this, m_graph.varArgChild(node, 1));
@@ -3767,13 +3773,19 @@
GPRReg arg2GPR = arg2.gpr();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ CanUseFlush canUseFlush = CanUseFlush::Yes;
+ std::tie(resultRegs, std::ignore, canUseFlush) = prefix(DataFormatJS);
speculateObject(m_graph.varArgChild(node, 0), arg1GPR);
speculateSymbol(m_graph.varArgChild(node, 1), arg2GPR);
- flushRegisters();
+ if (canUseFlush == CanUseFlush::No)
+ silentSpillAllRegisters(resultRegs);
+ else
+ flushRegisters();
callOperation(operationGetByValObjectSymbol, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), arg1GPR, arg2GPR);
+ if (canUseFlush == CanUseFlush::No)
+ silentFillAllRegisters();
m_jit.exceptionCheck();
jsValueResult(resultRegs, node);
@@ -8086,7 +8098,7 @@
strictInt32Result(vectorGPR, node);
}
-void SpeculativeJIT::compileGetByValOnDirectArguments(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByValOnDirectArguments(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
@@ -8095,7 +8107,7 @@
GPRReg propertyReg = property.gpr();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
GPRReg scratchReg = resultRegs.payloadGPR();
if (!m_compileOkay)
@@ -8127,7 +8139,7 @@
jsValueResult(resultRegs, node);
}
-void SpeculativeJIT::compileGetByValOnScopedArguments(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByValOnScopedArguments(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
@@ -8143,7 +8155,7 @@
return;
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
m_jit.loadPtr(
MacroAssembler::Address(baseReg, ScopedArguments::offsetOfStorage()), resultRegs.payloadGPR());
@@ -13701,7 +13713,7 @@
GPRReg enumeratorGPR;
MacroAssembler::JumpList recoverGenericCase;
- compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat)>([&] (DataFormat) {
+ compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat)>([&] (DataFormat) {
Edge storageEdge = m_graph.varArgChild(node, 2);
StorageOperand storage;
if (storageEdge)
@@ -13773,7 +13785,7 @@
}
notFastNamedCases.link(&m_jit);
- return std::make_pair(resultRegs, DataFormatJS);
+ return std::tuple { resultRegs, DataFormatJS, CanUseFlush::No };
}));
// We rely on compileGetByVal to call jsValueResult for us.
Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (285541 => 285542)
--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2021-11-10 00:29:58 UTC (rev 285541)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2021-11-10 00:38:06 UTC (rev 285542)
@@ -1353,14 +1353,15 @@
}
// We use a scopedLambda to placate register allocation validation.
- void compileGetByVal(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
+ enum class CanUseFlush { Yes, No };
+ void compileGetByVal(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
void compileGetCharCodeAt(Node*);
- void compileGetByValOnString(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
+ void compileGetByValOnString(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
void compileFromCharCode(Node*);
- void compileGetByValOnDirectArguments(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
- void compileGetByValOnScopedArguments(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
+ void compileGetByValOnDirectArguments(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
+ void compileGetByValOnScopedArguments(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
void compileGetPrivateName(Node*);
void compileGetPrivateNameById(Node*);
@@ -1440,12 +1441,12 @@
#if USE(LARGE_TYPED_ARRAYS)
void compileGetTypedArrayByteOffsetAsInt52(Node*);
#endif
- void compileGetByValOnIntTypedArray(Node*, TypedArrayType, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
+ void compileGetByValOnIntTypedArray(Node*, TypedArrayType, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
- void compileGetByValOnFloatTypedArray(Node*, TypedArrayType, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
+ void compileGetByValOnFloatTypedArray(Node*, TypedArrayType, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
- void compileGetByValForObjectWithString(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
- void compileGetByValForObjectWithSymbol(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix);
+ void compileGetByValForObjectWithString(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
+ void compileGetByValForObjectWithSymbol(Node*, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix);
void compilePutByValForCellWithString(Node*, Edge& child1, Edge& child2, Edge& child3);
void compilePutByValForCellWithSymbol(Node*, Edge& child1, Edge& child2, Edge& child3);
void compileGetByValWithThis(Node*);
Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (285541 => 285542)
--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2021-11-10 00:29:58 UTC (rev 285541)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2021-11-10 00:38:06 UTC (rev 285542)
@@ -1812,7 +1812,7 @@
noResult(node, UseChildrenCalledExplicitly);
}
-void SpeculativeJIT::compileGetByVal(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByVal(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
switch (node->arrayMode().type()) {
case Array::SelectUsingPredictions:
@@ -1828,7 +1828,7 @@
GPRReg indexGPR = index.gpr();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
speculationCheck(OutOfBounds, JSValueRegs(), node,
m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
@@ -1858,10 +1858,16 @@
JSValueRegs propertyRegs = property.jsValueRegs();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ CanUseFlush canUseFlush = CanUseFlush::Yes;
+ std::tie(resultRegs, std::ignore, canUseFlush) = prefix(DataFormatJS);
- flushRegisters();
+ if (canUseFlush == CanUseFlush::No)
+ silentSpillAllRegisters(resultRegs);
+ else
+ flushRegisters();
callOperation(operationGetByValCell, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, propertyRegs);
+ if (canUseFlush == CanUseFlush::No)
+ silentFillAllRegisters();
m_jit.exceptionCheck();
jsValueResult(resultRegs, node);
@@ -1878,7 +1884,7 @@
JSValueRegs propertyRegs = property.jsValueRegs();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
CodeOrigin codeOrigin = node->origin.semantic;
CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
@@ -1927,7 +1933,7 @@
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(node->arrayMode().type() == Array::Int32 ? DataFormatInt32 : DataFormatJS);
+ std::tie(resultRegs, format, std::ignore) = prefix(node->arrayMode().type() == Array::Int32 ? DataFormatInt32 : DataFormatJS);
speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
@@ -1984,7 +1990,7 @@
return;
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
MacroAssembler::JumpList slowCases;
@@ -2016,7 +2022,7 @@
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(DataFormatDouble);
+ std::tie(resultRegs, format, std::ignore) = prefix(DataFormatDouble);
speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
@@ -2048,7 +2054,7 @@
FPRReg tempReg = temp.fpr();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
MacroAssembler::JumpList slowCases;
@@ -2078,7 +2084,7 @@
return;
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
@@ -2101,7 +2107,7 @@
return;
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
JITCompiler::Jump outOfBounds = m_jit.branch32(
MacroAssembler::AboveOrEqual, propertyReg,
@@ -2567,10 +2573,10 @@
case StringCharAt: {
// Relies on StringCharAt node having same basic layout as GetByVal
JSValueRegsTemporary result;
- compileGetByValOnString(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
+ compileGetByValOnString(node, scopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
result = JSValueRegsTemporary(this);
ASSERT(preferredFormat & DataFormatJS);
- return std::make_pair(result.regs(), preferredFormat);
+ return std::tuple { result.regs(), preferredFormat, CanUseFlush::Yes };
}));
break;
}
@@ -2609,7 +2615,7 @@
case GetByVal: {
JSValueRegsTemporary jsValueResult;
GPRTemporary oneRegResult;
- compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
+ compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
JSValueRegs resultRegs;
switch (preferredFormat) {
case DataFormatDouble:
@@ -2626,7 +2632,7 @@
break;
}
};
- return std::make_pair(resultRegs, preferredFormat);
+ return std::tuple { resultRegs, preferredFormat, CanUseFlush::Yes };
}));
break;
}
Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (285541 => 285542)
--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2021-11-10 00:29:58 UTC (rev 285541)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2021-11-10 00:38:06 UTC (rev 285542)
@@ -2246,7 +2246,7 @@
}
}
-void SpeculativeJIT::compileGetByVal(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
+void SpeculativeJIT::compileGetByVal(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>& prefix)
{
switch (node->arrayMode().type()) {
case Array::AnyTypedArray:
@@ -2261,7 +2261,7 @@
GPRReg indexGPR = index.gpr();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
speculationCheck(OutOfBounds, JSValueRegs(), node,
m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
@@ -2293,10 +2293,16 @@
GPRReg propertyGPR = property.gpr();
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ CanUseFlush canUseFlush = CanUseFlush::Yes;
+ std::tie(resultRegs, std::ignore, canUseFlush) = prefix(DataFormatJS);
- flushRegisters();
+ if (canUseFlush == CanUseFlush::No)
+ silentSpillAllRegisters(resultRegs);
+ else
+ flushRegisters();
callOperation(operationGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, propertyGPR);
+ if (canUseFlush == CanUseFlush::No)
+ silentFillAllRegisters();
m_jit.exceptionCheck();
jsValueResult(resultRegs, node);
@@ -2319,7 +2325,7 @@
speculate(node, m_graph.varArgChild(node, 1));
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
GPRReg resultGPR = resultRegs.gpr();
CodeOrigin codeOrigin = node->origin.semantic;
@@ -2377,7 +2383,7 @@
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(node->arrayMode().type() == Array::Int32 ? DataFormatJSInt32 : DataFormatJS);
+ std::tie(resultRegs, format, std::ignore) = prefix(node->arrayMode().type() == Array::Int32 ? DataFormatJSInt32 : DataFormatJS);
GPRReg result = resultRegs.gpr();
speculationCheck(OutOfBounds, JSValueRegs(), nullptr, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
@@ -2409,7 +2415,7 @@
return;
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
GPRReg resultReg = resultRegs.gpr();
MacroAssembler::JumpList slowCases;
@@ -2453,7 +2459,7 @@
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(DataFormatDouble);
+ std::tie(resultRegs, format, std::ignore) = prefix(DataFormatDouble);
speculationCheck(OutOfBounds, JSValueRegs(), nullptr, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
@@ -2488,7 +2494,7 @@
JSValueRegs resultRegs;
DataFormat format;
- std::tie(resultRegs, format) = prefix(resultIsUnboxed ? DataFormatDouble : DataFormatJS);
+ std::tie(resultRegs, format, std::ignore) = prefix(resultIsUnboxed ? DataFormatDouble : DataFormatJS);
MacroAssembler::JumpList slowCases;
@@ -2541,7 +2547,7 @@
return;
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
GPRReg resultGPR = resultRegs.gpr();
speculationCheck(OutOfBounds, JSValueRegs(), nullptr, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
@@ -2566,7 +2572,7 @@
return;
JSValueRegs resultRegs;
- std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
+ std::tie(resultRegs, std::ignore, std::ignore) = prefix(DataFormatJS);
GPRReg resultReg = resultRegs.gpr();
MacroAssembler::JumpList slowCases;
@@ -3158,10 +3164,10 @@
case StringCharAt: {
// Relies on StringCharAt node having same basic layout as GetByVal
JSValueRegsTemporary result;
- compileGetByValOnString(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
+ compileGetByValOnString(node, scopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
result = JSValueRegsTemporary(this);
ASSERT(preferredFormat == DataFormatJS || preferredFormat == DataFormatCell);
- return std::make_pair(result.regs(), preferredFormat);
+ return std::tuple { result.regs(), preferredFormat, CanUseFlush::Yes };
}));
break;
}
@@ -3200,7 +3206,7 @@
case GetByVal: {
JSValueRegsTemporary result;
- compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
+ compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat, CanUseFlush>(DataFormat preferredFormat)>([&] (DataFormat preferredFormat) {
JSValueRegs resultRegs;
switch (preferredFormat) {
case DataFormatDouble:
@@ -3211,7 +3217,7 @@
break;
}
};
- return std::make_pair(resultRegs, preferredFormat);
+ return std::tuple { resultRegs, preferredFormat, CanUseFlush::Yes };
}));
break;
}