<!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>[159795] 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/159795">159795</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2013-11-26 17:22:07 -0800 (Tue, 26 Nov 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Create a new SymbolTable every time code is loaded so that the watchpoints don't get reused
https://bugs.webkit.org/show_bug.cgi?id=124824

Reviewed by Oliver Hunt.
        
This helps with one shot closure inference as well as closure variable constant
inference, since without this, if code was reloaded from the cache then we would
think that the first run was actually an Nth run. This would cause us to think that
the watchpoint(s) should all be invalidated.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::stronglyVisitStrongReferences):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::symbolTable):
* runtime/Executable.cpp:
(JSC::FunctionExecutable::symbolTable):
* runtime/Executable.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::clone):
* runtime/SymbolTable.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutablecpp">trunk/Source/JavaScriptCore/runtime/Executable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutableh">trunk/Source/JavaScriptCore/runtime/Executable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSActivationh">trunk/Source/JavaScriptCore/runtime/JSActivation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTablecpp">trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTableh">trunk/Source/JavaScriptCore/runtime/SymbolTable.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2013-11-24  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Create a new SymbolTable every time code is loaded so that the watchpoints don't get reused
+        https://bugs.webkit.org/show_bug.cgi?id=124824
+
+        Reviewed by Oliver Hunt.
+        
+        This helps with one shot closure inference as well as closure variable constant
+        inference, since without this, if code was reloaded from the cache then we would
+        think that the first run was actually an Nth run. This would cause us to think that
+        the watchpoint(s) should all be invalidated.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::stronglyVisitStrongReferences):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::symbolTable):
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::symbolTable):
+        * runtime/Executable.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::clone):
+        * runtime/SymbolTable.h:
+
</ins><span class="cx"> 2013-11-26  Oliver Hunt  &lt;oliver@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Crash in JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseUnaryExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -1481,6 +1481,10 @@
</span><span class="cx"> #endif
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_heap-&gt;isDeferred());
</span><ins>+    
+    if (SymbolTable* symbolTable = other.symbolTable())
+        m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
+    
</ins><span class="cx">     setNumParameters(other.numParameters());
</span><span class="cx">     optimizeAfterWarmUp();
</span><span class="cx">     jitAfterWarmUp();
</span><span class="lines">@@ -1527,6 +1531,13 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_heap-&gt;isDeferred());
</span><span class="cx"> 
</span><ins>+    if (SymbolTable* symbolTable = unlinkedCodeBlock-&gt;symbolTable()) {
+        if (codeType() == FunctionCode &amp;&amp; symbolTable-&gt;captureCount())
+            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable-&gt;clone(*m_vm));
+        else
+            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
+    }
+    
</ins><span class="cx">     ASSERT(m_source);
</span><span class="cx">     setNumParameters(unlinkedCodeBlock-&gt;numParameters());
</span><span class="cx"> 
</span><span class="lines">@@ -2338,6 +2349,7 @@
</span><span class="cx"> {
</span><span class="cx">     visitor.append(&amp;m_globalObject);
</span><span class="cx">     visitor.append(&amp;m_ownerExecutable);
</span><ins>+    visitor.append(&amp;m_symbolTable);
</ins><span class="cx">     visitor.append(&amp;m_unlinkedCode);
</span><span class="cx">     if (m_rareData)
</span><span class="cx">         m_rareData-&gt;m_evalCodeCache.visitAggregate(visitor);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -722,7 +722,7 @@
</span><span class="cx">     StringJumpTable&amp; stringSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData-&gt;m_stringSwitchJumpTables[tableIndex]; }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-    SymbolTable* symbolTable() const { return m_unlinkedCode-&gt;symbolTable(); }
</del><ins>+    SymbolTable* symbolTable() const { return m_symbolTable.get(); }
</ins><span class="cx"> 
</span><span class="cx">     EvalCodeCache&amp; evalCodeCache() { createRareDataIfNecessary(); return m_rareData-&gt;m_evalCodeCache; }
</span><span class="cx"> 
</span><span class="lines">@@ -1039,6 +1039,7 @@
</span><span class="cx">     VM* m_vm;
</span><span class="cx"> 
</span><span class="cx">     RefCountedArray&lt;Instruction&gt; m_instructions;
</span><ins>+    WriteBarrier&lt;SymbolTable&gt; m_symbolTable;
</ins><span class="cx">     VirtualRegister m_thisRegister;
</span><span class="cx">     VirtualRegister m_argumentsRegister;
</span><span class="cx">     VirtualRegister m_activationRegister;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.cpp (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.cpp        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/runtime/Executable.cpp        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -533,6 +533,11 @@
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_unlinkedExecutable);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SymbolTable* FunctionExecutable::symbolTable(CodeSpecializationKind kind)
+{
+    return codeBlockFor(kind)-&gt;symbolTable();
+}
+
</ins><span class="cx"> void FunctionExecutable::clearCodeIfNotCompiling()
</span><span class="cx"> {
</span><span class="cx">     if (isCompiling())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.h (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.h        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/runtime/Executable.h        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -639,7 +639,7 @@
</span><span class="cx">     JSString* nameValue() const { return m_unlinkedExecutable-&gt;nameValue(); }
</span><span class="cx">     size_t parameterCount() const { return m_unlinkedExecutable-&gt;parameterCount(); } // Excluding 'this'!
</span><span class="cx">     String paramString() const;
</span><del>-    SymbolTable* symbolTable(CodeSpecializationKind kind) const { return m_unlinkedExecutable-&gt;symbolTable(kind); }
</del><ins>+    SymbolTable* symbolTable(CodeSpecializationKind);
</ins><span class="cx"> 
</span><span class="cx">     void clearCodeIfNotCompiling();
</span><span class="cx">     void clearUnlinkedCodeForRecompilationIfNotCompiling();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSActivationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSActivation.h (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSActivation.h        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/runtime/JSActivation.h        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx">     static JSActivation* create(VM&amp; vm, CallFrame* callFrame, Register* registers, CodeBlock* codeBlock)
</span><span class="cx">     {
</span><span class="cx">         SymbolTable* symbolTable = codeBlock-&gt;symbolTable();
</span><ins>+        ASSERT(codeBlock-&gt;codeType() == FunctionCode);
</ins><span class="cx">         JSActivation* activation = new (
</span><span class="cx">             NotNull,
</span><span class="cx">             allocateCell&lt;JSActivation&gt;(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -109,5 +109,31 @@
</span><span class="cx"> 
</span><span class="cx"> SymbolTable::~SymbolTable() { }
</span><span class="cx"> 
</span><ins>+SymbolTable* SymbolTable::clone(VM&amp; vm)
+{
+    SymbolTable* result = SymbolTable::create(vm);
+    
+    result-&gt;m_parameterCountIncludingThis = m_parameterCountIncludingThis;
+    result-&gt;m_usesNonStrictEval = m_usesNonStrictEval;
+    result-&gt;m_captureStart = m_captureStart;
+    result-&gt;m_captureEnd = m_captureEnd;
+    
+    Map::iterator iter = m_map.begin();
+    Map::iterator end = m_map.end();
+    for (; iter != end; ++iter) {
+        result-&gt;m_map.add(
+            iter-&gt;key,
+            SymbolTableEntry(iter-&gt;value.getIndex(), iter-&gt;value.getAttributes()));
+    }
+    
+    if (m_slowArguments) {
+        result-&gt;m_slowArguments = std::make_unique&lt;SlowArgument[]&gt;(parameterCount());
+        for (unsigned i = parameterCount(); i--;)
+            result-&gt;m_slowArguments[i] = m_slowArguments[i];
+    }
+    
+    return result;
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (159794 => 159795)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2013-11-26 23:55:16 UTC (rev 159794)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2013-11-27 01:22:07 UTC (rev 159795)
</span><span class="lines">@@ -465,6 +465,8 @@
</span><span class="cx">     // 0 if we don't capture any arguments; parameterCount() in length if we do.
</span><span class="cx">     const SlowArgument* slowArguments() { return m_slowArguments.get(); }
</span><span class="cx">     void setSlowArguments(std::unique_ptr&lt;SlowArgument[]&gt; slowArguments) { m_slowArguments = std::move(slowArguments); }
</span><ins>+    
+    SymbolTable* clone(VM&amp;);
</ins><span class="cx"> 
</span><span class="cx">     DECLARE_EXPORT_INFO;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>