<!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>[199409] releases/WebKitGTK/webkit-2.12/Source/WTF</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/199409">199409</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-04-12 23:41:58 -0700 (Tue, 12 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/198345">r198345</a> - Silence leaks in ParkingLot
https://bugs.webkit.org/show_bug.cgi?id=155510

Reviewed by Alexey Proskuryakov.

ParkingLot has a concurrent hashtable that it reallocates on demand. It will not reallocate
it in steady state. The hashtable is sized to accommodate the high watermark of the number
of active threads - so long as the program doesn't just keep starting an unbounded number
of threads that are all active, the hashtable will stop resizing. Each resize operation is
designed to stay out of the way of the data-access-parallel normal path, in which two
threads operating on different lock addresses don't have to synchronize. To do this, it
simply drops the old hashtable without deleting it, so that threads that were still using
it don't crash. They will realize that they have the wrong hashtable before doing anything
bad, but we don't have a way of proving when all of those threads are no longer going to
read from the old hashtables. So, we just leak them.

This is a bounded leak, since the hashtable resizes exponentially. Thus the total memory
utilization of all hashtables, including the leaked ones, converges to a linear function of
the current hashtable's size (it's 2 * size of current hashtable).

But this leak is a problem for leaks tools, which will always report this leak. This is not
useful. It's better to silence the leak. That's what this patch does by ensuring that all
hashtables, including leaked ones, end up in a global vector. This is perf-neutral.

This requires making a StaticWordLock variant of WordLock. That's probably the biggest part
of this change.

