<!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>[179319] trunk</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/179319">179319</a></dd>
<dt>Author</dt> <dd>ggaren@apple.com</dd>
<dt>Date</dt> <dd>2015-01-28 16:58:13 -0800 (Wed, 28 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Removed fastMallocForbid / fastMallocAllow
https://bugs.webkit.org/show_bug.cgi?id=141012

Reviewed by Mark Hahnenberg.

Source/JavaScriptCore:

Copy non-current thread stacks before scanning them instead of scanning
them in-place.

This operation is uncommon (i.e., never in the web content process),
and even in a stress test with 4 threads it only copies about 27kB,
so I think the performance cost is OK.

Scanning in-place requires a complex dance where we constrain our GC
data structures not to use malloc, free, or any other interesting functions
that might acquire locks. We've gotten this wrong many times in the past,
and I just got it wrong again yesterday. Since this code path is rarely
tested, I want it to just make sense, and not depend on or constrain the
details of the rest of the GC heap's design.

* heap/MachineStackMarker.cpp:
(JSC::otherThreadStack): Factored out a helper function for dealing with
unaligned and/or backwards pointers.

(JSC::MachineThreads::tryCopyOtherThreadStack): This is now the only
constrained function, and it only calls memcpy and low-level thread APIs.

(JSC::MachineThreads::tryCopyOtherThreadStacks): The design here is that
you do one pass over all the threads to compute their combined size,
and then a second pass to do all the copying. In theory, the threads may
grow in between passes, in which case you'll continue until the threads
stop growing. In practice, you never continue.

(JSC::growBuffer): Helper function for growing.

(JSC::MachineThreads::gatherConservativeRoots):
(JSC::MachineThreads::gatherFromOtherThread): Deleted.
* heap/MachineStackMarker.h: Updated for interface changes.

Source/WTF:

Removed the forbid / allow API because it is no longer used.

* wtf/FastMalloc.cpp:
(WTF::tryFastMalloc):
(WTF::fastMalloc):
(WTF::tryFastCalloc):
(WTF::fastCalloc):
(WTF::fastFree):
(WTF::tryFastRealloc):
(WTF::fastRealloc):
(WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
(WTF::isForbidden): Deleted.
(WTF::fastMallocForbid): Deleted.
(WTF::fastMallocAllow): Deleted.
(WTF::initializeIsForbiddenKey): Deleted.
* wtf/FastMalloc.h:

Tools:

Fixed a test bug I noticed while testing.

* DumpRenderTree/JavaScriptThreading.cpp:
(stopJavaScriptThreads): Lock the javaScriptThreads lock before
accessing javaScriptThreads -- otherwise, you'll ASSERT.</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceJavaScriptCoreheapMachineStackMarkerh">trunk/Source/JavaScriptCore/heap/MachineStackMarker.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfFastMalloccpp">trunk/Source/WTF/wtf/FastMalloc.cpp</a></li>
<li><a href="#trunkSourceWTFwtfFastMalloch">trunk/Source/WTF/wtf/FastMalloc.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreeJavaScriptThreadingcpp">trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2015-01-28  Geoffrey Garen  &lt;ggaren@apple.com&gt;
+
+        Removed fastMallocForbid / fastMallocAllow
+        https://bugs.webkit.org/show_bug.cgi?id=141012
+
+        Reviewed by Mark Hahnenberg.
+
+        Copy non-current thread stacks before scanning them instead of scanning
+        them in-place.
+
+        This operation is uncommon (i.e., never in the web content process),
+        and even in a stress test with 4 threads it only copies about 27kB,
+        so I think the performance cost is OK.
+
+        Scanning in-place requires a complex dance where we constrain our GC
+        data structures not to use malloc, free, or any other interesting functions
+        that might acquire locks. We've gotten this wrong many times in the past,
+        and I just got it wrong again yesterday. Since this code path is rarely
+        tested, I want it to just make sense, and not depend on or constrain the
+        details of the rest of the GC heap's design.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::otherThreadStack): Factored out a helper function for dealing with
+        unaligned and/or backwards pointers.
+
+        (JSC::MachineThreads::tryCopyOtherThreadStack): This is now the only
+        constrained function, and it only calls memcpy and low-level thread APIs.
+
+        (JSC::MachineThreads::tryCopyOtherThreadStacks): The design here is that
+        you do one pass over all the threads to compute their combined size,
+        and then a second pass to do all the copying. In theory, the threads may
+        grow in between passes, in which case you'll continue until the threads
+        stop growing. In practice, you never continue.
+
+        (JSC::growBuffer): Helper function for growing.
+
+        (JSC::MachineThreads::gatherConservativeRoots):
+        (JSC::MachineThreads::gatherFromOtherThread): Deleted.
+        * heap/MachineStackMarker.h: Updated for interface changes.
+
</ins><span class="cx"> 2015-01-28  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: remove CSS.setPropertyText, CSS.toggleProperty and related dead code
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMachineStackMarkercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -413,57 +413,91 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MachineThreads::gatherFromOtherThread(ConservativeRoots&amp; conservativeRoots, Thread* thread, JITStubRoutineSet&amp; jitStubRoutines, CodeBlockSet&amp; codeBlocks)
</del><ins>+static std::pair&lt;void*, size_t&gt; otherThreadStack(void* stackBase, const PlatformThreadRegisters&amp; registers)
</ins><span class="cx"> {
</span><del>-    PlatformThreadRegisters regs;
-    size_t regSize = getPlatformThreadRegisters(thread-&gt;platformThread, regs);
</del><ins>+    void* begin = stackBase;
+    void* end = reinterpret_cast&lt;void*&gt;(
+        WTF::roundUpToMultipleOf&lt;sizeof(void*)&gt;(
+            reinterpret_cast&lt;uintptr_t&gt;(
+                otherThreadStackPointer(registers))));
+    if (begin &gt; end)
+        std::swap(begin, end);
+    return std::make_pair(begin, static_cast&lt;char*&gt;(end) - static_cast&lt;char*&gt;(begin));
+}
</ins><span class="cx"> 
</span><del>-    conservativeRoots.add(static_cast&lt;void*&gt;(&amp;regs), static_cast&lt;void*&gt;(reinterpret_cast&lt;char*&gt;(&amp;regs) + regSize), jitStubRoutines, codeBlocks);
</del><ins>+// This function must not call malloc(), free(), or any other function that might
+// acquire a lock. Since 'thread' is suspended, trying to acquire a lock
+// will deadlock if 'thread' holds that lock.
+void MachineThreads::tryCopyOtherThreadStack(Thread* thread, void* buffer, size_t capacity, size_t* size)
+{
+    PlatformThreadRegisters registers;
+    size_t registersSize = getPlatformThreadRegisters(thread-&gt;platformThread, registers);
+    std::pair&lt;void*, size_t&gt; stack = otherThreadStack(thread-&gt;stackBase, registers);
</ins><span class="cx"> 
</span><del>-    void* stackPointer = otherThreadStackPointer(regs);
-    void* stackBase = thread-&gt;stackBase;
-    stackPointer = reinterpret_cast&lt;void*&gt;(WTF::roundUpToMultipleOf&lt;sizeof(void*)&gt;(reinterpret_cast&lt;uintptr_t&gt;(stackPointer)));
-    conservativeRoots.add(stackPointer, stackBase, jitStubRoutines, codeBlocks);
</del><ins>+    bool canCopy = *size + registersSize + stack.second &lt;= capacity;
</ins><span class="cx"> 
</span><del>-    freePlatformThreadRegisters(regs);
</del><ins>+    if (canCopy)
+        memcpy(static_cast&lt;char*&gt;(buffer) + *size, &amp;registers, registersSize);
+    *size += registersSize;
+
+    if (canCopy)
+        memcpy(static_cast&lt;char*&gt;(buffer) + *size, stack.first, stack.second);
+    *size += stack.second;
+
+    freePlatformThreadRegisters(registers);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MachineThreads::gatherConservativeRoots(ConservativeRoots&amp; conservativeRoots, JITStubRoutineSet&amp; jitStubRoutines, CodeBlockSet&amp; codeBlocks, void* stackCurrent, RegisterState&amp; registers)
</del><ins>+bool MachineThreads::tryCopyOtherThreadStacks(MutexLocker&amp;, void* buffer, size_t capacity, size_t* size)
</ins><span class="cx"> {
</span><del>-    gatherFromCurrentThread(conservativeRoots, jitStubRoutines, codeBlocks, stackCurrent, registers);
</del><ins>+    *size = 0;
</ins><span class="cx"> 
</span><del>-    if (m_threadSpecific) {
-        PlatformThread currentPlatformThread = getCurrentPlatformThread();
</del><ins>+    PlatformThread currentPlatformThread = getCurrentPlatformThread();
+    for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
+        if (!equalThread(thread-&gt;platformThread, currentPlatformThread))
+            suspendThread(thread-&gt;platformThread);
+    }
</ins><span class="cx"> 
</span><del>-        MutexLocker lock(m_registeredThreadsMutex);
</del><ins>+    for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
+        if (!equalThread(thread-&gt;platformThread, currentPlatformThread))
+            tryCopyOtherThreadStack(thread, buffer, capacity, size);
+    }
</ins><span class="cx"> 
</span><del>-#ifndef NDEBUG
-        // Forbid malloc during the gather phase. The gather phase suspends
-        // threads, so a malloc during gather would risk a deadlock with a
-        // thread that had been suspended while holding the malloc lock.
-        fastMallocForbid();
-#endif
-        for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
-            if (!equalThread(thread-&gt;platformThread, currentPlatformThread))
-                suspendThread(thread-&gt;platformThread);
-        }
</del><ins>+    for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
+        if (!equalThread(thread-&gt;platformThread, currentPlatformThread))
+            resumeThread(thread-&gt;platformThread);
+    }
</ins><span class="cx"> 
</span><del>-        // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
-        // and since this is a shared heap, they are real locks.
-        for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
-            if (!equalThread(thread-&gt;platformThread, currentPlatformThread))
-                gatherFromOtherThread(conservativeRoots, thread, jitStubRoutines, codeBlocks);
-        }
</del><ins>+    return *size &lt;= capacity;
+}
</ins><span class="cx"> 
</span><del>-        for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
-            if (!equalThread(thread-&gt;platformThread, currentPlatformThread))
-                resumeThread(thread-&gt;platformThread);
-        }
</del><ins>+static void growBuffer(size_t size, void** buffer, size_t* capacity)
+{
+    if (*buffer)
+        fastFree(*buffer);
</ins><span class="cx"> 
</span><del>-#ifndef NDEBUG
-        fastMallocAllow();
-#endif
-    }
</del><ins>+    *capacity = WTF::roundUpToMultipleOf(WTF::pageSize(), size * 2);
+    *buffer = fastMalloc(*capacity);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MachineThreads::gatherConservativeRoots(ConservativeRoots&amp; conservativeRoots, JITStubRoutineSet&amp; jitStubRoutines, CodeBlockSet&amp; codeBlocks, void* stackCurrent, RegisterState&amp; currentThreadRegisters)
+{
+    gatherFromCurrentThread(conservativeRoots, jitStubRoutines, codeBlocks, stackCurrent, currentThreadRegisters);
+
+    if (!m_threadSpecific)
+        return;
+
+    size_t size;
+    size_t capacity = 0;
+    void* buffer = nullptr;
+    MutexLocker lock(m_registeredThreadsMutex);
+    while (!tryCopyOtherThreadStacks(lock, buffer, capacity, &amp;size))
+        growBuffer(size, &amp;buffer, &amp;capacity);
+
+    if (!buffer)
+        return;
+
+    conservativeRoots.add(buffer, static_cast&lt;char*&gt;(buffer) + size, jitStubRoutines, codeBlocks);
+    fastFree(buffer);
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMachineStackMarkerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MachineStackMarker.h (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MachineStackMarker.h        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Source/JavaScriptCore/heap/MachineStackMarker.h        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -48,15 +48,16 @@
</span><span class="cx">         JS_EXPORT_PRIVATE void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
</span><span class="cx"> 
</span><span class="cx">     private:
</span><ins>+        class Thread;
+
</ins><span class="cx">         void gatherFromCurrentThread(ConservativeRoots&amp;, JITStubRoutineSet&amp;, CodeBlockSet&amp;, void* stackCurrent, RegisterState&amp; registers);
</span><span class="cx"> 
</span><del>-        class Thread;
</del><ins>+        void tryCopyOtherThreadStack(Thread*, void*, size_t capacity, size_t*);
+        bool tryCopyOtherThreadStacks(MutexLocker&amp;, void*, size_t capacity, size_t*);
</ins><span class="cx"> 
</span><span class="cx">         static void removeThread(void*);
</span><span class="cx">         void removeCurrentThread();
</span><span class="cx"> 
</span><del>-        void gatherFromOtherThread(ConservativeRoots&amp;, Thread*, JITStubRoutineSet&amp;, CodeBlockSet&amp;);
-
</del><span class="cx">         Mutex m_registeredThreadsMutex;
</span><span class="cx">         Thread* m_registeredThreads;
</span><span class="cx">         WTF::ThreadSpecificKey m_threadSpecific;
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Source/WTF/ChangeLog        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2015-01-28  Geoffrey Garen  &lt;ggaren@apple.com&gt;
+
+        Removed fastMallocForbid / fastMallocAllow
+        https://bugs.webkit.org/show_bug.cgi?id=141012
+
+        Reviewed by Mark Hahnenberg.
+
+        Removed the forbid / allow API because it is no longer used.
+
+        * wtf/FastMalloc.cpp:
+        (WTF::tryFastMalloc):
+        (WTF::fastMalloc):
+        (WTF::tryFastCalloc):
+        (WTF::fastCalloc):
+        (WTF::fastFree):
+        (WTF::tryFastRealloc):
+        (WTF::fastRealloc):
+        (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
+        (WTF::isForbidden): Deleted.
+        (WTF::fastMallocForbid): Deleted.
+        (WTF::fastMallocAllow): Deleted.
+        (WTF::initializeIsForbiddenKey): Deleted.
+        * wtf/FastMalloc.h:
+
</ins><span class="cx"> 2015-01-28  Dana Burkart  &lt;dburkart@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move ASan flag settings from DebugRelease.xcconfig to Base.xcconfig
</span></span></pre></div>
<a id="trunkSourceWTFwtfFastMalloccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/FastMalloc.cpp (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/FastMalloc.cpp        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Source/WTF/wtf/FastMalloc.cpp        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -117,74 +117,8 @@
</span><span class="cx"> // Use a background thread to periodically scavenge memory to release back to the system
</span><span class="cx"> #define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 1
</span><span class="cx"> 
</span><del>-#ifndef NDEBUG
</del><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-#if OS(WINDOWS)
-
-static DWORD isForibiddenTlsIndex = TLS_OUT_OF_INDEXES;
-static const LPVOID kTlsAllowValue = reinterpret_cast&lt;LPVOID&gt;(0); // Must be zero.
-static const LPVOID kTlsForbiddenValue = reinterpret_cast&lt;LPVOID&gt;(1);
-
-#if !ASSERT_DISABLED
-static bool isForbidden()
-{
-    // By default, fastMalloc is allowed so we don't allocate the
-    // tls index unless we're asked to make it forbidden. If TlsSetValue
-    // has not been called on a thread, the value returned by TlsGetValue is 0.
-    return (isForibiddenTlsIndex != TLS_OUT_OF_INDEXES) &amp;&amp; (TlsGetValue(isForibiddenTlsIndex) == kTlsForbiddenValue);
-}
-#endif
-
-void fastMallocForbid()
-{
-    if (isForibiddenTlsIndex == TLS_OUT_OF_INDEXES)
-        isForibiddenTlsIndex = TlsAlloc(); // a little racey, but close enough for debug only
-    TlsSetValue(isForibiddenTlsIndex, kTlsForbiddenValue);
-}
-
-void fastMallocAllow()
-{
-    if (isForibiddenTlsIndex == TLS_OUT_OF_INDEXES)
-        return;
-    TlsSetValue(isForibiddenTlsIndex, kTlsAllowValue);
-}
-
-#else // !OS(WINDOWS)
-
-static pthread_key_t isForbiddenKey;
-static pthread_once_t isForbiddenKeyOnce = PTHREAD_ONCE_INIT;
-static void initializeIsForbiddenKey()
-{
-  pthread_key_create(&amp;isForbiddenKey, 0);
-}
-
-#if !ASSERT_DISABLED
-static bool isForbidden()
-{
-    pthread_once(&amp;isForbiddenKeyOnce, initializeIsForbiddenKey);
-    return !!pthread_getspecific(isForbiddenKey);
-}
-#endif
-
-void fastMallocForbid()
-{
-    pthread_once(&amp;isForbiddenKeyOnce, initializeIsForbiddenKey);
-    pthread_setspecific(isForbiddenKey, &amp;isForbiddenKey);
-}
-
-void fastMallocAllow()
-{
-    pthread_once(&amp;isForbiddenKeyOnce, initializeIsForbiddenKey);
-    pthread_setspecific(isForbiddenKey, 0);
-}
-#endif // OS(WINDOWS)
-
-} // namespace WTF
-#endif // NDEBUG
-
-namespace WTF {
-
</del><span class="cx"> void* fastZeroedMalloc(size_t n) 
</span><span class="cx"> {
</span><span class="cx">     void* result = fastMalloc(n);
</span><span class="lines">@@ -230,15 +164,11 @@
</span><span class="cx"> 
</span><span class="cx"> TryMallocReturnValue tryFastMalloc(size_t n) 
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
-
</del><span class="cx">     return malloc(n);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void* fastMalloc(size_t n) 
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
-
</del><span class="cx">     void* result = malloc(n);
</span><span class="cx">     if (!result)
</span><span class="cx">         CRASH();
</span><span class="lines">@@ -248,14 +178,11 @@
</span><span class="cx"> 
</span><span class="cx"> TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size)
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
</del><span class="cx">     return calloc(n_elements, element_size);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void* fastCalloc(size_t n_elements, size_t element_size)
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
-
</del><span class="cx">     void* result = calloc(n_elements, element_size);
</span><span class="cx">     if (!result)
</span><span class="cx">         CRASH();
</span><span class="lines">@@ -265,19 +192,16 @@
</span><span class="cx"> 
</span><span class="cx"> void fastFree(void* p)
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
</del><span class="cx">     free(p);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TryMallocReturnValue tryFastRealloc(void* p, size_t n)
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
</del><span class="cx">     return realloc(p, n);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void* fastRealloc(void* p, size_t n)
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
</del><span class="cx">     void* result = realloc(p, n);
</span><span class="cx">     if (!result)
</span><span class="cx">         CRASH();
</span><span class="lines">@@ -320,7 +244,6 @@
</span><span class="cx"> 
</span><span class="cx"> void* fastMalloc(size_t size)
</span><span class="cx"> {
</span><del>-    ASSERT(!isForbidden());
</del><span class="cx">     return bmalloc::api::malloc(size);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -4017,10 +3940,6 @@
</span><span class="cx"> static ALWAYS_INLINE void* do_malloc(size_t size) {
</span><span class="cx">   void* ret = NULL;
</span><span class="cx"> 
</span><del>-#ifdef WTF_CHANGES
-    ASSERT(!isForbidden());
-#endif
-
</del><span class="cx">   // The following call forces module initialization
</span><span class="cx">   TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCache();
</span><span class="cx"> #ifndef WTF_CHANGES
</span></span></pre></div>
<a id="trunkSourceWTFwtfFastMalloch"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/FastMalloc.h (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/FastMalloc.h        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Source/WTF/wtf/FastMalloc.h        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -76,11 +76,6 @@
</span><span class="cx"> 
</span><span class="cx">     WTF_EXPORT_PRIVATE void fastFree(void*);
</span><span class="cx"> 
</span><del>-#ifndef NDEBUG    
-    WTF_EXPORT_PRIVATE void fastMallocForbid();
-    WTF_EXPORT_PRIVATE void fastMallocAllow();
-#endif
-
</del><span class="cx">     WTF_EXPORT_PRIVATE void releaseFastMallocFreeMemory();
</span><span class="cx">     
</span><span class="cx">     struct FastMallocStatistics {
</span><span class="lines">@@ -109,11 +104,6 @@
</span><span class="cx"> using WTF::tryFastRealloc;
</span><span class="cx"> using WTF::tryFastZeroedMalloc;
</span><span class="cx"> 
</span><del>-#ifndef NDEBUG    
-using WTF::fastMallocForbid;
-using WTF::fastMallocAllow;
-#endif
-
</del><span class="cx"> #if COMPILER(GCC) &amp;&amp; OS(DARWIN)
</span><span class="cx"> #define WTF_PRIVATE_INLINE __private_extern__ inline __attribute__((always_inline))
</span><span class="cx"> #elif COMPILER(GCC)
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Tools/ChangeLog        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2015-01-28  Geoffrey Garen  &lt;ggaren@apple.com&gt;
+
+        Removed fastMallocForbid / fastMallocAllow
+        https://bugs.webkit.org/show_bug.cgi?id=141012
+
+        Reviewed by Mark Hahnenberg.
+
+        Fixed a test bug I noticed while testing.
+
+        * DumpRenderTree/JavaScriptThreading.cpp:
+        (stopJavaScriptThreads): Lock the javaScriptThreads lock before
+        accessing javaScriptThreads -- otherwise, you'll ASSERT.
+
</ins><span class="cx"> 2015-01-28  Dana Burkart  &lt;dburkart@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         asan.xcconfig should use CLANG_ADDRESS_SANITIZER=YES instead of -fsanitize=address
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeJavaScriptThreadingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp (179318 => 179319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp        2015-01-29 00:50:53 UTC (rev 179318)
+++ trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp        2015-01-29 00:58:13 UTC (rev 179319)
</span><span class="lines">@@ -147,7 +147,10 @@
</span><span class="cx">     for (size_t i = 0; i &lt; javaScriptThreadsCount; ++i)
</span><span class="cx">         waitForThreadCompletion(threads[i]);
</span><span class="cx"> 
</span><del>-    javaScriptThreads().clear();
</del><ins>+    {
+        MutexLocker locker(javaScriptThreadsMutex());
+        javaScriptThreads().clear();
+    }
</ins><span class="cx"> 
</span><span class="cx">     JSContextGroupRelease(javaScriptThreadsGroup);
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>