- Revision
- 96458
- Author
- [email protected]
- Date
- 2011-10-01 12:21:44 -0700 (Sat, 01 Oct 2011)
Log Message
JSVALUE32_64 DFG JIT - unboxed integers and cells in register file must be reboxed before exiting from DFG JIT
https://bugs.webkit.org/show_bug.cgi?id=69205
Patch by Yuqiang Xian <[email protected]> on 2011-10-01
Reviewed by Gavin Barraclough.
If there are unboxed integers and cells in register file (e.g. by SetLocal),
they must be reboxed before exiting from the speculative DFG JIT execution.
This patch also adds a new ValueSourceKind (CellInRegisterFile) and a new
ValueRecoveryTechnique (AlreadyInRegisterFileAsCell).
* dfg/DFGJITCompiler32_64.cpp:
(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::ValueSource::dump):
(JSC::DFG::ValueRecovery::dump):
(JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::ValueSource::forPrediction):
(JSC::DFG::ValueRecovery::alreadyInRegisterFileAsUnboxedCell):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (96457 => 96458)
--- trunk/Source/_javascript_Core/ChangeLog 2011-10-01 17:32:10 UTC (rev 96457)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-10-01 19:21:44 UTC (rev 96458)
@@ -1,3 +1,25 @@
+2011-10-01 Yuqiang Xian <[email protected]>
+
+ JSVALUE32_64 DFG JIT - unboxed integers and cells in register file must be reboxed before exiting from DFG JIT
+ https://bugs.webkit.org/show_bug.cgi?id=69205
+
+ Reviewed by Gavin Barraclough.
+
+ If there are unboxed integers and cells in register file (e.g. by SetLocal),
+ they must be reboxed before exiting from the speculative DFG JIT execution.
+ This patch also adds a new ValueSourceKind (CellInRegisterFile) and a new
+ ValueRecoveryTechnique (AlreadyInRegisterFileAsCell).
+
+ * dfg/DFGJITCompiler32_64.cpp:
+ (JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::ValueSource::dump):
+ (JSC::DFG::ValueRecovery::dump):
+ (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::ValueSource::forPrediction):
+ (JSC::DFG::ValueRecovery::alreadyInRegisterFileAsUnboxedCell):
+
2011-10-01 Sheriff Bot <[email protected]>
Unreviewed, rolling out r96421.
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp (96457 => 96458)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp 2011-10-01 17:32:10 UTC (rev 96457)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp 2011-10-01 19:21:44 UTC (rev 96458)
@@ -146,7 +146,8 @@
// Int32s, have no FPRs, and have no constants. If there are constants, we
// expect most of them to be jsUndefined(); if that's true then we handle that
// specially to minimize code size and execution time.
- bool haveUnboxedInt32s = false;
+ bool haveUnboxedInt32InRegisterFile = false;
+ bool haveUnboxedCellInRegisterFile = false;
bool haveFPRs = false;
bool haveConstants = false;
bool haveUndefined = false;
@@ -182,10 +183,14 @@
}
break;
- case UnboxedInt32InGPR:
- haveUnboxedInt32s = true;
+ case AlreadyInRegisterFileAsUnboxedInt32:
+ haveUnboxedInt32InRegisterFile = true;
break;
+ case AlreadyInRegisterFileAsUnboxedCell:
+ haveUnboxedCellInRegisterFile = true;
+ break;
+
case InFPR:
haveFPRs = true;
break;
@@ -206,9 +211,26 @@
// From here on, the code assumes that it is profitable to maximize the distance
// between when something is computed and when it is stored.
- // 4) Perform all reboxing of integers.
- // Currently we don't rebox for JSValue32_64.
-
+ // 4) Perform all reboxing of integers and cells, except for those in registers.
+
+ if (haveUnboxedInt32InRegisterFile || haveUnboxedCellInRegisterFile) {
+ for (int index = 0; index < exit.numberOfRecoveries(); ++index) {
+ const ValueRecovery& recovery = exit.valueRecovery(index);
+ switch (recovery.technique()) {
+ case AlreadyInRegisterFileAsUnboxedInt32:
+ store32(TrustedImm32(JSValue::Int32Tag), tagFor(static_cast<VirtualRegister>(exit.operandForIndex(index))));
+ break;
+
+ case AlreadyInRegisterFileAsUnboxedCell:
+ store32(TrustedImm32(JSValue::CellTag), tagFor(static_cast<VirtualRegister>(exit.operandForIndex(index))));
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
// 5) Dump all non-poisoned GPRs. For poisoned GPRs, save them into the scratch storage.
// Note that GPRs do not have a fast change (like haveFPRs) because we expect that
// most OSR failure points will have at least one GPR that needs to be dumped.
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (96457 => 96458)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-10-01 17:32:10 UTC (rev 96457)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-10-01 19:21:44 UTC (rev 96458)
@@ -44,6 +44,9 @@
case Int32InRegisterFile:
fprintf(out, "Int32");
break;
+ case CellInRegisterFile:
+ fprintf(out, "Cell");
+ break;
case HaveNode:
fprintf(out, "Node(%d)", m_nodeIndex);
break;
@@ -59,6 +62,9 @@
case AlreadyInRegisterFileAsUnboxedInt32:
fprintf(out, "(int32)");
break;
+ case AlreadyInRegisterFileAsUnboxedCell:
+ fprintf(out, "(cell)");
+ break;
case InGPR:
fprintf(out, "%%%s", GPRInfo::debugName(gpr()));
break;
@@ -399,6 +405,9 @@
case Int32InRegisterFile:
return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32();
+ case CellInRegisterFile:
+ return ValueRecovery::alreadyInRegisterFileAsUnboxedCell();
+
case HaveNode: {
if (m_jit.isConstant(valueSource.nodeIndex()))
return ValueRecovery::constant(m_jit.valueOfJSConstant(valueSource.nodeIndex()));
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (96457 => 96458)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-10-01 17:32:10 UTC (rev 96457)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-10-01 19:21:44 UTC (rev 96458)
@@ -70,6 +70,7 @@
SourceNotSet,
ValueInRegisterFile,
Int32InRegisterFile,
+ CellInRegisterFile,
HaveNode
};
@@ -97,6 +98,8 @@
{
if (isInt32Prediction(prediction))
return ValueSource(Int32InRegisterFile);
+ if (isCellPrediction(prediction))
+ return ValueSource(CellInRegisterFile);
return ValueSource(ValueInRegisterFile);
}
@@ -145,6 +148,7 @@
AlreadyInRegisterFile,
// It's already in the register file but unboxed.
AlreadyInRegisterFileAsUnboxedInt32,
+ AlreadyInRegisterFileAsUnboxedCell,
// It's in a register.
InGPR,
UnboxedInt32InGPR,
@@ -181,6 +185,13 @@
return result;
}
+ static ValueRecovery alreadyInRegisterFileAsUnboxedCell()
+ {
+ ValueRecovery result;
+ result.m_technique = AlreadyInRegisterFileAsUnboxedCell;
+ return result;
+ }
+
static ValueRecovery inGPR(GPRReg gpr, DataFormat dataFormat)
{
ASSERT(dataFormat != DataFormatNone);