<!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>[172976] 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/172976">172976</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-08-26 14:24:40 -0700 (Tue, 26 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>TypeSet caches structureIDs even after the corresponding Structure could be GCed
https://bugs.webkit.org/show_bug.cgi?id=136178

Patch by Saam Barati &lt;sbarati@apple.com&gt; on 2014-08-26
Reviewed by Geoffrey Garen.

Currently, TypeSet will never remove StructureIDs from its cache,
even after the corresponding Structures could be garbage collected.
Now, when the Garbage Collector collects, and type profiling is
enabled, the Garbage Collector will invalidate all TypeSet caches.

* heap/Heap.cpp:
(JSC::Heap::collect):
* runtime/TypeSet.cpp:
(JSC::TypeSet::addTypeInformation):
(JSC::TypeSet::invalidateCache):
* runtime/TypeSet.h:
* runtime/VM.cpp:
(JSC::VM::invalidateTypeSetCache):
* runtime/VM.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeSetcpp">trunk/Source/JavaScriptCore/runtime/TypeSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeSeth">trunk/Source/JavaScriptCore/runtime/TypeSet.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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (172975 => 172976)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-08-26 21:06:07 UTC (rev 172975)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-08-26 21:24:40 UTC (rev 172976)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2014-08-26  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        TypeSet caches structureIDs even after the corresponding Structure could be GCed
+        https://bugs.webkit.org/show_bug.cgi?id=136178
+
+        Reviewed by Geoffrey Garen.
+
+        Currently, TypeSet will never remove StructureIDs from its cache,
+        even after the corresponding Structures could be garbage collected.
+        Now, when the Garbage Collector collects, and type profiling is 
+        enabled, the Garbage Collector will invalidate all TypeSet caches.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::TypeSet::invalidateCache):
+        * runtime/TypeSet.h:
+        * runtime/VM.cpp:
+        (JSC::VM::invalidateTypeSetCache):
+        * runtime/VM.h:
+
</ins><span class="cx"> 2014-08-26  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(r172794) + 32Bit build: for-in-base-reassigned-later-and-change-structure.js fail with NaN result
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (172975 => 172976)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-08-26 21:06:07 UTC (rev 172975)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-08-26 21:24:40 UTC (rev 172976)
</span><span class="lines">@@ -982,6 +982,7 @@
</span><span class="cx">     if (vm()-&gt;typeProfiler()) {
</span><span class="cx">         DeferGCForAWhile awhile(*this);
</span><span class="cx">         vm()-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;GC&quot;));
</span><ins>+        vm()-&gt;invalidateTypeSetCache();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT(!m_deferralDepth);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeSet.cpp (172975 => 172976)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-08-26 21:06:07 UTC (rev 172975)
+++ trunk/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-08-26 21:24:40 UTC (rev 172976)
</span><span class="lines">@@ -71,10 +71,9 @@
</span><span class="cx">     m_seenTypes = m_seenTypes | type;
</span><span class="cx"> 
</span><span class="cx">     if (id &amp;&amp; shape &amp;&amp; type != TypeString) {
</span><del>-        ASSERT(m_structureIDHistory.isValidKey(id));
-        auto iter = m_structureIDHistory.find(id);
-        if (iter == m_structureIDHistory.end()) {
-            m_structureIDHistory.set(id, 1);
</del><ins>+        ASSERT(m_structureIDCache.isValidValue(id));
+        auto addResult = m_structureIDCache.add(id);
+        if (addResult.isNewEntry) {
</ins><span class="cx">             // Make one more pass making sure that we don't have the same shape. (Same shapes may have different StructureIDs).
</span><span class="cx">             bool found = false;
</span><span class="cx">             String hash = shape-&gt;propertyHash();
</span><span class="lines">@@ -92,6 +91,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TypeSet::invalidateCache()
+{
+    m_structureIDCache.clear();
+}
+
</ins><span class="cx"> String TypeSet::seenTypes() const
</span><span class="cx"> {
</span><span class="cx">     if (m_seenTypes == TypeNothing)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeSet.h (172975 => 172976)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeSet.h        2014-08-26 21:06:07 UTC (rev 172975)
+++ trunk/Source/JavaScriptCore/runtime/TypeSet.h        2014-08-26 21:24:40 UTC (rev 172976)
</span><span class="lines">@@ -27,7 +27,7 @@
</span><span class="cx"> #define TypeSet_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;StructureIDTable.h&quot;
</span><del>-#include &lt;wtf/HashMap.h&gt;
</del><ins>+#include &lt;wtf/HashSet.h&gt;
</ins><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -92,6 +92,7 @@
</span><span class="cx">     TypeSet();
</span><span class="cx">     void addTypeInformation(RuntimeType, PassRefPtr&lt;StructureShape&gt;, StructureID);
</span><span class="cx">     static RuntimeType getRuntimeTypeForValue(JSValue);
</span><ins>+    void invalidateCache();
</ins><span class="cx">     JS_EXPORT_PRIVATE String seenTypes() const;
</span><span class="cx">     String displayName() const;
</span><span class="cx">     PassRefPtr&lt;Inspector::Protocol::Array&lt;String&gt;&gt; allPrimitiveTypeNames() const;
</span><span class="lines">@@ -104,7 +105,7 @@
</span><span class="cx"> 
</span><span class="cx">     uint32_t m_seenTypes;
</span><span class="cx">     Vector&lt;RefPtr&lt;StructureShape&gt;&gt; m_structureHistory;
</span><del>-    HashMap&lt;StructureID, uint8_t&gt; m_structureIDHistory;
</del><ins>+    HashSet&lt;StructureID&gt; m_structureIDCache;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (172975 => 172976)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-26 21:06:07 UTC (rev 172975)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-26 21:24:40 UTC (rev 172976)
</span><span class="lines">@@ -942,6 +942,18 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void VM::invalidateTypeSetCache()
+{
+    RELEASE_ASSERT(typeProfiler());
+
+    for (Bag&lt;TypeLocation&gt;::iterator iter = m_typeLocationInfo-&gt;begin(); !!iter; ++iter) {
+        TypeLocation* location = *iter;
+        location-&gt;m_instructionTypeSet-&gt;invalidateCache();
+        if (location-&gt;m_globalTypeSet)
+            location-&gt;m_globalTypeSet-&gt;invalidateCache();
+    }
+}
+
</ins><span class="cx"> void sanitizeStackForVM(VM* vm)
</span><span class="cx"> {
</span><span class="cx">     logSanitizeStack(vm);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (172975 => 172976)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-26 21:06:07 UTC (rev 172975)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-26 21:24:40 UTC (rev 172976)
</span><span class="lines">@@ -514,6 +514,7 @@
</span><span class="cx">         TypeProfiler* typeProfiler() { return m_typeProfiler.get(); }
</span><span class="cx">         TypeLocation* nextTypeLocation();
</span><span class="cx">         JS_EXPORT_PRIVATE void dumpTypeProfilerData();
</span><ins>+        void invalidateTypeSetCache();
</ins><span class="cx">         GlobalVariableID getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
</span><span class="cx"> 
</span><span class="cx">     private:
</span></span></pre>
</div>
</div>

</body>
</html>