summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Hunt <oliver@apple.com>2014-07-04 14:15:56 +0200
committerAllan Sandfeld Jensen <allan.jensen@digia.com>2014-07-08 04:42:44 +0200
commitcb0f788597a946438bfd993850426f848ff39aa2 (patch)
tree0791094034bacf0127b03ba23afcfcd1015f808b
parent11567a6b05de1c524db04bd6ecec6786aacace35 (diff)
downloadqtwebkit-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.cpp11
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.h3
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp6
-rw-r--r--Source/JavaScriptCore/dfg/DFGFixupPhase.cpp1
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h3
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeType.h7
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp1
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp4
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();