Title: [154290] trunk
Revision
154290
Author
[email protected]
Date
2013-08-19 12:40:13 -0700 (Mon, 19 Aug 2013)

Log Message

<https://webkit.org/b/119860> Crash during exception unwinding

Reviewed by Filip Pizlo.

Source/_javascript_Core:

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):

LayoutTests:

Add a test

* fast/js/dfg-activation-register-overwritten-in-throw-expected.txt: Added.
* fast/js/dfg-activation-register-overwritten-in-throw.html: Added.
* fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js: Added.
(g):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (154289 => 154290)


--- trunk/LayoutTests/ChangeLog	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/LayoutTests/ChangeLog	2013-08-19 19:40:13 UTC (rev 154290)
@@ -1,3 +1,16 @@
+2013-08-16  Oliver Hunt  <[email protected]>
+
+        <https://webkit.org/b/119860> Crash during exception unwinding
+
+        Reviewed by Filip Pizlo.
+
+        Add a test
+
+        * fast/js/dfg-activation-register-overwritten-in-throw-expected.txt: Added.
+        * fast/js/dfg-activation-register-overwritten-in-throw.html: Added.
+        * fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js: Added.
+        (g):
+
 2013-08-19  Chris Fleizach  <[email protected]>
 
         <https://webkit.org/b/119916> AX: WebKit is not exposing AXLanguage correctly

Added: trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt (0 => 154290)


--- trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw-expected.txt	2013-08-19 19:40:13 UTC (rev 154290)
@@ -0,0 +1,9 @@
+This tests that the DFG does not attempt to overwrite the activation register with undefined.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html (0 => 154290)


--- trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-activation-register-overwritten-in-throw.html	2013-08-19 19:40:13 UTC (rev 154290)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js (0 => 154290)


--- trunk/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-activation-register-overwritten-in-throw.js	2013-08-19 19:40:13 UTC (rev 154290)
@@ -0,0 +1,15 @@
+description(
+"This tests that the DFG does not attempt to overwrite the activation register with undefined."
+);
+
+function g() { 
+    (eval("-7") = 0);
+}
+ 
+while (!dfgCompiled({f:g})) {
+    try {
+        g()
+    } catch(e) {
+
+    }
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (154289 => 154290)


--- trunk/Source/_javascript_Core/ChangeLog	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-08-19 19:40:13 UTC (rev 154290)
@@ -1,3 +1,35 @@
+2013-08-16  Oliver Hunt  <[email protected]>
+
+        <https://webkit.org/b/119860> Crash during exception unwinding
+
+        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):
+
 2013-08-19  Víctor Manuel Jáquez Leal  <[email protected]>
 
         <https://webkit.org/b/120008> [GTK][ARM] _javascript_core compilation is broken

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h	2013-08-19 19:40:13 UTC (rev 154290)
@@ -78,8 +78,7 @@
     // 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:
     //

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2013-08-19 19:40:13 UTC (rev 154290)
@@ -1492,7 +1492,11 @@
     case InlineStart:
     case CountExecution:
         break;
-        
+
+    case Unreachable:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+
     case LastNodeType:
         RELEASE_ASSERT_NOT_REACHED();
         break;

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2013-08-19 19:40:13 UTC (rev 154290)
@@ -2864,13 +2864,15 @@
             LAST_OPCODE(op_end);
 
         case op_throw:
+            addToGraph(Throw, get(currentInstruction[1].u.operand));
             flushAllArgumentsAndCapturedVariablesInInlineStack();
-            addToGraph(Throw, get(currentInstruction[1].u.operand));
+            addToGraph(Unreachable);
             LAST_OPCODE(op_throw);
             
         case op_throw_static_error:
+            addToGraph(ThrowReferenceError);
             flushAllArgumentsAndCapturedVariablesInInlineStack();
-            addToGraph(ThrowReferenceError);
+            addToGraph(Unreachable);
             LAST_OPCODE(op_throw_static_error);
             
         case op_call:

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2013-08-19 19:40:13 UTC (rev 154290)
@@ -132,6 +132,7 @@
     case Throw:
     case ForceOSRExit:
     case Return:
+    case Unreachable:
         write(SideState);
         return;
 

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2013-08-19 19:40:13 UTC (rev 154290)
@@ -880,6 +880,7 @@
         case CountExecution:
         case ForceOSRExit:
         case CheckWatchdogTimer:
+        case Unreachable:
             break;
 #else
         default:

Modified: trunk/Source/_javascript_Core/dfg/DFGFlushLivenessAnalysisPhase.cpp (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGFlushLivenessAnalysisPhase.cpp	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGFlushLivenessAnalysisPhase.cpp	2013-08-19 19:40:13 UTC (rev 154290)
@@ -49,7 +49,7 @@
         ASSERT(m_graph.m_form == SSA);
         
         // Liveness is a backwards analysis; the roots are the blocks that
-        // end in a terminal (Return/Throw/ThrowReferenceError). For now, we
+        // end in a terminal (Return/Unreachable). For now, we
         // use a fixpoint formulation since liveness is a rapid analysis with
         // convergence guaranteed after O(connectivity).
         

Modified: trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2013-08-19 19:40:13 UTC (rev 154290)
@@ -440,11 +440,10 @@
     }
         
     case Return:
-    case Throw:
-    case ThrowReferenceError:
+    case Unreachable:
         ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
         return false;
-        
+
     default:
         RELEASE_ASSERT_NOT_REACHED();
         return false;

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2013-08-19 19:40:13 UTC (rev 154290)
@@ -747,8 +747,7 @@
         case Branch:
         case Switch:
         case Return:
-        case Throw:
-        case ThrowReferenceError:
+        case Unreachable:
             return true;
         default:
             return false;

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2013-08-19 19:40:13 UTC (rev 154290)
@@ -243,13 +243,16 @@
     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(Switch, NodeMustGenerate) \
     macro(Return, NodeMustGenerate) \
-    macro(Throw, NodeMustGenerate) \
-    macro(ThrowReferenceError, NodeMustGenerate) \
+    macro(Unreachable, NodeMustGenerate) \
     \
     /* Count execution. */\
     macro(CountExecution, NodeMustGenerate) \

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2013-08-19 19:40:13 UTC (rev 154290)
@@ -542,6 +542,7 @@
         case Phantom:
         case PutGlobalVar:
         case CheckWatchdogTimer:
+        case Unreachable:
             break;
             
         // These gets ignored because it doesn't do anything.

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2013-08-19 19:40:13 UTC (rev 154290)
@@ -231,6 +231,7 @@
     case ForceOSRExit:
     case CheckWatchdogTimer:
     case StringFromCharCode:
+    case Unreachable:
         return true;
         
     case GetByVal:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2013-08-19 19:40:13 UTC (rev 154290)
@@ -4778,6 +4778,10 @@
         noResult(node);
         break;
 
+    case Unreachable:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+
     case LastNodeType:
     case Phi:
     case Upsilon:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (154289 => 154290)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2013-08-19 19:34:25 UTC (rev 154289)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2013-08-19 19:40:13 UTC (rev 154290)
@@ -4641,6 +4641,10 @@
         // This is a no-op.
         noResult(node);
         break;
+
+    case Unreachable:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
         
     case LastNodeType:
     case Phi:
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to