Commit 002405c0 authored by fpizlo@apple.com's avatar fpizlo@apple.com

FTL should have an explicit notion of bytecode liveness

https://bugs.webkit.org/show_bug.cgi?id=124181

Source/JavaScriptCore: 

Reviewed by Sam Weinig.
        
This makes FTL OSR exit use bytecode liveness analysis to determine which variables
to include values for. The decision of how to get the values of variables is based on
forward propagation of MovHints and SetLocals.
        
This fixes a bunch of bugs (like https://bugs.webkit.org/show_bug.cgi?id=124138 but
also others that I noticed when I started writing more targetted tests) and allows us
to remove some sketchy code.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeBasicBlock.h:
* bytecode/BytecodeLivenessAnalysis.cpp:
(JSC::isValidRegisterForLiveness):
(JSC::setForOperand):
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
(JSC::stepOverInstruction):
(JSC::computeLocalLivenessForBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
(JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
(JSC::getLivenessInfo):
(JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::computeFullLiveness):
* bytecode/BytecodeLivenessAnalysis.h:
* bytecode/BytecodeLivenessAnalysisInlines.h: Added.
(JSC::operandIsAlwaysLive):
(JSC::operandThatIsNotAlwaysLiveIsLive):
(JSC::operandIsLive):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::captureCount):
(JSC::CodeBlock::captureStart):
(JSC::CodeBlock::captureEnd):
* bytecode/CodeOrigin.cpp:
(JSC::InlineCallFrame::dumpInContext):
* bytecode/FullBytecodeLiveness.h: Added.
(JSC::FullBytecodeLiveness::FullBytecodeLiveness):
(JSC::FullBytecodeLiveness::getOut):
(JSC::FullBytecodeLiveness::operandIsLive):
(JSC::FullBytecodeLiveness::getLiveness):
* dfg/DFGAvailability.cpp: Added.
(JSC::DFG::Availability::dump):
(JSC::DFG::Availability::dumpInContext):
* dfg/DFGAvailability.h: Added.
(JSC::DFG::Availability::Availability):
(JSC::DFG::Availability::unavailable):
(JSC::DFG::Availability::withFlush):
(JSC::DFG::Availability::withNode):
(JSC::DFG::Availability::withUnavailableNode):
(JSC::DFG::Availability::nodeIsUndecided):
(JSC::DFG::Availability::nodeIsUnavailable):
(JSC::DFG::Availability::hasNode):
(JSC::DFG::Availability::node):
(JSC::DFG::Availability::flushedAt):
(JSC::DFG::Availability::operator!):
(JSC::DFG::Availability::operator==):
(JSC::DFG::Availability::merge):
(JSC::DFG::Availability::mergeNodes):
(JSC::DFG::Availability::unavailableMarker):
* dfg/DFGBasicBlock.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::Disassembler):
* dfg/DFGFlushFormat.cpp:
(WTF::printInternal):
* dfg/DFGFlushFormat.h:
(JSC::DFG::resultFor):
(JSC::DFG::useKindFor):
(JSC::DFG::dataFormatFor):
* dfg/DFGFlushedAt.cpp:
(JSC::DFG::FlushedAt::dump):
* dfg/DFGFlushedAt.h:
(JSC::DFG::FlushedAt::FlushedAt):
(JSC::DFG::FlushedAt::merge):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::livenessFor):
(JSC::DFG::Graph::isLiveInBytecode):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::baselineCodeBlockFor):
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
* dfg/DFGOSRAvailabilityAnalysisPhase.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGResurrectionForValidationPhase.cpp: Added.
(JSC::DFG::ResurrectionForValidationPhase::ResurrectionForValidationPhase):
(JSC::DFG::ResurrectionForValidationPhase::run):
(JSC::DFG::performResurrectionForValidation):
* dfg/DFGResurrectionForValidationPhase.h: Added.
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGValueSource.h:
(JSC::DFG::ValueSource::forFlushFormat):
* dfg/DFGVariableAccessData.h:
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dumpInContext):
* ftl/FTLInlineCacheSize.cpp:
(JSC::FTL::sizeOfGetById):
* ftl/FTLLocation.cpp:
(JSC::FTL::Location::gpr):
(JSC::FTL::Location::fpr):
(JSC::FTL::Location::directGPR):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::compileBlock):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileSetLocal):
(JSC::FTL::LowerDFGToLLVM::compileZombieHint):
(JSC::FTL::LowerDFGToLLVM::compilePutById):
(JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
(JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
(JSC::FTL::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
(JSC::FTL::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
(JSC::FTL::LowerDFGToLLVM::observeMovHint):
* ftl/FTLOutput.h:
(JSC::FTL::Output::alloca):
* ftl/FTLValueSource.cpp: Removed.
* ftl/FTLValueSource.h: Removed.
* llvm/LLVMAPIFunctions.h:
* runtime/DumpContext.cpp:
(JSC::DumpContext::DumpContext):
* runtime/DumpContext.h:
* runtime/Options.h:
* runtime/SymbolTable.h:
(JSC::SharedSymbolTable::captureStart):
(JSC::SharedSymbolTable::captureEnd):
(JSC::SharedSymbolTable::captureCount):

Tools: 

Reviewed by Mark Hahnenberg.

* Scripts/run-jsc-stress-tests:

LayoutTests: 

Reviewed by Mark Hahnenberg or Sam Weinig.
        
I totally added this test after the rest of the patch was r+'d. Under the right tier-up
modes this triggers one of the bugs that the rest of the patch is trying to avoid.

* js/regress/script-tests/weird-inlining-const-prop.js: Added.
(foo):
(bar):
(fuzz):
(testImpl):
(test):
* js/regress/weird-inlining-const-prop-expected.txt: Added.
* js/regress/weird-inlining-const-prop.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159394 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 48c4fbd3
2013-11-17 Filip Pizlo <fpizlo@apple.com>
FTL should have an explicit notion of bytecode liveness
https://bugs.webkit.org/show_bug.cgi?id=124181
Reviewed by Mark Hahnenberg or Sam Weinig.
I totally added this test after the rest of the patch was r+'d. Under the right tier-up
modes this triggers one of the bugs that the rest of the patch is trying to avoid.
* js/regress/script-tests/weird-inlining-const-prop.js: Added.
(foo):
(bar):
(fuzz):
(testImpl):
(test):
* js/regress/weird-inlining-const-prop-expected.txt: Added.
* js/regress/weird-inlining-const-prop.html: Added.
2013-11-17 Alexey Proskuryakov <ap@apple.com>
RSASSA-PKCS1-v1_5 JWK import doesn't check key size
......
function foo(o, p, q) {
var x = o[0];
var y;
if (p) {
x();
if (q) {
x();
y = 42;
} else {
x();
y = 11;
}
} else
y = 23;
o[1]++;
return x;
}
function bar(o, p, q) {
var x = o[0];
var y;
if (p)
y = 23;
else {
x();
if (q) {
x();
y = 42;
} else {
x();
y = 11;
}
}
o[1]++;
return x;
}
function fuzz() { }
noInline(foo);
noInline(bar);
function testImpl(f, x, p) {
var result = f([fuzz, x], p, false);
if (result != fuzz)
throw "Error: bad result: " + result;
}
function test(x, p) {
testImpl(foo, x, p);
testImpl(bar, x, !p);
}
for (var i = 0; i < 10000; ++i)
test(0, true);
for (var i = 0; i < 10000; ++i)
test(0, false);
test(0.5, true);
JSRegress/weird-inlining-const-prop
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS no exception thrown
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="resources/regress-pre.js"></script>
<script src="script-tests/weird-inlining-const-prop.js"></script>
<script src="resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
......@@ -91,6 +91,7 @@ set(JavaScriptCore_SOURCES
dfg/DFGArgumentsSimplificationPhase.cpp
dfg/DFGArrayMode.cpp
dfg/DFGAtTailAbstractState.cpp
dfg/DFGAvailability.cpp
dfg/DFGBackwardsPropagationPhase.cpp
dfg/DFGBasicBlock.cpp
dfg/DFGBinarySwitch.cpp
......@@ -158,6 +159,7 @@ set(JavaScriptCore_SOURCES
dfg/DFGPlan.cpp
dfg/DFGPredictionInjectionPhase.cpp
dfg/DFGPredictionPropagationPhase.cpp
dfg/DFGResurrectionForValidationPhase.cpp
dfg/DFGSSAConversionPhase.cpp
dfg/DFGSpeculativeJIT.cpp
dfg/DFGSpeculativeJIT32_64.cpp
......
2013-11-16 Filip Pizlo <fpizlo@apple.com>
FTL should have an explicit notion of bytecode liveness
https://bugs.webkit.org/show_bug.cgi?id=124181
Reviewed by Sam Weinig.
This makes FTL OSR exit use bytecode liveness analysis to determine which variables
to include values for. The decision of how to get the values of variables is based on
forward propagation of MovHints and SetLocals.
This fixes a bunch of bugs (like https://bugs.webkit.org/show_bug.cgi?id=124138 but
also others that I noticed when I started writing more targetted tests) and allows us
to remove some sketchy code.
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeBasicBlock.h:
* bytecode/BytecodeLivenessAnalysis.cpp:
(JSC::isValidRegisterForLiveness):
(JSC::setForOperand):
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
(JSC::stepOverInstruction):
(JSC::computeLocalLivenessForBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
(JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
(JSC::getLivenessInfo):
(JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::computeFullLiveness):
* bytecode/BytecodeLivenessAnalysis.h:
* bytecode/BytecodeLivenessAnalysisInlines.h: Added.
(JSC::operandIsAlwaysLive):
(JSC::operandThatIsNotAlwaysLiveIsLive):
(JSC::operandIsLive):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::captureCount):
(JSC::CodeBlock::captureStart):
(JSC::CodeBlock::captureEnd):
* bytecode/CodeOrigin.cpp:
(JSC::InlineCallFrame::dumpInContext):
* bytecode/FullBytecodeLiveness.h: Added.
(JSC::FullBytecodeLiveness::FullBytecodeLiveness):
(JSC::FullBytecodeLiveness::getOut):
(JSC::FullBytecodeLiveness::operandIsLive):
(JSC::FullBytecodeLiveness::getLiveness):
* dfg/DFGAvailability.cpp: Added.
(JSC::DFG::Availability::dump):
(JSC::DFG::Availability::dumpInContext):
* dfg/DFGAvailability.h: Added.
(JSC::DFG::Availability::Availability):
(JSC::DFG::Availability::unavailable):
(JSC::DFG::Availability::withFlush):
(JSC::DFG::Availability::withNode):
(JSC::DFG::Availability::withUnavailableNode):
(JSC::DFG::Availability::nodeIsUndecided):
(JSC::DFG::Availability::nodeIsUnavailable):
(JSC::DFG::Availability::hasNode):
(JSC::DFG::Availability::node):
(JSC::DFG::Availability::flushedAt):
(JSC::DFG::Availability::operator!):
(JSC::DFG::Availability::operator==):
(JSC::DFG::Availability::merge):
(JSC::DFG::Availability::mergeNodes):
(JSC::DFG::Availability::unavailableMarker):
* dfg/DFGBasicBlock.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::Disassembler):
* dfg/DFGFlushFormat.cpp:
(WTF::printInternal):
* dfg/DFGFlushFormat.h:
(JSC::DFG::resultFor):
(JSC::DFG::useKindFor):
(JSC::DFG::dataFormatFor):
* dfg/DFGFlushedAt.cpp:
(JSC::DFG::FlushedAt::dump):
* dfg/DFGFlushedAt.h:
(JSC::DFG::FlushedAt::FlushedAt):
(JSC::DFG::FlushedAt::merge):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::livenessFor):
(JSC::DFG::Graph::isLiveInBytecode):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::baselineCodeBlockFor):
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
* dfg/DFGOSRAvailabilityAnalysisPhase.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGResurrectionForValidationPhase.cpp: Added.
(JSC::DFG::ResurrectionForValidationPhase::ResurrectionForValidationPhase):
(JSC::DFG::ResurrectionForValidationPhase::run):
(JSC::DFG::performResurrectionForValidation):
* dfg/DFGResurrectionForValidationPhase.h: Added.
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGValueSource.h:
(JSC::DFG::ValueSource::forFlushFormat):
* dfg/DFGVariableAccessData.h:
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dumpInContext):
* ftl/FTLInlineCacheSize.cpp:
(JSC::FTL::sizeOfGetById):
* ftl/FTLLocation.cpp:
(JSC::FTL::Location::gpr):
(JSC::FTL::Location::fpr):
(JSC::FTL::Location::directGPR):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::compileBlock):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileSetLocal):
(JSC::FTL::LowerDFGToLLVM::compileZombieHint):
(JSC::FTL::LowerDFGToLLVM::compilePutById):
(JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
(JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
(JSC::FTL::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
(JSC::FTL::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
(JSC::FTL::LowerDFGToLLVM::observeMovHint):
* ftl/FTLOutput.h:
(JSC::FTL::Output::alloca):
* ftl/FTLValueSource.cpp: Removed.
* ftl/FTLValueSource.h: Removed.
* llvm/LLVMAPIFunctions.h:
* runtime/DumpContext.cpp:
(JSC::DumpContext::DumpContext):
* runtime/DumpContext.h:
* runtime/Options.h:
* runtime/SymbolTable.h:
(JSC::SharedSymbolTable::captureStart):
(JSC::SharedSymbolTable::captureEnd):
(JSC::SharedSymbolTable::captureCount):
2013-11-16 Filip Pizlo <fpizlo@apple.com>
Fix indentation of JSActivation.h.
......
......@@ -100,10 +100,11 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/ArrayProfile.cpp \
Source/JavaScriptCore/bytecode/ArrayProfile.h \
Source/JavaScriptCore/bytecode/ByValInfo.h \
Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp \
Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h \
Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp \
Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h \
Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp \
Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h \
Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp \
Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h \
Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h \
Source/JavaScriptCore/bytecode/BytecodeConventions.h \
Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \
Source/JavaScriptCore/bytecode/CallLinkInfo.h \
......@@ -132,6 +133,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/ExitKind.cpp \
Source/JavaScriptCore/bytecode/ExitKind.h \
Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h \
Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h \
Source/JavaScriptCore/bytecode/GetByIdStatus.cpp \
Source/JavaScriptCore/bytecode/GetByIdStatus.h \
Source/JavaScriptCore/bytecode/HandlerInfo.h \
......@@ -207,6 +209,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h \
Source/JavaScriptCore/dfg/DFGAtTailAbstractState.cpp \
Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h \
Source/JavaScriptCore/dfg/DFGAvailability.cpp \
Source/JavaScriptCore/dfg/DFGAvailability.h \
Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp \
Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.h \
Source/JavaScriptCore/dfg/DFGBasicBlock.cpp \
......@@ -358,6 +362,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h \
Source/JavaScriptCore/dfg/DFGRegisterBank.h \
Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.cpp \
Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.h \
Source/JavaScriptCore/dfg/DFGSafeToExecute.h \
Source/JavaScriptCore/dfg/DFGSaneStringGetByValSlowPathGenerator.h \
Source/JavaScriptCore/dfg/DFGScoreBoard.h \
......@@ -469,8 +475,6 @@ javascriptcore_sources += \
Source/JavaScriptCore/ftl/FTLValueFormat.cpp \
Source/JavaScriptCore/ftl/FTLValueFormat.h \
Source/JavaScriptCore/ftl/FTLValueFromBlock.h \
Source/JavaScriptCore/ftl/FTLValueSource.cpp \
Source/JavaScriptCore/ftl/FTLValueSource.h \
Source/JavaScriptCore/heap/CodeBlockSet.cpp \
Source/JavaScriptCore/heap/CodeBlockSet.h \
Source/JavaScriptCore/heap/CopiedAllocator.h \
......
......@@ -338,6 +338,7 @@
<ClCompile Include="..\dfg\DFGArgumentsSimplificationPhase.cpp" />
<ClCompile Include="..\dfg\DFGArrayMode.cpp" />
<ClCompile Include="..\dfg\DFGAtTailAbstractState.cpp" />
<ClCompile Include="..\dfg\DFGAvailability.cpp" />
<ClCompile Include="..\dfg\DFGBackwardsPropagationPhase.cpp" />
<ClCompile Include="..\dfg\DFGBasicBlock.cpp" />
<ClCompile Include="..\dfg\DFGBinarySwitch.cpp" />
......@@ -403,6 +404,7 @@
<ClCompile Include="..\dfg\DFGPlan.cpp" />
<ClCompile Include="..\dfg\DFGPredictionInjectionPhase.cpp" />
<ClCompile Include="..\dfg\DFGPredictionPropagationPhase.cpp" />
<ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp" />
<ClCompile Include="..\dfg\DFGSpeculativeJIT.cpp" />
<ClCompile Include="..\dfg\DFGSpeculativeJIT32_64.cpp" />
<ClCompile Include="..\dfg\DFGSpeculativeJIT64.cpp" />
......@@ -744,6 +746,7 @@
<ClInclude Include="..\bytecode\ByValInfo.h" />
<ClInclude Include="..\bytecode\BytecodeBasicBlock.h" />
<ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h" />
<ClInclude Include="..\bytecode\BytecodeLivenessAnalysisInline.h" />
<ClInclude Include="..\bytecode\CallLinkInfo.h" />
<ClInclude Include="..\bytecode\CallLinkStatus.h" />
<ClInclude Include="..\bytecode\CallReturnOffsetToBytecodeOffset.h" />
......@@ -761,6 +764,7 @@
<ClInclude Include="..\bytecode\ExecutionCounter.h" />
<ClInclude Include="..\bytecode\ExitKind.h" />
<ClInclude Include="..\bytecode\ExpressionRangeInfo.h" />
<ClInclude Include="..\bytecode\FullBytecodeLivenss.h" />
<ClInclude Include="..\bytecode\GetByIdStatus.h" />
<ClInclude Include="..\bytecode\HandlerInfo.h" />
<ClInclude Include="..\bytecode\InlineCallFrameSet.h" />
......@@ -811,6 +815,7 @@
<ClInclude Include="..\dfg\DFGArrayifySlowPathGenerator.h" />
<ClInclude Include="..\dfg\DFGArrayMode.h" />
<ClInclude Include="..\dfg\DFGAtTailAbstractState.h" />
<ClInclude Include="..\dfg\DFGAvailability.h" />
<ClInclude Include="..\dfg\DFGBackwardsPropagationPhase.h" />
<ClInclude Include="..\dfg\DFGBasicBlock.h" />
<ClInclude Include="..\dfg\DFGBasicBlockInlines.h" />
......@@ -894,6 +899,7 @@
<ClInclude Include="..\dfg\DFGPredictionPropagationPhase.h" />
<ClInclude Include="..\dfg\DFGRegisterBank.h" />
<ClInclude Include="..\dfg\DFGRegisterSet.h" />
<ClInclude Include="..\dfg\DFGResurrectionForValidationPhase.h" />
<ClInclude Include="..\dfg\DFGSafeToExecute.h" />
<ClInclude Include="..\dfg\DFGSaneStringGetByValSlowPathGenerator.h" />
<ClInclude Include="..\dfg\DFGScoreBoard.h" />
......
......@@ -36,8 +36,6 @@ namespace JSC {
class CodeBlock;
typedef HashMap<unsigned, FastBitVector, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > BytecodeToBitmapMap;
class BytecodeBasicBlock : public RefCounted<BytecodeBasicBlock> {
public:
enum SpecialBlockType { EntryBlock, ExitBlock };
......
......@@ -34,13 +34,16 @@
namespace JSC {
class CodeBlock;
class FullBytecodeLiveness;
class BytecodeLivenessAnalysis {
public:
BytecodeLivenessAnalysis(CodeBlock*);
bool operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset);
FastBitVector getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset);
void computeFullLiveness(FullBytecodeLiveness& result);
private:
void compute();
......@@ -53,6 +56,12 @@ private:
Vector<RefPtr<BytecodeBasicBlock> > m_basicBlocks;
};
inline bool operandIsAlwaysLive(CodeBlock*, int operand);
inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock*, const FastBitVector& out, int operand);
inline bool operandIsLive(CodeBlock*, const FastBitVector& out, int operand);
FastBitVector getLivenessInfo(CodeBlock*, const FastBitVector& out);
} // namespace JSC
#endif // BytecodeLivenessAnalysis_h
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BytecodeLivenessAnalysisInlines_h
#define BytecodeLivenessAnalysisInlines_h
#include "BytecodeLivenessAnalysis.h"
#include "CodeBlock.h"
namespace JSC {
inline bool operandIsAlwaysLive(CodeBlock* codeBlock, int operand)
{
if (VirtualRegister(operand).isArgument())
return true;
return operand <= codeBlock->captureStart() && operand > codeBlock->captureEnd();
}
inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
{
VirtualRegister virtualReg(operand);
if (virtualReg.offset() > codeBlock->captureStart())
return out.get(virtualReg.toLocal());
size_t index = virtualReg.toLocal() - codeBlock->captureCount();
if (index >= out.numBits())
return false;
return out.get(index);
}
inline bool operandIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
{
return operandIsAlwaysLive(codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(codeBlock, out, operand);
}
} // namespace JSC
#endif // BytecodeLivenessAnalysisInlines_h
......@@ -354,6 +354,27 @@ public:
{
return m_needsActivation;
}
unsigned captureCount() const
{
if (!symbolTable())
return 0;
return symbolTable()->captureCount();
}
int captureStart() const
{
if (!symbolTable())
return 0;
return symbolTable()->captureStart();
}
int captureEnd() const
{
if (!symbolTable())
return 0;
return symbolTable()->captureEnd();
}
bool isCaptured(VirtualRegister operand, InlineCallFrame* = 0) const;
......
......@@ -116,7 +116,7 @@ void InlineCallFrame::dumpInContext(PrintStream& out, DumpContext* context) cons
else
out.print(", known callee: ", inContext(calleeRecovery.constant(), context));
out.print(", numArgs+this = ", arguments.size());
out.print(", stack >= r", stackOffset);
out.print(", stack < loc", VirtualRegister(stackOffset).toLocal());
out.print(">");
}
......
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FullBytecodeLiveness_h
#define FullBytecodeLiveness_h
#include <wtf/FastBitVector.h>
namespace JSC {
class BytecodeLivenessAnalysis;
typedef HashMap<unsigned, FastBitVector, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> BytecodeToBitmapMap;
class FullBytecodeLiveness {
public:
FullBytecodeLiveness() : m_codeBlock(0) { }
// We say "out" to refer to the bitvector that contains raw results for a bytecode
// instruction.
const FastBitVector& getOut(unsigned bytecodeIndex) const
{
BytecodeToBitmapMap::const_iterator iter = m_map.find(bytecodeIndex);
ASSERT(iter != m_map.end());
return iter->value;
}
bool operandIsLive(int operand, unsigned bytecodeIndex) const
{
return operandIsAlwaysLive(m_codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(m_codeBlock, getOut(bytecodeIndex), operand);
}
FastBitVector getLiveness(unsigned bytecodeIndex) const
{
return getLivenessInfo(m_codeBlock, getOut(bytecodeIndex));
}
private:
friend class BytecodeLivenessAnalysis;
CodeBlock* m_codeBlock;
BytecodeToBitmapMap m_map;
};
} // namespace JSC
#endif // FullBytecodeLiveness_h
......@@ -24,47 +24,37 @@
*/
#include "config.h"
#include "FTLValueSource.h"
#include "DFGAvailability.h"
#if ENABLE(FTL_JIT)
#if ENABLE(DFG_JIT)
namespace JSC { namespace FTL {
#include "DFGNode.h"
void ValueSource::dump(PrintStream& out) const
namespace JSC { namespace DFG {
void Availability::dump(PrintStream& out) const
{
switch (kind()) {
case SourceNotSet:
out.print("SourceNotSet");
return;
case ValueInJSStack:
out.print("ValueInJSStack:", virtualRegister());
return;
case Int32InJSStack:
out.print("Int32InJSStack:", virtualRegister());
return;
case Int52InJSStack:
out.print("Int52InJSStack:", virtualRegister());
return;
case DoubleInJSStack:
out.print("DoubleInJSStack:", virtualRegister());
return;
case SourceIsDead:
out.print("SourceIsDead");
out.print(m_flushedAt, "/");
if (nodeIsUndecided()) {
out.print("Undecided");
return;
case HaveNode:
out.print("Node(", node(), ")");
}
if (nodeIsUnavailable()) {
out.print("Unavailable");
return;
}
RELEASE_ASSERT_NOT_REACHED();
out.print(node());
}
void ValueSource::dumpInContext(PrintStream& out, DumpContext*) const
void Availability::dumpInContext(PrintStream& out, DumpContext*) const
{
dump(out);
}
} } // namespace JSC::FTL
} } // namespace JSC::DFG
#endif // ENABLE(FTL_JIT)
#endif // ENABLE(DFG_JIT)
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DFGAvailability_h
#define DFGAvailability_h
#if ENABLE(DFG_JIT)
#include "DFGFlushedAt.h"
#include "DFGVariableAccessData.h"
namespace JSC { namespace DFG {
struct Node;
class Availability {
public:
Availability()
: m_node(0)
, m_flushedAt(DeadFlush)
{
}