diff options
author | Oliver Hunt <oliver@apple.com> | 2014-07-04 14:15:56 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-07-08 04:42:44 +0200 |
commit | cb0f788597a946438bfd993850426f848ff39aa2 (patch) | |
tree | 0791094034bacf0127b03ba23afcfcd1015f808b | |
parent | 11567a6b05de1c524db04bd6ecec6786aacace35 (diff) | |
download | qtwebkit-cb0f788597a946438bfd993850426f848ff39aa2.tar.gz |
Crash during exception unwinding
https://webkit.org/b/119860
Reviewed by Filip Pizlo.
Add an "Unreachable" NodeType, and then rearrange op_throw and op_throw_reference_error
to plant Throw or ThrowReferenceError followed by a flush and then the Unreachable node.
We need this so that Throw and ThrowReferenceError no longer need to be treated as
terminals and the subsequent flush keeps the activation (and other registers) live.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::isTerminal):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
Change-Id: Idb894e780cd3ebe15515d1796c58a339ae54d55f
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154290 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGAbstractState.cpp | 11 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGAbstractState.h | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGFixupPhase.cpp | 1 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGNode.h | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGNodeType.h | 7 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp | 1 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp | 4 |
9 files changed, 28 insertions, 12 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp index 2ac79c7c9..ab2a5af98 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp @@ -1567,7 +1567,11 @@ bool AbstractState::executeEffects(unsigned indexInBlock, Node* node) case Nop: case CountExecution: break; - + + case Unreachable: + RELEASE_ASSERT_NOT_REACHED(); + break; + case LastNodeType: RELEASE_ASSERT_NOT_REACHED(); break; @@ -1778,11 +1782,10 @@ inline bool AbstractState::mergeToSuccessors(Graph& graph, BasicBlock* basicBloc } case Return: - case Throw: - case ThrowReferenceError: + case Unreachable: ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection); return false; - + default: RELEASE_ASSERT_NOT_REACHED(); return false; diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h index de1f17d1f..cbb213a6f 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.h +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h @@ -156,8 +156,7 @@ public: // basic blocks) interrogate the basic block's notion of the state at the head. // Stores to local variables are handled in endBasicBlock(). This returns true // if execution should continue past this node. Notably, it will return true - // for block terminals, so long as those terminals are not Return or variants - // of Throw. + // for block terminals, so long as those terminals are not Return or Unreachable. // // This is guaranteed to be equivalent to doing: // diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp index a76d5f250..c3e041c26 100644 --- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp +++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp @@ -3031,13 +3031,15 @@ bool ByteCodeParser::parseBlock(unsigned limit) LAST_OPCODE(op_end); case op_throw: - flushAllArgumentsAndCapturedVariablesInInlineStack(); addToGraph(Throw, get(currentInstruction[1].u.operand)); + flushAllArgumentsAndCapturedVariablesInInlineStack(); + addToGraph(Unreachable); LAST_OPCODE(op_throw); case op_throw_static_error: - flushAllArgumentsAndCapturedVariablesInInlineStack(); addToGraph(ThrowReferenceError); + flushAllArgumentsAndCapturedVariablesInInlineStack(); + addToGraph(Unreachable); LAST_OPCODE(op_throw_static_error); case op_call: diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index ac2842322..ea201d73b 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -873,6 +873,7 @@ private: case CountExecution: case ForceOSRExit: case CheckWatchdogTimer: + case Unreachable: break; #else default: diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h index f45d3fa68..28eccc07a 100644 --- a/Source/JavaScriptCore/dfg/DFGNode.h +++ b/Source/JavaScriptCore/dfg/DFGNode.h @@ -677,8 +677,7 @@ struct Node { case Jump: case Branch: case Return: - case Throw: - case ThrowReferenceError: + case Unreachable: return true; default: return false; diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h index 9039e3f5f..2a4707377 100644 --- a/Source/JavaScriptCore/dfg/DFGNodeType.h +++ b/Source/JavaScriptCore/dfg/DFGNodeType.h @@ -250,12 +250,15 @@ namespace JSC { namespace DFG { macro(NewFunction, NodeResultJS) \ macro(NewFunctionExpression, NodeResultJS) \ \ + /* These aren't terminals but always exit */ \ + macro(Throw, NodeMustGenerate) \ + macro(ThrowReferenceError, NodeMustGenerate) \ + \ /* Block terminals. */\ macro(Jump, NodeMustGenerate) \ macro(Branch, NodeMustGenerate) \ macro(Return, NodeMustGenerate) \ - macro(Throw, NodeMustGenerate) \ - macro(ThrowReferenceError, NodeMustGenerate) \ + macro(Unreachable, NodeMustGenerate) \ \ macro(GarbageValue, NodeResultJS | NodeClobbersWorld) \ \ diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp index 980e6b447..01a9e4e42 100644 --- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp @@ -539,6 +539,7 @@ private: case PutGlobalVar: case PutGlobalVarCheck: case CheckWatchdogTimer: + case Unreachable: break; // These gets ignored because it doesn't do anything. diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp index 5fc35cb73..871a59c2a 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp @@ -4964,6 +4964,10 @@ void SpeculativeJIT::compile(Node* node) noResult(node); break; + case Unreachable: + RELEASE_ASSERT_NOT_REACHED(); + break; + case Nop: case LastNodeType: RELEASE_ASSERT_NOT_REACHED(); diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp index ab9da9732..fd3c2953c 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp @@ -4791,6 +4791,10 @@ void SpeculativeJIT::compile(Node* node) // This is a no-op. noResult(node); break; + + case Unreachable: + RELEASE_ASSERT_NOT_REACHED(); + break; case Nop: RELEASE_ASSERT_NOT_REACHED(); |