Modified: trunk/Source/_javascript_Core/ChangeLog (204203 => 204204)
--- trunk/Source/_javascript_Core/ChangeLog 2016-08-06 00:01:27 UTC (rev 204203)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-08-06 00:01:45 UTC (rev 204204)
@@ -1,3 +1,30 @@
+2016-08-05 Michael Saboff <[email protected]>
+
+ compilePutByValForIntTypedArray() has a slow path in the middle of its processing
+ https://bugs.webkit.org/show_bug.cgi?id=160614
+
+ Reviewed by Keith Miller.
+
+ In compilePutByValForIntTypedArray() we were calling out to the slow path
+ operationToInt32() and then returning back to the middle of code to finish
+ the processing of writing the value to the array. When we make the slow
+ path call, we trash any temporary registers that have been allocated.
+ In general slow path calls should finish the operation in progress and
+ continue processing at the beginning of the next node.
+
+ This was discovered while working on the register argument changes, when
+ we SpeculateStrictInt32Operand on the value child node. That child node's
+ value was live in register with a spill format of DataFormatJSInt32. In that
+ case we allocate a new temporary register and copy just the lower 32 bits from
+ the child register to the new temp register. That temp register gets trashed
+ when we make the operationToInt32() slow path call.
+
+ I spent some time trying to devise a test with the current code base and wasn't
+ successful. This case is tested with the register argument changes in progress.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+
2016-08-05 Saam Barati <[email protected]>
Assertion failure when accessing TDZ variable in catch through eval
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (204203 => 204204)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-08-06 00:01:27 UTC (rev 204203)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-08-06 00:01:45 UTC (rev 204204)
@@ -2726,8 +2726,19 @@
Edge valueUse = m_jit.graph().varArgChild(node, 2);
GPRTemporary value;
+#if USE(JSVALUE32_64)
+ GPRTemporary propertyTag;
+ GPRTemporary valueTag;
+#endif
+
GPRReg valueGPR = InvalidGPRReg;
-
+#if USE(JSVALUE32_64)
+ GPRReg propertyTagGPR = InvalidGPRReg;
+ GPRReg valueTagGPR = InvalidGPRReg;
+#endif
+
+ JITCompiler::JumpList slowPathCases;
+
if (valueUse->isConstant()) {
JSValue jsValue = valueUse->asJSValue();
if (!jsValue.isNumber()) {
@@ -2798,6 +2809,15 @@
value.adopt(result);
valueGPR = gpr;
} else {
+#if USE(JSVALUE32_64)
+ GPRTemporary realPropertyTag(this);
+ propertyTag.adopt(realPropertyTag);
+ propertyTagGPR = propertyTag.gpr();
+
+ GPRTemporary realValueTag(this);
+ valueTag.adopt(realValueTag);
+ valueTagGPR = valueTag.gpr();
+#endif
SpeculateDoubleOperand valueOp(this, valueUse);
GPRTemporary result(this);
FPRReg fpr = valueOp.fpr();
@@ -2804,14 +2824,21 @@
GPRReg gpr = result.gpr();
MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
m_jit.xorPtr(gpr, gpr);
- MacroAssembler::Jump fixed = m_jit.jump();
+ MacroAssembler::JumpList fixed(m_jit.jump());
notNaN.link(&m_jit);
-
- MacroAssembler::Jump failed = m_jit.branchTruncateDoubleToInt32(
- fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
-
- addSlowPathGenerator(slowPathCall(failed, this, operationToInt32, gpr, fpr, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded));
-
+
+ fixed.append(m_jit.branchTruncateDoubleToInt32(
+ fpr, gpr, MacroAssembler::BranchIfTruncateSuccessful));
+
+#if USE(JSVALUE64)
+ m_jit.or64(GPRInfo::tagTypeNumberRegister, property);
+ boxDouble(fpr, gpr);
+#else
+ m_jit.move(TrustedImm32(JSValue::Int32Tag), propertyTagGPR);
+ boxDouble(fpr, valueTagGPR, gpr);
+#endif
+ slowPathCases.append(m_jit.jump());
+
fixed.link(&m_jit);
value.adopt(result);
valueGPR = gpr;
@@ -2847,6 +2874,34 @@
JITCompiler::Jump done = jumpForTypedArrayIsNeuteredIfOutOfBounds(node, base, outOfBounds);
if (done.isSet())
done.link(&m_jit);
+
+ if (!slowPathCases.empty()) {
+#if USE(JSVALUE64)
+ if (node->op() == PutByValDirect) {
+ addSlowPathGenerator(slowPathCall(
+ slowPathCases, this,
+ m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValDirectStrict : operationPutByValDirectNonStrict,
+ NoResult, base, property, valueGPR));
+ } else {
+ addSlowPathGenerator(slowPathCall(
+ slowPathCases, this,
+ m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValStrict : operationPutByValNonStrict,
+ NoResult, base, property, valueGPR));
+ }
+#else // not USE(JSVALUE64)
+ if (node->op() == PutByValDirect) {
+ addSlowPathGenerator(slowPathCall(
+ slowPathCases, this,
+ m_jit.codeBlock()->isStrictMode() ? operationPutByValDirectCellStrict : operationPutByValDirectCellNonStrict,
+ NoResult, base, JSValueRegs(propertyTagGPR, property), JSValueRegs(valueTagGPR, valueGPR)));
+ } else {
+ addSlowPathGenerator(slowPathCall(
+ slowPathCases, this,
+ m_jit.codeBlock()->isStrictMode() ? operationPutByValCellStrict : operationPutByValCellNonStrict,
+ NoResult, base, JSValueRegs(propertyTagGPR, property), JSValueRegs(valueTagGPR, valueGPR)));
+ }
+#endif
+ }
noResult(node);
}