<!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>[164627] 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/164627">164627</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2014-02-24 20:44:09 -0800 (Mon, 24 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Need to initialize VM stack data even when the VM is on an exclusive thread.
&lt;https://webkit.org/b/129265&gt;

Reviewed by Geoffrey Garen.

Source/JavaScriptCore: 

We check VM::exclusiveThread as an optimization to forego the need to do
JSLock locking. However, we recently started piggy backing on JSLock's
lock() and unlock() to initialize VM stack data (stackPointerAtVMEntry
and lastStackTop) to appropriate values for the current thread. This is
needed because we may be acquiring the lock to enter the VM on a different
thread.

As a result, we ended up not initializing the VM stack data when
VM::exclusiveThread causes us to bypass the locking activity. Even though
the VM::exclusiveThread will not have to deal with the VM being entered
on a different thread, it still needs to initialize the VM stack data.
The VM relies on that data being initialized properly once it has been
entered.

With this fix, we push the check for exclusiveThread down into the JSLock,
and handle the bypassing of unneeded locking activity there while still
executing the necessary the VM stack data initialization.

* API/APIShims.h:
(JSC::APIEntryShim::APIEntryShim):
(JSC::APICallbackShim::shouldDropAllLocks):
* heap/MachineStackMarker.cpp:
(JSC::MachineThreads::addCurrentThread):
* runtime/JSLock.cpp:
(JSC::JSLockHolder::JSLockHolder):
(JSC::JSLockHolder::init):
(JSC::JSLockHolder::~JSLockHolder):
(JSC::JSLock::JSLock):
(JSC::JSLock::setExclusiveThread):
(JSC::JSLock::lock):
(JSLock::unlock):
(JSLock::currentThreadIsHoldingLock):
(JSLock::dropAllLocks):
(JSLock::grabAllLocks):
* runtime/JSLock.h:
(JSC::JSLock::exclusiveThread):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
(JSC::VM::exclusiveThread):
(JSC::VM::setExclusiveThread):
(JSC::VM::currentThreadIsHoldingAPILock):

Source/WebCore: 

No new tests.

