[JSC] OSRExit recovery for SpeculativeAdd does not consier "A = A + A" pattern
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Apr 2019 01:57:16 +0000 (01:57 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Apr 2019 01:57:16 +0000 (01:57 +0000)
commit190db06ea56d27a550bf4df6dab5b201ead7686b
tree14b7d00e8b4d748b299d33b47d6314f6d454455e
parentf359bf2cde9a4e32c8aceef87cf7d7c6584b7922
[JSC] OSRExit recovery for SpeculativeAdd does not consier "A = A + A" pattern
https://bugs.webkit.org/show_bug.cgi?id=196582

Reviewed by Saam Barati.

JSTests:

* stress/add-overflow-check-with-three-same-registers.js: Added.
(foo):
(Number.prototype.valueOf):
(runWithNumber):

Source/JavaScriptCore:

In DFG, our ArithAdd with overflow is executed speculatively, and we recover the value when overflow flag is set.
The recovery is subtracting the operand from the destination to get the original two operands. Our recovery code
handles A + B = A, A + B = B cases. But it misses A + A = A case (here, A and B are GPRReg). Our recovery code
attempts to produce the original operand by performing A - A, and it always produces zero accidentally.

This patch adds the recovery code for A + A = A case. Because we know that this ArithAdd overflows, and operands were
same values, we can calculate the original operand from the destination value by `((int32_t)value >> 1) ^ 0x80000000`.

We also found that FTL recovery code is dead. We remove them in this patch.

* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::executeOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGOSRExit.h:
(JSC::DFG::SpeculationRecovery::SpeculationRecovery):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithAdd):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dataFormat const):
(JSC::FTL::ExitValue::dumpInContext const):
* ftl/FTLExitValue.h:
(JSC::FTL::ExitValue::isArgument const):
(JSC::FTL::ExitValue::hasIndexInStackmapLocations const):
(JSC::FTL::ExitValue::adjustStackmapLocationsIndexByOffset):
(JSC::FTL::ExitValue::recovery): Deleted.
(JSC::FTL::ExitValue::isRecovery const): Deleted.
(JSC::FTL::ExitValue::leftRecoveryArgument const): Deleted.
(JSC::FTL::ExitValue::rightRecoveryArgument const): Deleted.
(JSC::FTL::ExitValue::recoveryFormat const): Deleted.
(JSC::FTL::ExitValue::recoveryOpcode const): Deleted.
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::preparePatchpointForExceptions):
(JSC::FTL::DFG::LowerDFGToB3::appendOSRExit):
(JSC::FTL::DFG::LowerDFGToB3::exitValueForNode):
(JSC::FTL::DFG::LowerDFGToB3::addAvailableRecovery): Deleted.
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileRecovery):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243959 268f45cc-cd09-0410-ab3c-d52691b4dbfc
JSTests/ChangeLog
JSTests/stress/add-overflow-check-with-three-same-registers.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGOSRExit.cpp
Source/JavaScriptCore/dfg/DFGOSRExit.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/ftl/FTLExitValue.cpp
Source/JavaScriptCore/ftl/FTLExitValue.h
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp