<!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>[169139] 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/169139">169139</a></dd>
<dt>Author</dt> <dd>mhahnenberg@apple.com</dd>
<dt>Date</dt> <dd>2014-05-20 15:55:49 -0700 (Tue, 20 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Watchdog timer should be lazily allocated
https://bugs.webkit.org/show_bug.cgi?id=133135

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:
We incur a noticeable amount of overhead on some benchmarks due to checking if the Watchdog ever fired.
There is no reason to do this checking if we never activated the Watchdog, which can only be done through
JSContextGroupSetExecutionTimeLimit or JSContextGroupClearExecutionTimeLimit.

By allocating the Watchdog lazily on the VM we can avoid all of the associated overhead when we don't use
these two API functions (which is true of most clients).

* API/JSContextRef.cpp:
(JSContextGroupSetExecutionTimeLimit):
(JSContextGroupClearExecutionTimeLimit):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_loop_hint):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/VM.h:
* runtime/Watchdog.cpp:
(JSC::Watchdog::Scope::Scope): Deleted.
(JSC::Watchdog::Scope::~Scope): Deleted.
* runtime/Watchdog.h:
(JSC::Watchdog::Scope::Scope):
(JSC::Watchdog::Scope::~Scope):

Source/WebCore:
No new tests.

We incur a noticeable amount of overhead on some benchmarks due to checking if the Watchdog ever fired.
There is no reason to do this checking if we never activated the Watchdog, which can only be done through
JSContextGroupSetExecutionTimeLimit or JSContextGroupClearExecutionTimeLimit.

By allocating the Watchdog lazily on the VM we can avoid all of the associated overhead when we don't use
these two API functions (which is true of most clients).

* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::evaluate):
(WebCore::WorkerScriptController::scheduleExecutionTermination):
(WebCore::WorkerScriptController::isExecutionTerminating):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIJSContextRefcpp">trunk/Source/JavaScriptCore/API/JSContextRef.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</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="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</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="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.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="#trunkSourceWebCorebindingsjsJSEventListenercpp">trunk/Source/WebCore/bindings/js/JSEventListener.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsWorkerScriptControllercpp">trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIJSContextRefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSContextRef.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSContextRef.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/API/JSContextRef.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -89,7 +89,9 @@
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = *toJS(group);
</span><span class="cx">     JSLockHolder locker(&amp;vm);
</span><del>-    Watchdog&amp; watchdog = vm.watchdog;
</del><ins>+    if (!vm.watchdog)
+        vm.watchdog = std::make_unique&lt;Watchdog&gt;();
+    Watchdog&amp; watchdog = *vm.watchdog;
</ins><span class="cx">     if (callback) {
</span><span class="cx">         void* callbackPtr = reinterpret_cast&lt;void*&gt;(callback);
</span><span class="cx">         watchdog.setTimeLimit(vm, limit, internalScriptTimeoutCallback, callbackPtr, callbackData);
</span><span class="lines">@@ -101,7 +103,9 @@
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = *toJS(group);
</span><span class="cx">     JSLockHolder locker(&amp;vm);
</span><del>-    Watchdog&amp; watchdog = vm.watchdog;
</del><ins>+    if (!vm.watchdog)
+        vm.watchdog = std::make_unique&lt;Watchdog&gt;();
+    Watchdog&amp; watchdog = *vm.watchdog;
</ins><span class="cx">     watchdog.setTimeLimit(vm, std::numeric_limits&lt;double&gt;::infinity());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2014-05-20  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
+
+        Watchdog timer should be lazily allocated
+        https://bugs.webkit.org/show_bug.cgi?id=133135
+
+        Reviewed by Geoffrey Garen.
+
+        We incur a noticeable amount of overhead on some benchmarks due to checking if the Watchdog ever fired. 
+        There is no reason to do this checking if we never activated the Watchdog, which can only be done through 
+        JSContextGroupSetExecutionTimeLimit or JSContextGroupClearExecutionTimeLimit. 
+
+        By allocating the Watchdog lazily on the VM we can avoid all of the associated overhead when we don't use 
+        these two API functions (which is true of most clients).
+
+        * API/JSContextRef.cpp:
+        (JSContextGroupSetExecutionTimeLimit):
+        (JSContextGroupClearExecutionTimeLimit):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_loop_hint):
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/VM.h:
+        * runtime/Watchdog.cpp:
+        (JSC::Watchdog::Scope::Scope): Deleted.
+        (JSC::Watchdog::Scope::~Scope): Deleted.
+        * runtime/Watchdog.h:
+        (JSC::Watchdog::Scope::Scope):
+        (JSC::Watchdog::Scope::~Scope):
+
</ins><span class="cx"> 2014-05-19  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JSArray::shiftCountWith* could be more efficient
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -3192,7 +3192,7 @@
</span><span class="cx"> 
</span><span class="cx">             addToGraph(LoopHint);
</span><span class="cx">             
</span><del>-            if (m_vm-&gt;watchdog.isEnabled())
</del><ins>+            if (m_vm-&gt;watchdog &amp;&amp; m_vm-&gt;watchdog-&gt;isEnabled())
</ins><span class="cx">                 addToGraph(CheckWatchdogTimer);
</span><span class="cx">             
</span><span class="cx">             NEXT_OPCODE(op_loop_hint);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -4551,11 +4551,12 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case CheckWatchdogTimer:
</span><ins>+        ASSERT(m_jit.vm()-&gt;watchdog);
</ins><span class="cx">         speculationCheck(
</span><span class="cx">             WatchdogTimerFired, JSValueRegs(), 0,
</span><span class="cx">             m_jit.branchTest8(
</span><span class="cx">                 JITCompiler::NonZero,
</span><del>-                JITCompiler::AbsoluteAddress(m_jit.vm()-&gt;watchdog.timerDidFireAddress())));
</del><ins>+                JITCompiler::AbsoluteAddress(m_jit.vm()-&gt;watchdog-&gt;timerDidFireAddress())));
</ins><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case CountExecution:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -4575,11 +4575,12 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case CheckWatchdogTimer:
</span><ins>+        ASSERT(m_jit.vm()-&gt;watchdog);
</ins><span class="cx">         speculationCheck(
</span><span class="cx">             WatchdogTimerFired, JSValueRegs(), 0,
</span><span class="cx">             m_jit.branchTest8(
</span><span class="cx">                 JITCompiler::NonZero,
</span><del>-                JITCompiler::AbsoluteAddress(m_jit.vm()-&gt;watchdog.timerDidFireAddress())));
</del><ins>+                JITCompiler::AbsoluteAddress(m_jit.vm()-&gt;watchdog-&gt;timerDidFireAddress())));
</ins><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case Phantom:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -913,7 +913,7 @@
</span><span class="cx"> 
</span><span class="cx">     ProgramCodeBlock* codeBlock = program-&gt;codeBlock();
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</del><ins>+    if (UNLIKELY(vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire(callFrame)))
</ins><span class="cx">         return throwTerminatedExecutionException(callFrame);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(codeBlock-&gt;numParameters() == 1); // 1 parameter for 'this'.
</span><span class="lines">@@ -928,7 +928,7 @@
</span><span class="cx">     JSValue result;
</span><span class="cx">     {
</span><span class="cx">         SamplingTool::CallRecord callRecord(m_sampler.get());
</span><del>-        Watchdog::Scope watchdogScope(vm.watchdog);
</del><ins>+        Watchdog::Scope watchdogScope(vm.watchdog.get());
</ins><span class="cx"> 
</span><span class="cx">         result = program-&gt;generatedJITCode()-&gt;execute(&amp;vm, &amp;protoCallFrame);
</span><span class="cx">     }
</span><span class="lines">@@ -975,7 +975,7 @@
</span><span class="cx">     } else
</span><span class="cx">         newCodeBlock = 0;
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</del><ins>+    if (UNLIKELY(vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire(callFrame)))
</ins><span class="cx">         return throwTerminatedExecutionException(callFrame);
</span><span class="cx"> 
</span><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="lines">@@ -987,7 +987,7 @@
</span><span class="cx">     JSValue result;
</span><span class="cx">     {
</span><span class="cx">         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
</span><del>-        Watchdog::Scope watchdogScope(vm.watchdog);
</del><ins>+        Watchdog::Scope watchdogScope(vm.watchdog.get());
</ins><span class="cx"> 
</span><span class="cx">         // Execute the code:
</span><span class="cx">         if (isJSCall)
</span><span class="lines">@@ -1043,7 +1043,7 @@
</span><span class="cx">     } else
</span><span class="cx">         newCodeBlock = 0;
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</del><ins>+    if (UNLIKELY(vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire(callFrame)))
</ins><span class="cx">         return throwTerminatedExecutionException(callFrame);
</span><span class="cx"> 
</span><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="lines">@@ -1055,7 +1055,7 @@
</span><span class="cx">     JSValue result;
</span><span class="cx">     {
</span><span class="cx">         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
</span><del>-        Watchdog::Scope watchdogScope(vm.watchdog);
</del><ins>+        Watchdog::Scope watchdogScope(vm.watchdog.get());
</ins><span class="cx"> 
</span><span class="cx">         // Execute the code.
</span><span class="cx">         if (isJSConstruct)
</span><span class="lines">@@ -1118,14 +1118,14 @@
</span><span class="cx">     if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx">         profiler-&gt;willExecute(closure.oldCallFrame, closure.function);
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.watchdog.didFire(closure.oldCallFrame)))
</del><ins>+    if (UNLIKELY(vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire(closure.oldCallFrame)))
</ins><span class="cx">         return throwTerminatedExecutionException(closure.oldCallFrame);
</span><span class="cx"> 
</span><span class="cx">     // Execute the code:
</span><span class="cx">     JSValue result;
</span><span class="cx">     {
</span><span class="cx">         SamplingTool::CallRecord callRecord(m_sampler.get());
</span><del>-        Watchdog::Scope watchdogScope(vm.watchdog);
</del><ins>+        Watchdog::Scope watchdogScope(vm.watchdog.get());
</ins><span class="cx"> 
</span><span class="cx">         result = closure.functionExecutable-&gt;generatedJITCodeForCall()-&gt;execute(&amp;vm, closure.protoCallFrame);
</span><span class="cx">     }
</span><span class="lines">@@ -1194,7 +1194,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</del><ins>+    if (UNLIKELY(vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire(callFrame)))
</ins><span class="cx">         return throwTerminatedExecutionException(callFrame);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(codeBlock-&gt;numParameters() == 1); // 1 parameter for 'this'.
</span><span class="lines">@@ -1209,7 +1209,7 @@
</span><span class="cx">     JSValue result;
</span><span class="cx">     {
</span><span class="cx">         SamplingTool::CallRecord callRecord(m_sampler.get());
</span><del>-        Watchdog::Scope watchdogScope(vm.watchdog);
</del><ins>+        Watchdog::Scope watchdogScope(vm.watchdog.get());
</ins><span class="cx"> 
</span><span class="cx">         result = eval-&gt;generatedJITCode()-&gt;execute(&amp;vm, &amp;protoCallFrame);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -1091,8 +1091,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Emit the watchdog timer check:
</span><del>-    if (m_vm-&gt;watchdog.isEnabled())
-        addSlowCase(branchTest8(NonZero, AbsoluteAddress(m_vm-&gt;watchdog.timerDidFireAddress())));
</del><ins>+    if (m_vm-&gt;watchdog &amp;&amp; m_vm-&gt;watchdog-&gt;isEnabled())
+        addSlowCase(branchTest8(NonZero, AbsoluteAddress(m_vm-&gt;watchdog-&gt;timerDidFireAddress())));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT::emitSlow_op_loop_hint(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="lines">@@ -1117,7 +1117,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // Emit the slow path of the watchdog timer check:
</span><del>-    if (m_vm-&gt;watchdog.isEnabled()) {
</del><ins>+    if (m_vm-&gt;watchdog &amp;&amp; m_vm-&gt;watchdog-&gt;isEnabled()) {
</ins><span class="cx">         linkSlowCase(iter);
</span><span class="cx">         callOperation(operationHandleWatchdogTimer);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -983,7 +983,7 @@
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;vm, exec);
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(vm.watchdog.didFire(exec)))
</del><ins>+    if (UNLIKELY(vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire(exec)))
</ins><span class="cx">         vm.throwException(exec, createTerminatedExecutionException(&amp;vm));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -1354,7 +1354,8 @@
</span><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
</span><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN_NO_SET_PC();
</span><del>-    if (UNLIKELY(vm.watchdog.didFire(exec)))
</del><ins>+    ASSERT(vm.watchdog);
+    if (UNLIKELY(vm.watchdog-&gt;didFire(exec)))
</ins><span class="cx">         LLINT_THROW(createTerminatedExecutionException(&amp;vm));
</span><span class="cx">     LLINT_RETURN_TWO(0, exec);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -230,7 +230,7 @@
</span><span class="cx">         VMType vmType;
</span><span class="cx">         ClientData* clientData;
</span><span class="cx">         ExecState* topCallFrame;
</span><del>-        Watchdog watchdog;
</del><ins>+        std::unique_ptr&lt;Watchdog&gt; watchdog;
</ins><span class="cx"> 
</span><span class="cx">         const OwnPtr&lt;const HashTable&gt; arrayConstructorTable;
</span><span class="cx">         const OwnPtr&lt;const HashTable&gt; arrayPrototypeTable;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWatchdogcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Watchdog.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Watchdog.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/runtime/Watchdog.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -185,15 +185,4 @@
</span><span class="cx">     m_isStopped = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Watchdog::Scope::Scope(Watchdog&amp; watchdog)
-    : m_watchdog(watchdog)
-{
-    m_watchdog.arm();
-}
-
-Watchdog::Scope::~Scope()
-{
-    m_watchdog.disarm();
-}
-
</del><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWatchdogh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Watchdog.h (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Watchdog.h        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/JavaScriptCore/runtime/Watchdog.h        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -104,11 +104,23 @@
</span><span class="cx"> 
</span><span class="cx"> class Watchdog::Scope {
</span><span class="cx"> public:
</span><del>-    Scope(Watchdog&amp;);
-    ~Scope();
</del><ins>+    Scope(Watchdog* watchdog)
+        : m_watchdog(watchdog)
+    {
+        if (!watchdog)
+            return;
+        m_watchdog-&gt;arm();
+    }
+    
+    ~Scope()
+    {
+        if (!m_watchdog)
+            return;
+        m_watchdog-&gt;disarm();
+    }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    Watchdog&amp; m_watchdog;
</del><ins>+    Watchdog* m_watchdog;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/WebCore/ChangeLog        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2014-05-20  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
+
+        Watchdog timer should be lazily allocated
+        https://bugs.webkit.org/show_bug.cgi?id=133135
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests.
+
+        We incur a noticeable amount of overhead on some benchmarks due to checking if the Watchdog ever fired. 
+        There is no reason to do this checking if we never activated the Watchdog, which can only be done through 
+        JSContextGroupSetExecutionTimeLimit or JSContextGroupClearExecutionTimeLimit. 
+
+        By allocating the Watchdog lazily on the VM we can avoid all of the associated overhead when we don't use 
+        these two API functions (which is true of most clients).
+
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSEventListener::handleEvent):
+        * bindings/js/WorkerScriptController.cpp:
+        (WebCore::WorkerScriptController::evaluate):
+        (WebCore::WorkerScriptController::scheduleExecutionTermination):
+        (WebCore::WorkerScriptController::isExecutionTerminating):
+
</ins><span class="cx"> 2014-05-20  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Mac] Allow popup menus to override default appearance
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSEventListenercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSEventListener.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSEventListener.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/WebCore/bindings/js/JSEventListener.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx"> 
</span><span class="cx">         if (scriptExecutionContext-&gt;isWorkerGlobalScope()) {
</span><span class="cx">             bool terminatorCausedException = (exec-&gt;hadException() &amp;&amp; isTerminatedExecutionException(exec-&gt;exception()));
</span><del>-            if (terminatorCausedException || vm.watchdog.didFire())
</del><ins>+            if (terminatorCausedException || (vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire()))
</ins><span class="cx">                 toWorkerGlobalScope(scriptExecutionContext)-&gt;script()-&gt;forbidExecution();
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsWorkerScriptControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp (169138 => 169139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp        2014-05-20 22:54:34 UTC (rev 169138)
+++ trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp        2014-05-20 22:55:49 UTC (rev 169139)
</span><span class="lines">@@ -134,7 +134,9 @@
</span><span class="cx">     JSValue evaluationException;
</span><span class="cx">     JSC::evaluate(exec, sourceCode.jsSourceCode(), m_workerGlobalScopeWrapper-&gt;globalThis(), &amp;evaluationException);
</span><span class="cx"> 
</span><del>-    if ((evaluationException &amp;&amp; isTerminatedExecutionException(evaluationException)) ||  m_workerGlobalScopeWrapper-&gt;vm().watchdog.didFire()) {
</del><ins>+    VM&amp; vm = exec-&gt;vm();
+    if ((evaluationException &amp;&amp; isTerminatedExecutionException(evaluationException)) 
+        || (vm.watchdog &amp;&amp; vm.watchdog-&gt;didFire())) {
</ins><span class="cx">         forbidExecution();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -162,14 +164,17 @@
</span><span class="cx">     // termination is scheduled, isExecutionTerminating will
</span><span class="cx">     // accurately reflect that state when called from another thread.
</span><span class="cx">     MutexLocker locker(m_scheduledTerminationMutex);
</span><del>-    m_vm-&gt;watchdog.fire();
</del><ins>+    if (m_vm-&gt;watchdog)
+        m_vm-&gt;watchdog-&gt;fire();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool WorkerScriptController::isExecutionTerminating() const
</span><span class="cx"> {
</span><span class="cx">     // See comments in scheduleExecutionTermination regarding mutex usage.
</span><span class="cx">     MutexLocker locker(m_scheduledTerminationMutex);
</span><del>-    return m_vm-&gt;watchdog.didFire();
</del><ins>+    if (m_vm-&gt;watchdog)
+        return m_vm-&gt;watchdog-&gt;didFire();
+    return false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WorkerScriptController::forbidExecution()
</span></span></pre>
</div>
</div>

</body>
</html>