* bindings/js/JSDOMBinding.cpp:
(WebCore::reportException):
- Added an assertion to ensure that we are holding the JSLock.
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::commonVM):
- Updated to use the new VM::setExclusiveThread().</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIAPIShimsh">trunk/Source/JavaScriptCore/API/APIShims.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMachineStackMarkercpp">trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLockcpp">trunk/Source/JavaScriptCore/runtime/JSLock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLockh">trunk/Source/JavaScriptCore/runtime/JSLock.h</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="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingcpp">trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMWindowBasecpp">trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIAPIShimsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/APIShims.h (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/APIShims.h        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/JavaScriptCore/API/APIShims.h        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -58,13 +58,13 @@
</span><span class="cx"> public:
</span><span class="cx">     APIEntryShim(ExecState* exec, bool registerThread = true)
</span><span class="cx">         : APIEntryShimWithoutLock(&amp;exec-&gt;vm(), registerThread)
</span><del>-        , m_lockHolder(exec-&gt;vm().exclusiveThread ? 0 : exec)
</del><ins>+        , m_lockHolder(&amp;exec-&gt;vm())
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     APIEntryShim(VM* vm, bool registerThread = true)
</span><span class="cx">         : APIEntryShimWithoutLock(vm, registerThread)
</span><del>-        , m_lockHolder(vm-&gt;exclusiveThread ? 0 : vm)
</del><ins>+        , m_lockHolder(vm)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -102,9 +102,6 @@
</span><span class="cx"> private:
</span><span class="cx">     static bool shouldDropAllLocks(VM&amp; vm)
</span><span class="cx">     {
</span><del>-        if (vm.exclusiveThread)
-            return false;
-
</del><span class="cx">         // If the VM is in the middle of being destroyed then we don't want to resurrect it
</span><span class="cx">         // by allowing DropAllLocks to ref it. By this point the APILock has already been 
</span><span class="cx">         // released anyways, so it doesn't matter that DropAllLocks is a no-op.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -1,3 +1,53 @@
</span><ins>+2014-02-24  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Need to initialize VM stack data even when the VM is on an exclusive thread.
+        &lt;https://webkit.org/b/129265&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        We check VM::exclusiveThread as an optimization to forego the need to do
+        JSLock locking. However, we recently started piggy backing on JSLock's
+        lock() and unlock() to initialize VM stack data (stackPointerAtVMEntry
+        and lastStackTop) to appropriate values for the current thread. This is
+        needed because we may be acquiring the lock to enter the VM on a different
+        thread.
+
+        As a result, we ended up not initializing the VM stack data when
+        VM::exclusiveThread causes us to bypass the locking activity. Even though
+        the VM::exclusiveThread will not have to deal with the VM being entered
+        on a different thread, it still needs to initialize the VM stack data.
+        The VM relies on that data being initialized properly once it has been
+        entered.
+
+        With this fix, we push the check for exclusiveThread down into the JSLock,
+        and handle the bypassing of unneeded locking activity there while still
+        executing the necessary the VM stack data initialization.
+
+        * API/APIShims.h:
+        (JSC::APIEntryShim::APIEntryShim):
+        (JSC::APICallbackShim::shouldDropAllLocks):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::addCurrentThread):
+        * runtime/JSLock.cpp:
+        (JSC::JSLockHolder::JSLockHolder):
+        (JSC::JSLockHolder::init):
+        (JSC::JSLockHolder::~JSLockHolder):
+        (JSC::JSLock::JSLock):
+        (JSC::JSLock::setExclusiveThread):
+        (JSC::JSLock::lock):
+        (JSLock::unlock):
+        (JSLock::currentThreadIsHoldingLock):
+        (JSLock::dropAllLocks):
+        (JSLock::grabAllLocks):
+        * runtime/JSLock.h:
+        (JSC::JSLock::exclusiveThread):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        (JSC::VM::exclusiveThread):
+        (JSC::VM::setExclusiveThread):
+        (JSC::VM::currentThreadIsHoldingAPILock):
+
</ins><span class="cx"> 2014-02-24  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         FTL should do polymorphic PutById inlining
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMachineStackMarkercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -182,7 +182,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MachineThreads::addCurrentThread()
</span><span class="cx"> {
</span><del>-    ASSERT(!m_heap-&gt;vm()-&gt;exclusiveThread || m_heap-&gt;vm()-&gt;exclusiveThread == currentThread());
</del><ins>+    ASSERT(!m_heap-&gt;vm()-&gt;hasExclusiveThread() || m_heap-&gt;vm()-&gt;exclusiveThread() == std::this_thread::get_id());
</ins><span class="cx"> 
</span><span class="cx">     if (!m_threadSpecific || threadSpecificGet(m_threadSpecific))
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLock.cpp (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -50,7 +50,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSLockHolder::JSLockHolder(ExecState* exec)
</span><del>-    : m_vm(exec ? &amp;exec-&gt;vm() : 0)
</del><ins>+    : m_vm(&amp;exec-&gt;vm())
</ins><span class="cx"> {
</span><span class="cx">     init();
</span><span class="cx"> }
</span><span class="lines">@@ -69,23 +69,21 @@
</span><span class="cx"> 
</span><span class="cx"> void JSLockHolder::init()
</span><span class="cx"> {
</span><del>-    if (m_vm)
-        m_vm-&gt;apiLock().lock();
</del><ins>+    m_vm-&gt;apiLock().lock();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSLockHolder::~JSLockHolder()
</span><span class="cx"> {
</span><del>-    if (!m_vm)
-        return;
-
</del><span class="cx">     RefPtr&lt;JSLock&gt; apiLock(&amp;m_vm-&gt;apiLock());
</span><span class="cx">     m_vm.clear();
</span><span class="cx">     apiLock-&gt;unlock();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSLock::JSLock(VM* vm)
</span><del>-    : m_lockCount(0)
</del><ins>+    : m_ownerThreadID(std::thread::id())
+    , m_lockCount(0)
</ins><span class="cx">     , m_lockDropDepth(0)
</span><ins>+    , m_hasExclusiveThread(false)
</ins><span class="cx">     , m_vm(vm)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -100,6 +98,13 @@
</span><span class="cx">     m_vm = 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSLock::setExclusiveThread(std::thread::id threadId)
+{
+    RELEASE_ASSERT(!m_lockCount &amp;&amp; m_ownerThreadID == std::thread::id());
+    m_hasExclusiveThread = (threadId != std::thread::id());
+    m_ownerThreadID = threadId;
+}
+
</ins><span class="cx"> void JSLock::lock()
</span><span class="cx"> {
</span><span class="cx">     lock(1);
</span><span class="lines">@@ -113,21 +118,21 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_lock.lock();
-
-    m_ownerThreadID = std::this_thread::get_id();
</del><ins>+    if (!m_hasExclusiveThread) {
+        m_lock.lock();
+        m_ownerThreadID = std::this_thread::get_id();
+    }
</ins><span class="cx">     ASSERT(!m_lockCount);
</span><span class="cx">     m_lockCount = lockCount;
</span><span class="cx"> 
</span><span class="cx">     if (!m_vm)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    WTFThreadData&amp; threadData = wtfThreadData();
-
</del><span class="cx">     RELEASE_ASSERT(!m_vm-&gt;stackPointerAtVMEntry());
</span><span class="cx">     void* p = &amp;p; // A proxy for the current stack pointer.
</span><span class="cx">     m_vm-&gt;setStackPointerAtVMEntry(p);
</span><span class="cx"> 
</span><ins>+    WTFThreadData&amp; threadData = wtfThreadData();
</ins><span class="cx">     m_vm-&gt;setLastStackTop(threadData.savedLastStackTop());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -146,8 +151,11 @@
</span><span class="cx">     if (!m_lockCount) {
</span><span class="cx">         if (m_vm)
</span><span class="cx">             m_vm-&gt;setStackPointerAtVMEntry(nullptr);
</span><del>-        m_ownerThreadID = std::thread::id();
-        m_lock.unlock();
</del><ins>+
+        if (!m_hasExclusiveThread) {
+            m_ownerThreadID = std::thread::id();
+            m_lock.unlock();
+        }
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -163,12 +171,20 @@
</span><span class="cx"> 
</span><span class="cx"> bool JSLock::currentThreadIsHoldingLock()
</span><span class="cx"> {
</span><ins>+    ASSERT(!m_hasExclusiveThread || (exclusiveThread() == std::this_thread::get_id()));
+    if (m_hasExclusiveThread)
+        return !!m_lockCount;
</ins><span class="cx">     return m_ownerThreadID == std::this_thread::get_id();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // This function returns the number of locks that were dropped.
</span><span class="cx"> unsigned JSLock::dropAllLocks(DropAllLocks* dropper)
</span><span class="cx"> {
</span><ins>+    if (m_hasExclusiveThread) {
+        ASSERT(exclusiveThread() == std::this_thread::get_id());
+        return 0;
+    }
+
</ins><span class="cx">     // Check if this thread is currently holding the lock.
</span><span class="cx">     // FIXME: Maybe we want to require this, guard with an ASSERT?
</span><span class="cx">     if (!currentThreadIsHoldingLock())
</span><span class="lines">@@ -193,6 +209,8 @@
</span><span class="cx"> 
</span><span class="cx"> void JSLock::grabAllLocks(DropAllLocks* dropper, unsigned droppedLockCount)
</span><span class="cx"> {
</span><ins>+    ASSERT(!m_hasExclusiveThread || !droppedLockCount);
+
</ins><span class="cx">     // If no locks were dropped, nothing to do!
</span><span class="cx">     if (!droppedLockCount)
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLock.h (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLock.h        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/JavaScriptCore/runtime/JSLock.h        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -94,6 +94,13 @@
</span><span class="cx"> 
</span><span class="cx">         VM* vm() { return m_vm; }
</span><span class="cx"> 
</span><ins>+        bool hasExclusiveThread() const { return m_hasExclusiveThread; }
+        std::thread::id exclusiveThread() const
+        {
+            ASSERT(m_hasExclusiveThread);
+            return m_ownerThreadID;
+        }
+        JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id);
</ins><span class="cx">         JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
</span><span class="cx"> 
</span><span class="cx">         void willDestroyVM(VM*);
</span><span class="lines">@@ -129,6 +136,7 @@
</span><span class="cx">         std::thread::id m_ownerThreadID;
</span><span class="cx">         intptr_t m_lockCount;
</span><span class="cx">         unsigned m_lockDropDepth;
</span><ins>+        bool m_hasExclusiveThread;
</ins><span class="cx">         VM* m_vm;
</span><span class="cx">     };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -208,7 +208,6 @@
</span><span class="cx"> #if ENABLE(REGEXP_TRACING)
</span><span class="cx">     , m_rtTraceList(new RTTraceList())
</span><span class="cx"> #endif
</span><del>-    , exclusiveThread(0)
</del><span class="cx">     , m_newStringsSinceLastHashCons(0)
</span><span class="cx"> #if ENABLE(ASSEMBLER)
</span><span class="cx">     , m_canUseAssembler(enableAssembler(executableAllocator))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -463,7 +463,9 @@
</span><span class="cx">         RTTraceList* m_rtTraceList;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-        ThreadIdentifier exclusiveThread;
</del><ins>+        bool hasExclusiveThread() const { return m_apiLock-&gt;hasExclusiveThread(); }
+        std::thread::id exclusiveThread() const { return m_apiLock-&gt;exclusiveThread(); }
+        void setExclusiveThread(std::thread::id threadId) { m_apiLock-&gt;setExclusiveThread(threadId); }
</ins><span class="cx"> 
</span><span class="cx">         JS_EXPORT_PRIVATE void resetDateCache();
</span><span class="cx"> 
</span><span class="lines">@@ -491,10 +493,7 @@
</span><span class="cx">         bool haveEnoughNewStringsToHashCons() { return m_newStringsSinceLastHashCons &gt; s_minNumberOfNewStringsToHashCons; }
</span><span class="cx">         void resetNewStringsSinceLastHashCons() { m_newStringsSinceLastHashCons = 0; }
</span><span class="cx"> 
</span><del>-        bool currentThreadIsHoldingAPILock() const
-        {
-            return m_apiLock-&gt;currentThreadIsHoldingLock() || exclusiveThread == currentThread();
-        }
</del><ins>+        bool currentThreadIsHoldingAPILock() const { return m_apiLock-&gt;currentThreadIsHoldingLock(); }
</ins><span class="cx"> 
</span><span class="cx">         JSLock&amp; apiLock() { return *m_apiLock; }
</span><span class="cx">         CodeCache* codeCache() { return m_codeCache.get(); }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/WebCore/ChangeLog        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2014-02-24  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Need to initialize VM stack data even when the VM is on an exclusive thread.
+        &lt;https://webkit.org/b/129265&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::reportException):
+        - Added an assertion to ensure that we are holding the JSLock.
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::JSDOMWindowBase::commonVM):
+        - Updated to use the new VM::setExclusiveThread().
+
</ins><span class="cx"> 2014-02-24  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a DefaultVisitedLinkProvider and route visited link actions through it
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -153,6 +153,7 @@
</span><span class="cx"> 
</span><span class="cx"> void reportException(ExecState* exec, JSValue exception, CachedScript* cachedScript)
</span><span class="cx"> {
</span><ins>+    RELEASE_ASSERT(exec-&gt;vm().currentThreadIsHoldingAPILock());
</ins><span class="cx">     if (isTerminatedExecutionException(exception))
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMWindowBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp (164626 => 164627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp        2014-02-25 04:00:13 UTC (rev 164626)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp        2014-02-25 04:44:09 UTC (rev 164627)
</span><span class="lines">@@ -224,7 +224,7 @@
</span><span class="cx">         vm-&gt;makeUsableFromMultipleThreads();
</span><span class="cx">         vm-&gt;heap.machineThreads().addCurrentThread();
</span><span class="cx"> #else
</span><del>-        vm-&gt;exclusiveThread = currentThread();
</del><ins>+        vm-&gt;setExclusiveThread(std::this_thread::get_id());
</ins><span class="cx"> #endif // !PLATFORM(IOS)
</span><span class="cx">         initNormalWorldClientData(vm);
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>