<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[213107] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/213107">213107</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2017-02-27 17:20:54 -0800 (Mon, 27 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Introduce a VM Traps mechanism and refactor Watchdog to use it.
https://bugs.webkit.org/show_bug.cgi?id=168842

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Currently, the traps mechanism is only used for the JSC watchdog, and for
asynchronous termination requests (which is currently only used for worker
threads termination).

This first cut of the traps mechanism still relies on polling from DFG and FTL
code.  This is done to keep the patch as small as possible.  The work to do
a non-polling version of the traps mechanism for DFG and FTL code is deferred to
another patch.

In this patch, worker threads still need to set the VM::m_needAsynchronousTerminationSupport
flag to enable the traps polling in the DFG and FTL code.  When we have the
non-polling version of the DFG and FTL traps mechanism, we can remove the use of
the VM::m_needAsynchronousTerminationSupport flag.

Note: this patch also separates asynchronous termination support from the JSC
watchdog.  This separation allows us to significantly simplify the locking
requirements in the watchdog code, and make it easier to reason about its
correctness.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitLoopHint):
(JSC::BytecodeGenerator::emitCheckTraps):
(JSC::BytecodeGenerator::emitWatchdog): Deleted.
* bytecompiler/BytecodeGenerator.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCheckTraps):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckTraps):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckWatchdogTimer): Deleted.
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeProgram):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::execute):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_check_traps):
(JSC::JIT::emitSlow_op_check_traps):
(JSC::JIT::emit_op_watchdog): Deleted.
(JSC::JIT::emitSlow_op_watchdog): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/VM.cpp:
(JSC::VM::~VM):
(JSC::VM::ensureWatchdog):
(JSC::VM::handleTraps):
* runtime/VM.h:
(JSC::VM::ownerThread):
(JSC::VM::needTrapHandling):
(JSC::VM::needTrapHandlingAddress):
(JSC::VM::notifyNeedTermination):
(JSC::VM::notifyNeedWatchdogCheck):
(JSC::VM::needAsynchronousTerminationSupport):
(JSC::VM::setNeedAsynchronousTerminationSupport):
* runtime/VMInlines.h:
(JSC::VM::shouldTriggerTermination): Deleted.
* runtime/VMTraps.cpp: Added.
(JSC::VMTraps::fireTrap):
(JSC::VMTraps::takeTrap):
* runtime/VMTraps.h: Added.
(JSC::VMTraps::needTrapHandling):
(JSC::VMTraps::needTrapHandlingAddress):
(JSC::VMTraps::hasTrapForEvent):
(JSC::VMTraps::setTrapForEvent):
(JSC::VMTraps::clearTrapForEvent):
* runtime/Watchdog.cpp:
(JSC::Watchdog::Watchdog):
(JSC::Watchdog::setTimeLimit):
(JSC::Watchdog::shouldTerminate):
(JSC::Watchdog::enteredVM):
(JSC::Watchdog::exitedVM):
(JSC::Watchdog::startTimer):
(JSC::Watchdog::stopTimer):
(JSC::Watchdog::willDestroyVM):
(JSC::Watchdog::terminateSoon): Deleted.
(JSC::Watchdog::shouldTerminateSlow): Deleted.
* runtime/Watchdog.h:
(JSC::Watchdog::shouldTerminate): Deleted.
(JSC::Watchdog::timerDidFireAddress): Deleted.

Source/WebCore:

No new tests needed because this is a re-implementation of existing functionality.

* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::WorkerScriptController):
(WebCore::WorkerScriptController::scheduleExecutionTermination):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMInlinesh">trunk/Source/JavaScriptCore/runtime/VMInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeWatchdogcpp">trunk/Source/JavaScriptCore/runtime/Watchdog.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeWatchdogh">trunk/Source/JavaScriptCore/runtime/Watchdog.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsWorkerScriptControllercpp">trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMTrapscpp">trunk/Source/JavaScriptCore/runtime/VMTraps.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMTrapsh">trunk/Source/JavaScriptCore/runtime/VMTraps.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -904,6 +904,7 @@
</span><span class="cx">     runtime/TypeofType.cpp
</span><span class="cx">     runtime/VM.cpp
</span><span class="cx">     runtime/VMEntryScope.cpp
</span><ins>+    runtime/VMTraps.cpp
</ins><span class="cx">     runtime/VarOffset.cpp
</span><span class="cx">     runtime/Watchdog.cpp
</span><span class="cx">     runtime/WeakMapConstructor.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,3 +1,132 @@
</span><ins>+2017-02-27  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Introduce a VM Traps mechanism and refactor Watchdog to use it.
+        https://bugs.webkit.org/show_bug.cgi?id=168842
+
+        Reviewed by Filip Pizlo.
+
+        Currently, the traps mechanism is only used for the JSC watchdog, and for
+        asynchronous termination requests (which is currently only used for worker
+        threads termination).
+
+        This first cut of the traps mechanism still relies on polling from DFG and FTL
+        code.  This is done to keep the patch as small as possible.  The work to do
+        a non-polling version of the traps mechanism for DFG and FTL code is deferred to
+        another patch.
+
+        In this patch, worker threads still need to set the VM::m_needAsynchronousTerminationSupport
+        flag to enable the traps polling in the DFG and FTL code.  When we have the
+        non-polling version of the DFG and FTL traps mechanism, we can remove the use of
+        the VM::m_needAsynchronousTerminationSupport flag.
+
+        Note: this patch also separates asynchronous termination support from the JSC
+        watchdog.  This separation allows us to significantly simplify the locking
+        requirements in the watchdog code, and make it easier to reason about its
+        correctness.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitLoopHint):
+        (JSC::BytecodeGenerator::emitCheckTraps):
+        (JSC::BytecodeGenerator::emitWatchdog): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCheckTraps):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCheckTraps):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCheckWatchdogTimer): Deleted.
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::executeProgram):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        (JSC::Interpreter::execute):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_check_traps):
+        (JSC::JIT::emitSlow_op_check_traps):
+        (JSC::JIT::emit_op_watchdog): Deleted.
+        (JSC::JIT::emitSlow_op_watchdog): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/VM.cpp:
+        (JSC::VM::~VM):
+        (JSC::VM::ensureWatchdog):
+        (JSC::VM::handleTraps):
+        * runtime/VM.h:
+        (JSC::VM::ownerThread):
+        (JSC::VM::needTrapHandling):
+        (JSC::VM::needTrapHandlingAddress):
+        (JSC::VM::notifyNeedTermination):
+        (JSC::VM::notifyNeedWatchdogCheck):
+        (JSC::VM::needAsynchronousTerminationSupport):
+        (JSC::VM::setNeedAsynchronousTerminationSupport):
+        * runtime/VMInlines.h:
+        (JSC::VM::shouldTriggerTermination): Deleted.
+        * runtime/VMTraps.cpp: Added.
+        (JSC::VMTraps::fireTrap):
+        (JSC::VMTraps::takeTrap):
+        * runtime/VMTraps.h: Added.
+        (JSC::VMTraps::needTrapHandling):
+        (JSC::VMTraps::needTrapHandlingAddress):
+        (JSC::VMTraps::hasTrapForEvent):
+        (JSC::VMTraps::setTrapForEvent):
+        (JSC::VMTraps::clearTrapForEvent):
+        * runtime/Watchdog.cpp:
+        (JSC::Watchdog::Watchdog):
+        (JSC::Watchdog::setTimeLimit):
+        (JSC::Watchdog::shouldTerminate):
+        (JSC::Watchdog::enteredVM):
+        (JSC::Watchdog::exitedVM):
+        (JSC::Watchdog::startTimer):
+        (JSC::Watchdog::stopTimer):
+        (JSC::Watchdog::willDestroyVM):
+        (JSC::Watchdog::terminateSoon): Deleted.
+        (JSC::Watchdog::shouldTerminateSlow): Deleted.
+        * runtime/Watchdog.h:
+        (JSC::Watchdog::shouldTerminate): Deleted.
+        (JSC::Watchdog::timerDidFireAddress): Deleted.
+
</ins><span class="cx"> 2017-02-27  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r213019.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -2396,6 +2396,8 @@
</span><span class="cx">                 FE6491391D78F3AF00A694D4 /* ExceptionScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6491381D78F3A300A694D4 /* ExceptionScope.cpp */; };
</span><span class="cx">                 FE68C6371B90DE040042BCB3 /* MacroAssemblerPrinter.h in Headers */ = {isa = PBXBuildFile; fileRef = FE68C6361B90DDD90042BCB3 /* MacroAssemblerPrinter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FE68C6381B90DE0B0042BCB3 /* MacroAssemblerPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE68C6351B90DDD90042BCB3 /* MacroAssemblerPrinter.cpp */; };
</span><ins>+                FE6F56DE1E64EAD600D17801 /* VMTraps.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6F56DD1E64E92000D17801 /* VMTraps.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                FE6F56DF1E64EADB00D17801 /* VMTraps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6F56DC1E64E92000D17801 /* VMTraps.cpp */; };
</ins><span class="cx">                 FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */; };
</span><span class="cx">                 FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FE7C41961B97FC4B00F4D598 /* PingPongStackOverflowTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */; };
</span><span class="lines">@@ -4965,6 +4967,8 @@
</span><span class="cx">                 FE6491381D78F3A300A694D4 /* ExceptionScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionScope.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE68C6351B90DDD90042BCB3 /* MacroAssemblerPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerPrinter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE68C6361B90DDD90042BCB3 /* MacroAssemblerPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerPrinter.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                FE6F56DC1E64E92000D17801 /* VMTraps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMTraps.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                FE6F56DD1E64E92000D17801 /* VMTraps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMTraps.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapVerifier.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapVerifier.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE80C1961D775B27008510C0 /* CatchScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CatchScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6871,6 +6875,8 @@
</span><span class="cx">                                 FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */,
</span><span class="cx">                                 FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */,
</span><span class="cx">                                 FE90BB3A1B7CF64E006B3F03 /* VMInlines.h */,
</span><ins>+                                FE6F56DC1E64E92000D17801 /* VMTraps.cpp */,
+                                FE6F56DD1E64E92000D17801 /* VMTraps.h */,
</ins><span class="cx">                                 FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */,
</span><span class="cx">                                 FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
</span><span class="cx">                                 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
</span><span class="lines">@@ -8435,6 +8441,7 @@
</span><span class="cx">                                 E3FF75331D9CEA1800C7E16D /* DOMJITGetterSetter.h in Headers */,
</span><span class="cx">                                 E35CA1541DBC3A5C00F83516 /* DOMJITHeapRange.h in Headers */,
</span><span class="cx">                                 E3C08E3C1DA41B810039478F /* DOMJITPatchpoint.h in Headers */,
</span><ins>+                                FE6F56DE1E64EAD600D17801 /* VMTraps.h in Headers */,
</ins><span class="cx">                                 E37AD83C1DA4928600F3D412 /* DOMJITPatchpointParams.h in Headers */,
</span><span class="cx">                                 E37AD83D1DA4928600F3D412 /* DOMJITReg.h in Headers */,
</span><span class="cx">                                 E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */,
</span><span class="lines">@@ -9988,6 +9995,7 @@
</span><span class="cx">                                 149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
</span><span class="cx">                                 A5FC84B31D1DDAD9006B5C46 /* DebuggerLocation.cpp in Sources */,
</span><span class="cx">                                 A5A1A0951D8CB341004C2EB8 /* DebuggerParseData.cpp in Sources */,
</span><ins>+                                FE6F56DF1E64EADB00D17801 /* VMTraps.cpp in Sources */,
</ins><span class="cx">                                 0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */,
</span><span class="cx">                                 2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */,
</span><span class="cx">                                 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_create_rest&quot;, &quot;length&quot;: 4 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_get_rest_length&quot;, &quot;length&quot;: 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_yield&quot;, &quot;length&quot; : 4 },
</span><del>-            { &quot;name&quot; : &quot;op_watchdog&quot;, &quot;length&quot; : 1 },
</del><ins>+            { &quot;name&quot; : &quot;op_check_traps&quot;, &quot;length&quot; : 1 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_log_shadow_chicken_prologue&quot;, &quot;length&quot; : 2},
</span><span class="cx">             { &quot;name&quot; : &quot;op_log_shadow_chicken_tail&quot;, &quot;length&quot; : 3}
</span><span class="cx">         ]
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx">     case op_create_direct_arguments:
</span><span class="cx">     case op_create_cloned_arguments:
</span><span class="cx">     case op_get_rest_length:
</span><del>-    case op_watchdog:
</del><ins>+    case op_check_traps:
</ins><span class="cx">     case op_get_argument:
</span><span class="cx">         return;
</span><span class="cx">     case op_assert:
</span><span class="lines">@@ -359,7 +359,7 @@
</span><span class="cx">     case op_profile_control_flow:
</span><span class="cx">     case op_put_to_arguments:
</span><span class="cx">     case op_set_function_name:
</span><del>-    case op_watchdog:
</del><ins>+    case op_check_traps:
</ins><span class="cx">     case op_log_shadow_chicken_prologue:
</span><span class="cx">     case op_log_shadow_chicken_tail:
</span><span class="cx">     case op_yield:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1386,8 +1386,8 @@
</span><span class="cx">             printLocationAndOp(out, exec, location, it, &quot;loop_hint&quot;);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        case op_watchdog: {
-            printLocationAndOp(out, exec, location, it, &quot;watchdog&quot;);
</del><ins>+        case op_check_traps: {
+            printLocationAndOp(out, exec, location, it, &quot;check_traps&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case op_log_shadow_chicken_prologue: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -195,7 +195,7 @@
</span><span class="cx"> 
</span><span class="cx">     allocateAndEmitScope();
</span><span class="cx"> 
</span><del>-    emitWatchdog();
</del><ins>+    emitCheckTraps();
</ins><span class="cx"> 
</span><span class="cx">     const FunctionStack&amp; functionStack = programNode-&gt;functionStack();
</span><span class="cx"> 
</span><span class="lines">@@ -329,7 +329,7 @@
</span><span class="cx"> 
</span><span class="cx">     allocateAndEmitScope();
</span><span class="cx"> 
</span><del>-    emitWatchdog();
</del><ins>+    emitCheckTraps();
</ins><span class="cx">     
</span><span class="cx">     if (functionNameIsInScope(functionNode-&gt;ident(), functionNode-&gt;functionMode())) {
</span><span class="cx">         ASSERT(parseMode != SourceParseMode::GeneratorBodyMode);
</span><span class="lines">@@ -761,7 +761,7 @@
</span><span class="cx"> 
</span><span class="cx">     allocateAndEmitScope();
</span><span class="cx"> 
</span><del>-    emitWatchdog();
</del><ins>+    emitCheckTraps();
</ins><span class="cx">     
</span><span class="cx">     const DeclarationStacks::FunctionStack&amp; functionStack = evalNode-&gt;functionStack();
</span><span class="cx">     for (size_t i = 0; i &lt; functionStack.size(); ++i)
</span><span class="lines">@@ -846,7 +846,7 @@
</span><span class="cx"> 
</span><span class="cx">     allocateAndEmitScope();
</span><span class="cx"> 
</span><del>-    emitWatchdog();
</del><ins>+    emitCheckTraps();
</ins><span class="cx">     
</span><span class="cx">     m_calleeRegister.setIndex(CallFrameSlot::callee);
</span><span class="cx"> 
</span><span class="lines">@@ -1269,13 +1269,13 @@
</span><span class="cx"> void BytecodeGenerator::emitLoopHint()
</span><span class="cx"> {
</span><span class="cx">     emitOpcode(op_loop_hint);
</span><del>-    emitWatchdog();
</del><ins>+    emitCheckTraps();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BytecodeGenerator::emitWatchdog()
</del><ins>+void BytecodeGenerator::emitCheckTraps()
</ins><span class="cx"> {
</span><del>-    if (vm()-&gt;watchdog())
-        emitOpcode(op_watchdog);
</del><ins>+    if (vm()-&gt;watchdog() || vm()-&gt;needAsynchronousTerminationSupport())
+        emitOpcode(op_check_traps);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BytecodeGenerator::retrieveLastBinaryOp(int&amp; dstIndex, int&amp; src1Index, int&amp; src2Index)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008-2009, 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2008 Cameron Zwarich &lt;cwzwarich@uwaterloo.ca&gt;
</span><span class="cx">  * Copyright (C) 2012 Igalia, S.L.
</span><span class="cx">  *
</span><span class="lines">@@ -704,7 +704,7 @@
</span><span class="cx">         void emitJumpIfNotFunctionApply(RegisterID* cond, Label&amp; target);
</span><span class="cx"> 
</span><span class="cx">         void emitEnter();
</span><del>-        void emitWatchdog();
</del><ins>+        void emitCheckTraps();
</ins><span class="cx"> 
</span><span class="cx">         RegisterID* emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
</span><span class="cx">         RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -2914,7 +2914,7 @@
</span><span class="cx">         m_state.setStructureClobberState(StructuresAreWatched);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><del>-    case CheckWatchdogTimer:
</del><ins>+    case CheckTraps:
</ins><span class="cx">     case LogShadowChickenPrologue:
</span><span class="cx">     case LogShadowChickenTail:
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -5383,9 +5383,9 @@
</span><span class="cx">             NEXT_OPCODE(op_loop_hint);
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        case op_watchdog: {
-            addToGraph(CheckWatchdogTimer);
-            NEXT_OPCODE(op_watchdog); 
</del><ins>+        case op_check_traps: {
+            addToGraph(CheckTraps);
+            NEXT_OPCODE(op_check_traps);
</ins><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         case op_create_lexical_environment: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -187,7 +187,7 @@
</span><span class="cx">     case op_jngreater:
</span><span class="cx">     case op_jngreatereq:
</span><span class="cx">     case op_loop_hint:
</span><del>-    case op_watchdog:
</del><ins>+    case op_check_traps:
</ins><span class="cx">     case op_ret:
</span><span class="cx">     case op_end:
</span><span class="cx">     case op_new_object:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1411,7 +1411,7 @@
</span><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case CountExecution:
</span><del>-    case CheckWatchdogTimer:
</del><ins>+    case CheckTraps:
</ins><span class="cx">         read(InternalState);
</span><span class="cx">         write(InternalState);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -190,7 +190,7 @@
</span><span class="cx">     case Throw:
</span><span class="cx">     case CountExecution:
</span><span class="cx">     case ForceOSRExit:
</span><del>-    case CheckWatchdogTimer:
</del><ins>+    case CheckTraps:
</ins><span class="cx">     case StringFromCharCode:
</span><span class="cx">     case MapHash:
</span><span class="cx">     case GetMapBucket:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1868,7 +1868,7 @@
</span><span class="cx">         case ForceOSRExit:
</span><span class="cx">         case CheckBadCell:
</span><span class="cx">         case CheckNotEmpty:
</span><del>-        case CheckWatchdogTimer:
</del><ins>+        case CheckTraps:
</ins><span class="cx">         case Unreachable:
</span><span class="cx">         case ExtractOSREntryLocal:
</span><span class="cx">         case LoopHint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -391,8 +391,8 @@
</span><span class="cx">     /* flow. */\
</span><span class="cx">     macro(BottomValue, NodeResultJS) \
</span><span class="cx">     \
</span><del>-    /* Checks the watchdog timer. If the timer has fired, we call operation operationHandleWatchdogTimer*/ \
-    macro(CheckWatchdogTimer, NodeMustGenerate) \
</del><ins>+    /* Checks for VM traps. If there is a trap, we call operation operationHandleTraps */ \
+    macro(CheckTraps, NodeMustGenerate) \
</ins><span class="cx">     /* Write barriers */\
</span><span class="cx">     macro(StoreBarrier, NodeMustGenerate) \
</span><span class="cx">     macro(FencedStoreBarrier, NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1101,7 +1101,7 @@
</span><span class="cx">         case Phantom:
</span><span class="cx">         case Check:
</span><span class="cx">         case PutGlobalVariable:
</span><del>-        case CheckWatchdogTimer:
</del><ins>+        case CheckTraps:
</ins><span class="cx">         case LogShadowChickenPrologue:
</span><span class="cx">         case LogShadowChickenTail:
</span><span class="cx">         case Unreachable:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -317,7 +317,7 @@
</span><span class="cx">     case ThrowStaticError:
</span><span class="cx">     case CountExecution:
</span><span class="cx">     case ForceOSRExit:
</span><del>-    case CheckWatchdogTimer:
</del><ins>+    case CheckTraps:
</ins><span class="cx">     case LogShadowChickenPrologue:
</span><span class="cx">     case LogShadowChickenTail:
</span><span class="cx">     case StringFromCharCode:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1895,7 +1895,18 @@
</span><span class="cx">             dumpContext.dump(WTF::dataFile());
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+    
+void SpeculativeJIT::compileCheckTraps(Node*)
+{
+    GPRTemporary unused(this);
+    GPRReg unusedGPR = unused.gpr();
</ins><span class="cx"> 
</span><ins>+    JITCompiler::Jump needTrapHandling = m_jit.branchTest8(JITCompiler::NonZero,
+        JITCompiler::AbsoluteAddress(m_jit.vm()-&gt;needTrapHandlingAddress()));
+
+    addSlowPathGenerator(slowPathCall(needTrapHandling, this, operationHandleTraps, unusedGPR));
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileDoublePutByVal(Node* node, SpeculateCellOperand&amp; base, SpeculateStrictInt32Operand&amp; property)
</span><span class="cx"> {
</span><span class="cx">     Edge child3 = m_jit.graph().varArgChild(node, 2);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -762,6 +762,8 @@
</span><span class="cx">         return lastNode-&gt;op() == Branch &amp;&amp; lastNode-&gt;child1() == m_currentNode ? m_block-&gt;size() - 1 : UINT_MAX;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void compileCheckTraps(Node*);
+
</ins><span class="cx">     void compileMovHint(Node*);
</span><span class="cx">     void compileMovHintAndCheck(Node*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2011 Intel Corporation. All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -5543,17 +5543,9 @@
</span><span class="cx">         emitInvalidationPoint(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><del>-    case CheckWatchdogTimer: {
-        ASSERT(m_jit.vm()-&gt;watchdog());
-        GPRTemporary unused(this);
-        GPRReg unusedGPR = unused.gpr();
-        
-        JITCompiler::Jump timerDidFire = m_jit.branchTest8(JITCompiler::NonZero,
-            JITCompiler::AbsoluteAddress(m_jit.vm()-&gt;watchdog()-&gt;timerDidFireAddress()));
-        
-        addSlowPathGenerator(slowPathCall(timerDidFire, this, operationHandleWatchdogTimer, unusedGPR));
</del><ins>+    case CheckTraps:
+        compileCheckTraps(node);
</ins><span class="cx">         break;
</span><del>-    }
</del><span class="cx"> 
</span><span class="cx">     case CountExecution:
</span><span class="cx">         m_jit.add64(TrustedImm32(1), MacroAssembler::AbsoluteAddress(node-&gt;executionCounter()-&gt;address()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -5327,17 +5327,9 @@
</span><span class="cx">         emitInvalidationPoint(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><del>-    case CheckWatchdogTimer: {
-        ASSERT(m_jit.vm()-&gt;watchdog());
-        GPRTemporary unused(this);
-        GPRReg unusedGPR = unused.gpr();
-
-        JITCompiler::Jump timerDidFire = m_jit.branchTest8(JITCompiler::NonZero,
-            JITCompiler::AbsoluteAddress(m_jit.vm()-&gt;watchdog()-&gt;timerDidFireAddress()));
-
-        addSlowPathGenerator(slowPathCall(timerDidFire, this, operationHandleWatchdogTimer, unusedGPR));
</del><ins>+    case CheckTraps:
+        compileCheckTraps(node);
</ins><span class="cx">         break;
</span><del>-    }
</del><span class="cx"> 
</span><span class="cx">     case Phantom:
</span><span class="cx">     case Check:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -134,7 +134,7 @@
</span><span class="cx">     case CheckBadCell:
</span><span class="cx">     case CheckNotEmpty:
</span><span class="cx">     case CheckStringIdent:
</span><del>-    case CheckWatchdogTimer:
</del><ins>+    case CheckTraps:
</ins><span class="cx">     case StringCharCodeAt:
</span><span class="cx">     case StringFromCharCode:
</span><span class="cx">     case AllocatePropertyStorage:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1021,8 +1021,8 @@
</span><span class="cx">         case MaterializeCreateActivation:
</span><span class="cx">             compileMaterializeCreateActivation();
</span><span class="cx">             break;
</span><del>-        case CheckWatchdogTimer:
-            compileCheckWatchdogTimer();
</del><ins>+        case CheckTraps:
+            compileCheckTraps();
</ins><span class="cx">             break;
</span><span class="cx">         case CreateRest:
</span><span class="cx">             compileCreateRest();
</span><span class="lines">@@ -8983,20 +8983,20 @@
</span><span class="cx">         setJSValue(activation);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void compileCheckWatchdogTimer()
</del><ins>+    void compileCheckTraps()
</ins><span class="cx">     {
</span><del>-        LBasicBlock timerDidFire = m_out.newBlock();
</del><ins>+        LBasicBlock needTrapHandling = m_out.newBlock();
</ins><span class="cx">         LBasicBlock continuation = m_out.newBlock();
</span><span class="cx">         
</span><del>-        LValue state = m_out.load8ZeroExt32(m_out.absolute(vm().watchdog()-&gt;timerDidFireAddress()));
</del><ins>+        LValue state = m_out.load8ZeroExt32(m_out.absolute(vm().needTrapHandlingAddress()));
</ins><span class="cx">         m_out.branch(m_out.isZero32(state),
</span><del>-            usually(continuation), rarely(timerDidFire));
</del><ins>+            usually(continuation), rarely(needTrapHandling));
</ins><span class="cx"> 
</span><del>-        LBasicBlock lastNext = m_out.appendTo(timerDidFire, continuation);
</del><ins>+        LBasicBlock lastNext = m_out.appendTo(needTrapHandling, continuation);
</ins><span class="cx"> 
</span><span class="cx">         lazySlowPath(
</span><span class="cx">             [=] (const Vector&lt;Location&gt;&amp;) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><del>-                return createLazyCallGenerator(operationHandleWatchdogTimer, InvalidGPRReg);
</del><ins>+                return createLazyCallGenerator(operationHandleTraps, InvalidGPRReg);
</ins><span class="cx">             });
</span><span class="cx">         m_out.jump(continuation);
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -860,8 +860,10 @@
</span><span class="cx">         codeBlock = jsCast&lt;ProgramCodeBlock*&gt;(tempCodeBlock);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.shouldTriggerTermination(callFrame)))
-        return throwTerminatedExecutionException(callFrame, throwScope);
</del><ins>+    if (UNLIKELY(vm.needTrapHandling())) {
+        vm.handleTraps(callFrame);
+        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+    }
</ins><span class="cx"> 
</span><span class="cx">     if (scope-&gt;structure()-&gt;isUncacheableDictionary())
</span><span class="cx">         scope-&gt;flattenDictionaryObject(vm);
</span><span class="lines">@@ -918,8 +920,10 @@
</span><span class="cx">     } else
</span><span class="cx">         newCodeBlock = 0;
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.shouldTriggerTermination(callFrame)))
-        return throwTerminatedExecutionException(callFrame, throwScope);
</del><ins>+    if (UNLIKELY(vm.needTrapHandling())) {
+        vm.handleTraps(callFrame);
+        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+    }
</ins><span class="cx"> 
</span><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="cx">     protoCallFrame.init(newCodeBlock, function, thisValue, argsCount, args.data());
</span><span class="lines">@@ -981,8 +985,10 @@
</span><span class="cx">     } else
</span><span class="cx">         newCodeBlock = 0;
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.shouldTriggerTermination(callFrame)))
-        return throwTerminatedExecutionException(callFrame, throwScope);
</del><ins>+    if (UNLIKELY(vm.needTrapHandling())) {
+        vm.handleTraps(callFrame);
+        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+    }
</ins><span class="cx"> 
</span><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="cx">     protoCallFrame.init(newCodeBlock, constructor, newTarget, argsCount, args.data());
</span><span class="lines">@@ -1043,8 +1049,10 @@
</span><span class="cx"> 
</span><span class="cx">     StackStats::CheckPoint stackCheckPoint;
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.shouldTriggerTermination(closure.oldCallFrame)))
-        return throwTerminatedExecutionException(closure.oldCallFrame, throwScope);
</del><ins>+    if (UNLIKELY(vm.needTrapHandling())) {
+        vm.handleTraps(closure.oldCallFrame);
+        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+    }
</ins><span class="cx"> 
</span><span class="cx">     // Execute the code:
</span><span class="cx">     JSValue result = closure.functionExecutable-&gt;generatedJITCodeForCall()-&gt;execute(&amp;vm, closure.protoCallFrame);
</span><span class="lines">@@ -1144,8 +1152,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.shouldTriggerTermination(callFrame)))
-        return throwTerminatedExecutionException(callFrame, throwScope);
</del><ins>+    if (UNLIKELY(vm.needTrapHandling())) {
+        vm.handleTraps(callFrame);
+        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+    }
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(codeBlock-&gt;numParameters() == 1); // 1 parameter for 'this'.
</span><span class="cx"> 
</span><span class="lines">@@ -1183,8 +1193,10 @@
</span><span class="cx">         codeBlock = jsCast&lt;ModuleProgramCodeBlock*&gt;(tempCodeBlock);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.shouldTriggerTermination(callFrame)))
-        return throwTerminatedExecutionException(callFrame, throwScope);
</del><ins>+    if (UNLIKELY(vm.needTrapHandling())) {
+        vm.handleTraps(callFrame);
+        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
+    }
</ins><span class="cx"> 
</span><span class="cx">     if (scope-&gt;structure()-&gt;isUncacheableDictionary())
</span><span class="cx">         scope-&gt;flattenDictionaryObject(vm);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -328,7 +328,7 @@
</span><span class="cx">         DEFINE_OP(op_jngreatereq)
</span><span class="cx">         DEFINE_OP(op_jtrue)
</span><span class="cx">         DEFINE_OP(op_loop_hint)
</span><del>-        DEFINE_OP(op_watchdog)
</del><ins>+        DEFINE_OP(op_check_traps)
</ins><span class="cx">         DEFINE_OP(op_lshift)
</span><span class="cx">         DEFINE_OP(op_mod)
</span><span class="cx">         DEFINE_OP(op_mov)
</span><span class="lines">@@ -504,7 +504,7 @@
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_jngreater)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_jngreatereq)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_loop_hint)
</span><del>-        DEFINE_SLOWCASE_OP(op_watchdog)
</del><ins>+        DEFINE_SLOWCASE_OP(op_check_traps)
</ins><span class="cx">         DEFINE_SLOWCASE_OP(op_lshift)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_mod)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_mul)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -530,7 +530,7 @@
</span><span class="cx">         void emit_op_jngreatereq(Instruction*);
</span><span class="cx">         void emit_op_jtrue(Instruction*);
</span><span class="cx">         void emit_op_loop_hint(Instruction*);
</span><del>-        void emit_op_watchdog(Instruction*);
</del><ins>+        void emit_op_check_traps(Instruction*);
</ins><span class="cx">         void emit_op_lshift(Instruction*);
</span><span class="cx">         void emit_op_mod(Instruction*);
</span><span class="cx">         void emit_op_mov(Instruction*);
</span><span class="lines">@@ -638,7 +638,7 @@
</span><span class="cx">         void emitSlow_op_jngreatereq(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_jtrue(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_loop_hint(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><del>-        void emitSlow_op_watchdog(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</del><ins>+        void emitSlow_op_check_traps(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</ins><span class="cx">         void emitSlow_op_lshift(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_mod(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_mul(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009, 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2010 Patrick Gansterer &lt;paroga@paroga.com&gt;
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -943,17 +943,15 @@
</span><span class="cx">     slowPathCall.call();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emit_op_watchdog(Instruction*)
</del><ins>+void JIT::emit_op_check_traps(Instruction*)
</ins><span class="cx"> {
</span><del>-    ASSERT(m_vm-&gt;watchdog());
-    addSlowCase(branchTest8(NonZero, AbsoluteAddress(m_vm-&gt;watchdog()-&gt;timerDidFireAddress())));
</del><ins>+    addSlowCase(branchTest8(NonZero, AbsoluteAddress(m_vm-&gt;needTrapHandlingAddress())));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emitSlow_op_watchdog(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</del><ins>+void JIT::emitSlow_op_check_traps(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</ins><span class="cx"> {
</span><del>-    ASSERT(m_vm-&gt;watchdog());
</del><span class="cx">     linkSlowCase(iter);
</span><del>-    callOperation(operationHandleWatchdogTimer);
</del><ins>+    callOperation(operationHandleTraps);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_new_regexp(Instruction* currentInstruction)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1205,18 +1205,14 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // The only reason for returning an UnusedPtr (instead of void) is so that we can reuse the
</span><del>-// existing DFG slow path generator machinery when creating the slow path for CheckWatchdogTimer
</del><ins>+// existing DFG slow path generator machinery when creating the slow path for CheckTraps
</ins><span class="cx"> // in the DFG. If a DFG slow path generator that supports a void return type is added in the
</span><span class="cx"> // future, we can switch to using that then.
</span><del>-UnusedPtr JIT_OPERATION operationHandleWatchdogTimer(ExecState* exec)
</del><ins>+UnusedPtr JIT_OPERATION operationHandleTraps(ExecState* exec)
</ins><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;vm, exec);
</span><del>-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(vm.shouldTriggerTermination(exec)))
-        throwException(exec, scope, createTerminatedExecutionException(&amp;vm));
-
</del><ins>+    vm.handleTraps(exec);
</ins><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -384,7 +384,7 @@
</span><span class="cx"> void JIT_OPERATION operationSetFunctionName(ExecState*, JSCell*, EncodedJSValue) WTF_INTERNAL;
</span><span class="cx"> JSCell* JIT_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL;
</span><del>-UnusedPtr JIT_OPERATION operationHandleWatchdogTimer(ExecState*) WTF_INTERNAL;
</del><ins>+UnusedPtr JIT_OPERATION operationHandleTraps(ExecState*) WTF_INTERNAL;
</ins><span class="cx"> void JIT_OPERATION operationThrow(ExecState*, EncodedJSValue) WTF_INTERNAL;
</span><span class="cx"> void JIT_OPERATION operationDebug(ExecState*, int32_t) WTF_INTERNAL;
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1494,13 +1494,11 @@
</span><span class="cx">     LLINT_THROW(LLINT_OP_C(1).jsValue());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
</del><ins>+LLINT_SLOW_PATH_DECL(slow_path_handle_traps)
</ins><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN_NO_SET_PC();
</span><del>-    ASSERT(vm.watchdog());
-    if (UNLIKELY(vm.shouldTriggerTermination(exec)))
-        LLINT_THROW(createTerminatedExecutionException(&amp;vm));
-    LLINT_RETURN_TWO(0, exec);
</del><ins>+    vm.handleTraps(exec);
+    LLINT_RETURN_TWO(throwScope.exception(), exec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_debug)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2014, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_strcat);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw);
</span><del>-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_watchdog_timer);
</del><ins>+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_traps);
</ins><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_debug);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_exception);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-# Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+# Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> #
</span><span class="cx"> # Redistribution and use in source and binary forms, with or without
</span><span class="cx"> # modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1544,19 +1544,17 @@
</span><span class="cx">     dispatch(1)
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-_llint_op_watchdog:
</del><ins>+_llint_op_check_traps:
</ins><span class="cx">     traceExecution()
</span><span class="cx">     loadp CodeBlock[cfr], t1
</span><span class="cx">     loadp CodeBlock::m_vm[t1], t1
</span><del>-    loadp VM::m_watchdog[t1], t0
-    btpnz t0, .handleWatchdogTimer
-.afterWatchdogTimerCheck:
</del><ins>+    loadb VM::m_traps+VMTraps::m_needTrapHandling[t1], t0
+    btpnz t0, .handleTraps
+.afterHandlingTraps:
</ins><span class="cx">     dispatch(1)
</span><del>-.handleWatchdogTimer:
-    loadb Watchdog::m_timerDidFire[t0], t0
-    btbz t0, .afterWatchdogTimerCheck
-    callWatchdogTimerHandler(.throwHandler)
-    jmp .afterWatchdogTimerCheck
</del><ins>+.handleTraps:
+    callTrapHandler(.throwHandler)
+    jmp .afterHandlingTraps
</ins><span class="cx"> .throwHandler:
</span><span class="cx">     jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-# Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+# Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> #
</span><span class="cx"> # Redistribution and use in source and binary forms, with or without
</span><span class="cx"> # modification, are permitted provided that the following conditions
</span><span class="lines">@@ -377,11 +377,11 @@
</span><span class="cx">     action(r0, r1)
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro callWatchdogTimerHandler(throwHandler)
</del><ins>+macro callTrapHandler(throwHandler)
</ins><span class="cx">     storei PC, ArgumentCount + TagOffset[cfr]
</span><span class="cx">     move cfr, a0
</span><span class="cx">     move PC, a1
</span><del>-    cCall2(_llint_slow_path_handle_watchdog_timer)
</del><ins>+    cCall2(_llint_slow_path_handle_traps)
</ins><span class="cx">     btpnz r0, throwHandler
</span><span class="cx">     loadi ArgumentCount + TagOffset[cfr], PC
</span><span class="cx"> end
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-# Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+# Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> #
</span><span class="cx"> # Redistribution and use in source and binary forms, with or without
</span><span class="cx"> # modification, are permitted provided that the following conditions
</span><span class="lines">@@ -347,12 +347,12 @@
</span><span class="cx">     action(r0, r1)
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro callWatchdogTimerHandler(throwHandler)
</del><ins>+macro callTrapHandler(throwHandler)
</ins><span class="cx">     storei PC, ArgumentCount + TagOffset[cfr]
</span><span class="cx">     prepareStateForCCall()
</span><span class="cx">     move cfr, a0
</span><span class="cx">     move PC, a1
</span><del>-    cCall2(_llint_slow_path_handle_watchdog_timer)
</del><ins>+    cCall2(_llint_slow_path_handle_traps)
</ins><span class="cx">     btpnz r0, throwHandler
</span><span class="cx">     loadi ArgumentCount + TagOffset[cfr], PC
</span><span class="cx"> end
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -98,6 +98,7 @@
</span><span class="cx"> #include &quot;StrictEvalActivation.h&quot;
</span><span class="cx"> #include &quot;StrongInlines.h&quot;
</span><span class="cx"> #include &quot;StructureInlines.h&quot;
</span><ins>+#include &quot;ThrowScope.h&quot;
</ins><span class="cx"> #include &quot;TypeProfiler.h&quot;
</span><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><span class="cx"> #include &quot;UnlinkedCodeBlock.h&quot;
</span><span class="lines">@@ -356,6 +357,8 @@
</span><span class="cx"> 
</span><span class="cx"> VM::~VM()
</span><span class="cx"> {
</span><ins>+    if (UNLIKELY(m_watchdog))
+        m_watchdog-&gt;willDestroyVM(this);
</ins><span class="cx">     VMInspector::instance().remove(this);
</span><span class="cx"> 
</span><span class="cx">     // Never GC, ever again.
</span><span class="lines">@@ -459,7 +462,7 @@
</span><span class="cx"> Watchdog&amp; VM::ensureWatchdog()
</span><span class="cx"> {
</span><span class="cx">     if (!m_watchdog) {
</span><del>-        m_watchdog = adoptRef(new Watchdog());
</del><ins>+        m_watchdog = adoptRef(new Watchdog(this));
</ins><span class="cx">         
</span><span class="cx">         // The LLINT peeks into the Watchdog object directly. In order to do that,
</span><span class="cx">         // the LLINT assumes that the internal shape of a std::unique_ptr is the
</span><span class="lines">@@ -943,4 +946,28 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void VM::handleTraps(ExecState* exec)
+{
+    auto scope = DECLARE_THROW_SCOPE(*this);
+
+    ASSERT(needTrapHandling());
+    while (needTrapHandling()) {
+        auto trapEventType = m_traps.takeTopPriorityTrap();
+        switch (trapEventType) {
+        case VMTraps::NeedWatchdogCheck:
+            ASSERT(m_watchdog);
+            if (LIKELY(!m_watchdog-&gt;shouldTerminate(exec)))
+                continue;
+            FALLTHROUGH;
+
+        case VMTraps::NeedTermination:
+            JSC::throwException(exec, scope, createTerminatedExecutionException(this));
+            return;
+
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -56,6 +56,7 @@
</span><span class="cx"> #include &quot;TemplateRegistryKeyTable.h&quot;
</span><span class="cx"> #include &quot;ThunkGenerators.h&quot;
</span><span class="cx"> #include &quot;VMEntryRecord.h&quot;
</span><ins>+#include &quot;VMTraps.h&quot;
</ins><span class="cx"> #include &quot;Watchpoint.h&quot;
</span><span class="cx"> #include &lt;wtf/Bag.h&gt;
</span><span class="cx"> #include &lt;wtf/BumpPointerAllocator.h&gt;
</span><span class="lines">@@ -614,6 +615,8 @@
</span><span class="cx">     std::thread::id exclusiveThread() const { return m_apiLock-&gt;exclusiveThread(); }
</span><span class="cx">     void setExclusiveThread(std::thread::id threadId) { m_apiLock-&gt;setExclusiveThread(threadId); }
</span><span class="cx"> 
</span><ins>+    std::thread::id ownerThread() const { return m_apiLock-&gt;ownerThread(); }
+
</ins><span class="cx">     JS_EXPORT_PRIVATE void resetDateCache();
</span><span class="cx"> 
</span><span class="cx">     RegExpCache* regExpCache() { return m_regExpCache; }
</span><span class="lines">@@ -664,8 +667,6 @@
</span><span class="cx">     void setGlobalConstRedeclarationShouldThrow(bool globalConstRedeclarationThrow) { m_globalConstRedeclarationShouldThrow = globalConstRedeclarationThrow; }
</span><span class="cx">     ALWAYS_INLINE bool globalConstRedeclarationShouldThrow() const { return m_globalConstRedeclarationShouldThrow; }
</span><span class="cx"> 
</span><del>-    inline bool shouldTriggerTermination(ExecState*);
-
</del><span class="cx">     void setShouldBuildPCToCodeOriginMapping() { m_shouldBuildPCToCodeOriginMapping = true; }
</span><span class="cx">     bool shouldBuilderPCToCodeOriginMapping() const { return m_shouldBuildPCToCodeOriginMapping; }
</span><span class="cx"> 
</span><span class="lines">@@ -676,6 +677,17 @@
</span><span class="cx">     template&lt;typename Func&gt;
</span><span class="cx">     void logEvent(CodeBlock*, const char* summary, const Func&amp; func);
</span><span class="cx"> 
</span><ins>+    void handleTraps(ExecState*);
+
+    bool needTrapHandling() { return m_traps.needTrapHandling(); }
+    void* needTrapHandlingAddress() { return m_traps.needTrapHandlingAddress(); }
+
+    void notifyNeedTermination() { m_traps.fireTrap(VMTraps::NeedTermination); }
+    void notifyNeedWatchdogCheck() { m_traps.fireTrap(VMTraps::NeedWatchdogCheck); }
+
+    bool needAsynchronousTerminationSupport() const { return m_needAsynchronousTerminationSupport; }
+    void setNeedAsynchronousTerminationSupport() { m_needAsynchronousTerminationSupport = true; }
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx"> 
</span><span class="lines">@@ -760,6 +772,7 @@
</span><span class="cx">     DeletePropertyMode m_deletePropertyMode { DeletePropertyMode::Default };
</span><span class="cx">     bool m_globalConstRedeclarationShouldThrow { true };
</span><span class="cx">     bool m_shouldBuildPCToCodeOriginMapping { false };
</span><ins>+    bool m_needAsynchronousTerminationSupport { false };
</ins><span class="cx">     std::unique_ptr&lt;CodeCache&gt; m_codeCache;
</span><span class="cx">     std::unique_ptr&lt;BuiltinExecutables&gt; m_builtinExecutables;
</span><span class="cx">     HashMap&lt;String, RefPtr&lt;WatchpointSet&gt;&gt; m_impurePropertyWatchpointSets;
</span><span class="lines">@@ -771,6 +784,7 @@
</span><span class="cx">     unsigned m_controlFlowProfilerEnabledCount;
</span><span class="cx">     Deque&lt;std::unique_ptr&lt;QueuedTask&gt;&gt; m_microtaskQueue;
</span><span class="cx">     MallocPtr&lt;EncodedJSValue&gt; m_exceptionFuzzBuffer;
</span><ins>+    VMTraps m_traps;
</ins><span class="cx">     RefPtr&lt;Watchdog&gt; m_watchdog;
</span><span class="cx">     std::unique_ptr&lt;HeapProfiler&gt; m_heapProfiler;
</span><span class="cx"> #if ENABLE(SAMPLING_PROFILER)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VMInlines.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VMInlines.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/runtime/VMInlines.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -51,13 +51,6 @@
</span><span class="cx">     return safe;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool VM::shouldTriggerTermination(ExecState* exec)
-{
-    if (!watchdog())
-        return false;
-    return watchdog()-&gt;shouldTerminate(exec);
-}
-
</del><span class="cx"> template&lt;typename Func&gt;
</span><span class="cx"> void VM::logEvent(CodeBlock* codeBlock, const char* summary, const Func&amp; func)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMTrapscppfromrev213106trunkSourceJavaScriptCoreruntimeVMInlinesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/VMTraps.cpp (from rev 213106, trunk/Source/JavaScriptCore/runtime/VMInlines.h) (0 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VMTraps.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/VMTraps.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;VMTraps.h&quot;
+
+namespace JSC {
+
+void VMTraps::fireTrap(VMTraps::EventType eventType)
+{
+    auto locker = holdLock(m_lock);
+    setTrapForEvent(locker, eventType);
+}
+
+bool VMTraps::takeTrap(VMTraps::EventType eventType)
+{
+    auto locker = holdLock(m_lock);
+    if (hasTrapForEvent(locker, eventType)) {
+        clearTrapForEvent(locker, eventType);
+        return true;
+    }
+    return false;
+}
+
+auto VMTraps::takeTopPriorityTrap() -&gt; EventType
+{
+    for (int i = 0; i &lt; NumberOfEventTypes; ++i) {
+        EventType eventType = static_cast&lt;EventType&gt;(i);
+        if (takeTrap(eventType))
+            return eventType;
+    }
+    return Invalid;
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMTrapshfromrev213106trunkSourceJavaScriptCoreruntimeVMInlinesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/VMTraps.h (from rev 213106, trunk/Source/JavaScriptCore/runtime/VMInlines.h) (0 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VMTraps.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/VMTraps.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include &lt;wtf/Lock.h&gt;
+#include &lt;wtf/Locker.h&gt;
+
+namespace JSC {
+
+class VM;
+
+class VMTraps {
+public:
+    enum EventType {
+        // Sorted in servicing priority order from highest to lowest.
+        NeedTermination,
+        NeedWatchdogCheck,
+        NumberOfEventTypes, // This entry must be last in this list.
+        Invalid
+    };
+
+    bool needTrapHandling() { return m_needTrapHandling; }
+    void* needTrapHandlingAddress() { return &amp;m_needTrapHandling; }
+
+    JS_EXPORT_PRIVATE void fireTrap(EventType);
+
+    bool takeTrap(EventType);
+    EventType takeTopPriorityTrap();
+
+private:
+    VM&amp; vm() const;
+
+    bool hasTrapForEvent(Locker&lt;Lock&gt;&amp;, EventType eventType)
+    {
+        ASSERT(eventType &lt; NumberOfEventTypes);
+        return (m_trapsBitField &amp; (1 &lt;&lt; eventType));
+    }
+    void setTrapForEvent(Locker&lt;Lock&gt;&amp;, EventType eventType)
+    {
+        ASSERT(eventType &lt; NumberOfEventTypes);
+        m_trapsBitField |= (1 &lt;&lt; eventType);
+    }
+    void clearTrapForEvent(Locker&lt;Lock&gt;&amp;, EventType eventType)
+    {
+        ASSERT(eventType &lt; NumberOfEventTypes);
+        m_trapsBitField &amp;= ~(1 &lt;&lt; eventType);
+    }
+
+    Lock m_lock;
+    union {
+        uint8_t m_needTrapHandling { false };
+        uint8_t m_trapsBitField;
+    };
+
+    friend class LLIntOffsetsExtractor;
+};
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWatchdogcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Watchdog.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Watchdog.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/runtime/Watchdog.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -40,8 +40,8 @@
</span><span class="cx">     return std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(steadyTimeSinceEpoch);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Watchdog::Watchdog()
-    : m_timerDidFire(false)
</del><ins>+Watchdog::Watchdog(VM* vm)
+    : m_vm(vm)
</ins><span class="cx">     , m_timeLimit(noTimeLimit)
</span><span class="cx">     , m_cpuDeadline(noTimeLimit)
</span><span class="cx">     , m_wallClockDeadline(noTimeLimit)
</span><span class="lines">@@ -55,7 +55,7 @@
</span><span class="cx"> void Watchdog::setTimeLimit(std::chrono::microseconds limit,
</span><span class="cx">     ShouldTerminateCallback callback, void* data1, void* data2)
</span><span class="cx"> {
</span><del>-    LockHolder locker(m_lock);
</del><ins>+    ASSERT(m_vm-&gt;ownerThread() == std::this_thread::get_id());
</ins><span class="cx"> 
</span><span class="cx">     m_timeLimit = limit;
</span><span class="cx">     m_callback = callback;
</span><span class="lines">@@ -63,27 +63,14 @@
</span><span class="cx">     m_callbackData2 = data2;
</span><span class="cx"> 
</span><span class="cx">     if (m_hasEnteredVM &amp;&amp; hasTimeLimit())
</span><del>-        startTimer(locker, m_timeLimit);
</del><ins>+        startTimer(m_timeLimit);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-JS_EXPORT_PRIVATE void Watchdog::terminateSoon()
</del><ins>+bool Watchdog::shouldTerminate(ExecState* exec)
</ins><span class="cx"> {
</span><del>-    LockHolder locker(m_lock);
-
-    m_timeLimit = std::chrono::microseconds(0);
-    m_cpuDeadline = std::chrono::microseconds(0);
-    m_wallClockDeadline = std::chrono::microseconds(0);
-    m_timerDidFire = true;
-}
-
-bool Watchdog::shouldTerminateSlow(ExecState* exec)
-{
</del><ins>+    ASSERT(m_vm-&gt;ownerThread() == std::this_thread::get_id());
+    // FIXME: Will unindent the following before landing. Leaving indented for now to minimize the code diff.
</ins><span class="cx">     {
</span><del>-        LockHolder locker(m_lock);
-
-        ASSERT(m_timerDidFire);
-        m_timerDidFire = false;
-
</del><span class="cx">         if (currentWallClockTime() &lt; m_wallClockDeadline)
</span><span class="cx">             return false; // Just a stale timer firing. Nothing to do.
</span><span class="cx"> 
</span><span class="lines">@@ -94,7 +81,7 @@
</span><span class="cx">         auto cpuTime = currentCPUTime();
</span><span class="cx">         if (cpuTime &lt; m_cpuDeadline) {
</span><span class="cx">             auto remainingCPUTime = m_cpuDeadline - cpuTime;
</span><del>-            startTimer(locker, remainingCPUTime);
</del><ins>+            startTimer(remainingCPUTime);
</ins><span class="cx">             return false;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -109,9 +96,8 @@
</span><span class="cx">     if (needsTermination)
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><ins>+    // FIXME: Will unindent the following before landing. Leaving indented for now to minimize the code diff.
</ins><span class="cx">     {
</span><del>-        LockHolder locker(m_lock);
-
</del><span class="cx">         // If we get here, then the callback above did not want to terminate execution. As a
</span><span class="cx">         // result, the callback may have done one of the following:
</span><span class="cx">         //   1. cleared the time limit (i.e. watchdog is disabled),
</span><span class="lines">@@ -125,7 +111,7 @@
</span><span class="cx">         ASSERT(m_hasEnteredVM);
</span><span class="cx">         bool callbackAlreadyStartedTimer = (m_cpuDeadline != noTimeLimit);
</span><span class="cx">         if (hasTimeLimit() &amp;&amp; !callbackAlreadyStartedTimer)
</span><del>-            startTimer(locker, m_timeLimit);
</del><ins>+            startTimer(m_timeLimit);
</ins><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="lines">@@ -138,23 +124,21 @@
</span><span class="cx"> void Watchdog::enteredVM()
</span><span class="cx"> {
</span><span class="cx">     m_hasEnteredVM = true;
</span><del>-    if (hasTimeLimit()) {
-        LockHolder locker(m_lock);
-        startTimer(locker, m_timeLimit);
-    }
</del><ins>+    if (hasTimeLimit())
+        startTimer(m_timeLimit);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Watchdog::exitedVM()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_hasEnteredVM);
</span><del>-    LockHolder locker(m_lock);
-    stopTimer(locker);
</del><ins>+    stopTimer();
</ins><span class="cx">     m_hasEnteredVM = false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Watchdog::startTimer(LockHolder&amp;, std::chrono::microseconds timeLimit)
</del><ins>+void Watchdog::startTimer(std::chrono::microseconds timeLimit)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_hasEnteredVM);
</span><ins>+    ASSERT(m_vm-&gt;ownerThread() == std::this_thread::get_id());
</ins><span class="cx">     ASSERT(hasTimeLimit());
</span><span class="cx">     ASSERT(timeLimit &lt;= m_timeLimit);
</span><span class="cx"> 
</span><span class="lines">@@ -167,21 +151,32 @@
</span><span class="cx">         return; // Wait for the current active timer to expire before starting a new one.
</span><span class="cx"> 
</span><span class="cx">     // Else, the current active timer won't fire soon enough. So, start a new timer.
</span><del>-    this-&gt;ref(); // m_timerHandler will deref to match later.
</del><span class="cx">     m_wallClockDeadline = wallClockDeadline;
</span><span class="cx"> 
</span><del>-    m_timerQueue-&gt;dispatchAfter(std::chrono::nanoseconds(timeLimit), [this] {
-        {
-            LockHolder locker(m_lock);
-            m_timerDidFire = true;
-        }
-        deref();
</del><ins>+    // We need to ensure that the Watchdog outlives the timer.
+    // For the same reason, the timer may also outlive the VM that the Watchdog operates on.
+    // So, we always need to null check m_vm before using it. The VM will notify the Watchdog
+    // via willDestroyVM() before it goes away.
+    RefPtr&lt;Watchdog&gt; protectedThis = this;
+    m_timerQueue-&gt;dispatchAfter(std::chrono::nanoseconds(timeLimit), [this, protectedThis] {
+        LockHolder locker(m_lock);
+        if (m_vm)
+            m_vm-&gt;notifyNeedWatchdogCheck();
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Watchdog::stopTimer(LockHolder&amp;)
</del><ins>+void Watchdog::stopTimer()
</ins><span class="cx"> {
</span><ins>+    ASSERT(m_hasEnteredVM);
+    ASSERT(m_vm-&gt;ownerThread() == std::this_thread::get_id());
</ins><span class="cx">     m_cpuDeadline = noTimeLimit;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Watchdog::willDestroyVM(VM* vm)
+{
+    LockHolder locker(m_lock);
+    ASSERT_UNUSED(vm, m_vm == vm);
+    m_vm = nullptr;
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWatchdogh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Watchdog.h (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Watchdog.h        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/JavaScriptCore/runtime/Watchdog.h        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -40,49 +40,32 @@
</span><span class="cx"> public:
</span><span class="cx">     class Scope;
</span><span class="cx"> 
</span><del>-    Watchdog();
</del><ins>+    Watchdog(VM*);
+    void willDestroyVM(VM*);
</ins><span class="cx"> 
</span><span class="cx">     typedef bool (*ShouldTerminateCallback)(ExecState*, void* data1, void* data2);
</span><span class="cx">     void setTimeLimit(std::chrono::microseconds limit, ShouldTerminateCallback = 0, void* data1 = 0, void* data2 = 0);
</span><del>-    JS_EXPORT_PRIVATE void terminateSoon();
</del><span class="cx"> 
</span><del>-    bool shouldTerminate(ExecState* exec)
-    {
-        if (!m_timerDidFire)
-            return false;
-        return shouldTerminateSlow(exec);
-    }
</del><ins>+    bool shouldTerminate(ExecState*);
</ins><span class="cx"> 
</span><span class="cx">     bool hasTimeLimit();
</span><span class="cx">     void enteredVM();
</span><span class="cx">     void exitedVM();
</span><span class="cx"> 
</span><del>-    void* timerDidFireAddress() { return &amp;m_timerDidFire; }
-
</del><span class="cx">     static const std::chrono::microseconds noTimeLimit;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void startTimer(LockHolder&amp;, std::chrono::microseconds timeLimit);
-    void stopTimer(LockHolder&amp;);
</del><ins>+    void startTimer(std::chrono::microseconds timeLimit);
+    void stopTimer();
</ins><span class="cx"> 
</span><del>-    bool shouldTerminateSlow(ExecState*);
</del><ins>+    Lock m_lock; // Guards access to m_vm.
+    VM* m_vm;
</ins><span class="cx"> 
</span><del>-    // m_timerDidFire indicates whether the timer fired. The Watchdog
-    // still needs to check if the allowed CPU time has elapsed. If so, then
-    // the Watchdog fires and m_didFire will be set.
-    // NOTE: m_timerDidFire is only set by the platform specific timer
-    // (probably from another thread) but is only cleared in the script thread.
-    bool m_timerDidFire;
-
</del><span class="cx">     std::chrono::microseconds m_timeLimit;
</span><span class="cx"> 
</span><span class="cx">     std::chrono::microseconds m_cpuDeadline;
</span><span class="cx">     std::chrono::microseconds m_wallClockDeadline;
</span><span class="cx"> 
</span><del>-    // Writes to m_timerDidFire and m_timeLimit, and Reads+Writes to m_cpuDeadline and m_wallClockDeadline
-    // must be guarded by this lock.
-    Lock m_lock;
-
</del><span class="cx">     bool m_hasEnteredVM { false };
</span><span class="cx"> 
</span><span class="cx">     ShouldTerminateCallback m_callback;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/WebCore/ChangeLog        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2017-02-27  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Introduce a VM Traps mechanism and refactor Watchdog to use it.
+        https://bugs.webkit.org/show_bug.cgi?id=168842
+
+        Reviewed by Filip Pizlo.
+
+        No new tests needed because this is a re-implementation of existing functionality.
+
+        * bindings/js/WorkerScriptController.cpp:
+        (WebCore::WorkerScriptController::WorkerScriptController):
+        (WebCore::WorkerScriptController::scheduleExecutionTermination):
+
</ins><span class="cx"> 2017-02-27  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Cocoa] Rename FileMac.mm to FileCocoa.mm
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsWorkerScriptControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp (213106 => 213107)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp        2017-02-28 01:20:16 UTC (rev 213106)
+++ trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp        2017-02-28 01:20:54 UTC (rev 213107)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2016 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
</ins><span class="cx">  * Copyright (C) 2011, 2012 Google Inc. All Rights Reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -40,7 +40,6 @@
</span><span class="cx"> #include &lt;runtime/Exception.h&gt;
</span><span class="cx"> #include &lt;runtime/ExceptionHelpers.h&gt;
</span><span class="cx"> #include &lt;runtime/JSLock.h&gt;
</span><del>-#include &lt;runtime/Watchdog.h&gt;
</del><span class="cx"> 
</span><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span><span class="lines">@@ -52,7 +51,7 @@
</span><span class="cx">     , m_workerGlobalScopeWrapper(*m_vm)
</span><span class="cx"> {
</span><span class="cx">     m_vm-&gt;heap.acquireAccess(); // It's not clear that we have good discipline for heap access, so turn it on permanently.
</span><del>-    m_vm-&gt;ensureWatchdog();
</del><ins>+    m_vm-&gt;setNeedAsynchronousTerminationSupport();
</ins><span class="cx">     JSVMClientData::initNormalWorld(m_vm.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -157,9 +156,7 @@
</span><span class="cx">     // accurately reflect that state when called from another thread.
</span><span class="cx">     LockHolder locker(m_scheduledTerminationMutex);
</span><span class="cx">     m_isTerminatingExecution = true;
</span><del>-
-    ASSERT(m_vm-&gt;watchdog());
-    m_vm-&gt;watchdog()-&gt;terminateSoon();
</del><ins>+    m_vm-&gt;notifyNeedTermination();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool WorkerScriptController::isTerminatingExecution() const
</span></span></pre>
</div>
</div>

</body>
</html>