<!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>[163661] trunk/Source/JavaScriptCore</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/163661">163661</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2014-02-07 16:24:13 -0800 (Fri, 07 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fix bug in stack limit adjustments in JSLock.
&lt;https://webkit.org/b/128406&gt;

Reviewed by Geoffrey Garen.

1. JSLock::unlock() was only clearing the VM::stackPointerAtEntry when
   m_vm-&gt;stackPointerAtVMEntry == entryStackPointer. FYI,
   entryStackPointer is a field in JSLock.

   When DropAllLocks::~DropAllLocks() will call JSLock::grabAllLocks()
   to relock the JSLock, JSLock::grabAllLocks() will set a new
   entryStackPointer value. Thereafter, DropAllLocks::~DropAllLocks() will
   restore the saved VM::stackPointerAtEntry, which will now defer from
   the JSLock's entryStackPointer value.

   It turns out that when m_vm-&gt;stackPointerAtVMEntry was initialized,
   it was set to whatever value entryStackPointer is set to. At no time
   do we ever expect the 2 values to differ. The only time it differs is
   when this bug manifests.

   The fix is to remove the entryStackPointer field in JSLock and its uses
   altogether.

2. DropAllLocks was unconditionally clearing VM::stackPointerAtEntry in
   its constructor instead of letting JSLock::unlock() do the clearing.

   However, DropAllLocks will not actually drop locks if it isn't required
   to (e.g. when alwaysDropLocks is DontAlwaysDropLocks), and when we've
   already drop locks once (i.e. JSLock::m_lockDropDepth is not 0).

   We should not have cleared VM::stackPointerAtEntry here if we don't
   actually drop the locks.

* runtime/JSLock.cpp:
(JSC::JSLock::unlock):
(JSC::JSLock::DropAllLocks::DropAllLocks):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLockcpp">trunk/Source/JavaScriptCore/runtime/JSLock.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (163660 => 163661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-08 00:19:49 UTC (rev 163660)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-08 00:24:13 UTC (rev 163661)
</span><span class="lines">@@ -1,3 +1,42 @@
</span><ins>+2014-02-07  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Fix bug in stack limit adjustments in JSLock.
+        &lt;https://webkit.org/b/128406&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        1. JSLock::unlock() was only clearing the VM::stackPointerAtEntry when
+           m_vm-&gt;stackPointerAtVMEntry == entryStackPointer. FYI,
+           entryStackPointer is a field in JSLock.
+
+           When DropAllLocks::~DropAllLocks() will call JSLock::grabAllLocks()
+           to relock the JSLock, JSLock::grabAllLocks() will set a new
+           entryStackPointer value. Thereafter, DropAllLocks::~DropAllLocks() will
+           restore the saved VM::stackPointerAtEntry, which will now defer from
+           the JSLock's entryStackPointer value.
+
+           It turns out that when m_vm-&gt;stackPointerAtVMEntry was initialized,
+           it was set to whatever value entryStackPointer is set to. At no time
+           do we ever expect the 2 values to differ. The only time it differs is
+           when this bug manifests.
+
+           The fix is to remove the entryStackPointer field in JSLock and its uses
+           altogether.
+
+        2. DropAllLocks was unconditionally clearing VM::stackPointerAtEntry in
+           its constructor instead of letting JSLock::unlock() do the clearing.
+
+           However, DropAllLocks will not actually drop locks if it isn't required
+           to (e.g. when alwaysDropLocks is DontAlwaysDropLocks), and when we've
+           already drop locks once (i.e. JSLock::m_lockDropDepth is not 0).
+
+           We should not have cleared VM::stackPointerAtEntry here if we don't
+           actually drop the locks.
+
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::unlock):
+        (JSC::JSLock::DropAllLocks::DropAllLocks):
+
</ins><span class="cx"> 2014-02-07  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Eliminate race between XPC connection queue and Notification queue
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLock.cpp (163660 => 163661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2014-02-08 00:19:49 UTC (rev 163660)
+++ trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2014-02-08 00:24:13 UTC (rev 163661)
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx">     m_lockCount--;
</span><span class="cx"> 
</span><span class="cx">     if (!m_lockCount) {
</span><del>-        if (m_vm &amp;&amp; m_vm-&gt;stackPointerAtVMEntry == entryStackPointer) {
</del><ins>+        if (m_vm) {
</ins><span class="cx">             m_vm-&gt;stackPointerAtVMEntry = nullptr;
</span><span class="cx">             m_vm-&gt;updateStackLimitWithReservedZoneSize(wtfThreadData().savedReservedZoneSize());
</span><span class="cx">         }
</span><span class="lines">@@ -312,8 +312,6 @@
</span><span class="cx">     threadData.setSavedLastStackTop(m_vm-&gt;lastStackTop());
</span><span class="cx">     threadData.setSavedReservedZoneSize(m_vm-&gt;reservedZoneSize());
</span><span class="cx"> 
</span><del>-    m_vm-&gt;stackPointerAtVMEntry = nullptr;
-
</del><span class="cx">     if (alwaysDropLocks)
</span><span class="cx">         m_lockCount = m_vm-&gt;apiLock().dropAllLocksUnconditionally(spinLock);
</span><span class="cx">     else
</span><span class="lines">@@ -337,8 +335,6 @@
</span><span class="cx">     threadData.setSavedLastStackTop(m_vm-&gt;lastStackTop());
</span><span class="cx">     threadData.setSavedReservedZoneSize(m_vm-&gt;reservedZoneSize());
</span><span class="cx"> 
</span><del>-    m_vm-&gt;stackPointerAtVMEntry = nullptr;
-
</del><span class="cx">     if (alwaysDropLocks)
</span><span class="cx">         m_lockCount = m_vm-&gt;apiLock().dropAllLocksUnconditionally(spinLock);
</span><span class="cx">     else
</span></span></pre>
</div>
</div>

</body>
</html>