* wtf/ParkingLot.cpp:
* wtf/WordLock.cpp:
(WTF::WordLockBase::lockSlow):
(WTF::WordLockBase::unlockSlow):
(WTF::WordLock::lockSlow): Deleted.
(WTF::WordLock::unlockSlow): Deleted.
* wtf/WordLock.h:
(WTF::WordLockBase::lock):
(WTF::WordLockBase::isLocked):
(WTF::WordLock::WordLock):
(WTF::WordLock::lock): Deleted.
(WTF::WordLock::isLocked): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212SourceWTFChangeLog">releases/WebKitGTK/webkit-2.12/Source/WTF/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWTFwtfParkingLotcpp">releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/ParkingLot.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWTFwtfWordLockcpp">releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWTFwtfWordLockh">releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit212SourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WTF/ChangeLog (199408 => 199409)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WTF/ChangeLog        2016-04-13 06:37:10 UTC (rev 199408)
+++ releases/WebKitGTK/webkit-2.12/Source/WTF/ChangeLog        2016-04-13 06:41:58 UTC (rev 199409)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2016-03-17  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Silence leaks in ParkingLot
+        https://bugs.webkit.org/show_bug.cgi?id=155510
+
+        Reviewed by Alexey Proskuryakov.
+
+        ParkingLot has a concurrent hashtable that it reallocates on demand. It will not reallocate
+        it in steady state. The hashtable is sized to accommodate the high watermark of the number
+        of active threads - so long as the program doesn't just keep starting an unbounded number
+        of threads that are all active, the hashtable will stop resizing. Each resize operation is
+        designed to stay out of the way of the data-access-parallel normal path, in which two
+        threads operating on different lock addresses don't have to synchronize. To do this, it
+        simply drops the old hashtable without deleting it, so that threads that were still using
+        it don't crash. They will realize that they have the wrong hashtable before doing anything
+        bad, but we don't have a way of proving when all of those threads are no longer going to
+        read from the old hashtables. So, we just leak them.
+
+        This is a bounded leak, since the hashtable resizes exponentially. Thus the total memory
+        utilization of all hashtables, including the leaked ones, converges to a linear function of
+        the current hashtable's size (it's 2 * size of current hashtable).
+
+        But this leak is a problem for leaks tools, which will always report this leak. This is not
+        useful. It's better to silence the leak. That's what this patch does by ensuring that all
+        hashtables, including leaked ones, end up in a global vector. This is perf-neutral.
+
+        This requires making a StaticWordLock variant of WordLock. That's probably the biggest part
+        of this change.
+
+        * wtf/ParkingLot.cpp:
+        * wtf/WordLock.cpp:
+        (WTF::WordLockBase::lockSlow):
+        (WTF::WordLockBase::unlockSlow):
+        (WTF::WordLock::lockSlow): Deleted.
+        (WTF::WordLock::unlockSlow): Deleted.
+        * wtf/WordLock.h:
+        (WTF::WordLockBase::lock):
+        (WTF::WordLockBase::isLocked):
+        (WTF::WordLock::WordLock):
+        (WTF::WordLock::lock): Deleted.
+        (WTF::WordLock::isLocked): Deleted.
+
</ins><span class="cx"> 2016-03-08  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Support iterating over an OptionSet and checking if it is empty
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWTFwtfParkingLotcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/ParkingLot.cpp (199408 => 199409)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/ParkingLot.cpp        2016-04-13 06:37:10 UTC (rev 199408)
+++ releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/ParkingLot.cpp        2016-04-13 06:41:58 UTC (rev 199409)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -177,6 +177,12 @@
</span><span class="cx">     char padding[64];
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct Hashtable;
+
+// We track all allocated hashtables so that hashtable resizing doesn't anger leak detectors.
+Vector&lt;Hashtable*&gt;* hashtables;
+StaticWordLock hashtablesLock;
+
</ins><span class="cx"> struct Hashtable {
</span><span class="cx">     unsigned size;
</span><span class="cx">     Atomic&lt;Bucket*&gt; data[1];
</span><span class="lines">@@ -188,11 +194,28 @@
</span><span class="cx">         Hashtable* result = static_cast&lt;Hashtable*&gt;(
</span><span class="cx">             fastZeroedMalloc(sizeof(Hashtable) + sizeof(Atomic&lt;Bucket*&gt;) * (size - 1)));
</span><span class="cx">         result-&gt;size = size;
</span><ins>+
+        {
+            // This is not fast and it's not data-access parallel, but that's fine, because
+            // hashtable resizing is guaranteed to be rare and it will never happen in steady
+            // state.
+            WordLockHolder locker(hashtablesLock);
+            if (!hashtables)
+                hashtables = new Vector&lt;Hashtable*&gt;();
+            hashtables-&gt;append(result);
+        }
+        
</ins><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static void destroy(Hashtable* hashtable)
</span><span class="cx">     {
</span><ins>+        {
+            // This is not fast, but that's OK. See comment in create().
+            WordLockHolder locker(hashtablesLock);
+            hashtables-&gt;removeFirst(hashtable);
+        }
+        
</ins><span class="cx">         fastFree(hashtable);
</span><span class="cx">     }
</span><span class="cx"> };
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWTFwtfWordLockcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.cpp (199408 => 199409)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.cpp        2016-04-13 06:37:10 UTC (rev 199408)
+++ releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.cpp        2016-04-13 06:41:58 UTC (rev 199409)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> 
</span><span class="cx"> } // anonymous namespace
</span><span class="cx"> 
</span><del>-NEVER_INLINE void WordLock::lockSlow()
</del><ins>+NEVER_INLINE void WordLockBase::lockSlow()
</ins><span class="cx"> {
</span><span class="cx">     unsigned spinCount = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -178,7 +178,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE void WordLock::unlockSlow()
</del><ins>+NEVER_INLINE void WordLockBase::unlockSlow()
</ins><span class="cx"> {
</span><span class="cx">     // The fast path can fail either because of spurious weak CAS failure, or because someone put a
</span><span class="cx">     // thread on the queue, or the queue lock is held. If the queue lock is held, it can only be
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWTFwtfWordLockh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.h (199408 => 199409)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.h        2016-04-13 06:37:10 UTC (rev 199408)
+++ releases/WebKitGTK/webkit-2.12/Source/WTF/wtf/WordLock.h        2016-04-13 06:41:58 UTC (rev 199409)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -42,14 +42,7 @@
</span><span class="cx"> // Lock instead. WordLock sits lower in the stack and is used to implement Lock, so Lock is the main
</span><span class="cx"> // client of WordLock.
</span><span class="cx"> 
</span><del>-class WordLock {
-    WTF_MAKE_NONCOPYABLE(WordLock);
-public:
-    WordLock()
-    {
-        m_word.store(0, std::memory_order_relaxed);
-    }
-
</del><ins>+struct WordLockBase {
</ins><span class="cx">     void lock()
</span><span class="cx">     {
</span><span class="cx">         if (LIKELY(m_word.compareExchangeWeak(0, isLockedBit, std::memory_order_acquire))) {
</span><span class="lines">@@ -80,7 +73,7 @@
</span><span class="cx">         return isHeld();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-private:
</del><ins>+protected:
</ins><span class="cx">     friend struct TestWebKitAPI::LockInspector;
</span><span class="cx">     
</span><span class="cx">     static const uintptr_t isLockedBit = 1;
</span><span class="lines">@@ -99,12 +92,23 @@
</span><span class="cx">     Atomic&lt;uintptr_t&gt; m_word;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-typedef Locker&lt;WordLock&gt; WordLockHolder;
</del><ins>+class WordLock : public WordLockBase {
+    WTF_MAKE_NONCOPYABLE(WordLock);
+public:
+    WordLock()
+    {
+        m_word.store(0, std::memory_order_relaxed);
+    }
+};
</ins><span class="cx"> 
</span><ins>+typedef WordLockBase StaticWordLock;
+typedef Locker&lt;WordLockBase&gt; WordLockHolder;
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> using WTF::WordLock;
</span><span class="cx"> using WTF::WordLockHolder;
</span><ins>+using WTF::StaticWordLock;
</ins><span class="cx"> 
</span><span class="cx"> #endif // WTF_WordLock_h
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>