<!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>[159395] 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/159395">159395</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2013-11-17 18:10:42 -0800 (Sun, 17 Nov 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Simplify WatchpointSet state tracking
https://bugs.webkit.org/show_bug.cgi?id=124465

Reviewed by Sam Weinig.
        
We previously represented the state of watchpoint sets using two booleans. But that
makes it awkward to case over the state.
        
We also previously supported a watchpoint set being both watched and invalidated. We
never used that capability, and its presence was just purely confusing.
        
This turns the whole thing into an enum.

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branch8):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::branch8):
* assembler/MacroAssemblerX86.h:
(JSC::MacroAssemblerX86::branch8):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::branch8):
* bytecode/Watchpoint.cpp:
(JSC::WatchpointSet::WatchpointSet):
(JSC::WatchpointSet::add):
(JSC::WatchpointSet::notifyWriteSlow):
(JSC::InlineWatchpointSet::inflateSlow):
* bytecode/Watchpoint.h:
(JSC::WatchpointSet::state):
(JSC::WatchpointSet::isStillValid):
(JSC::WatchpointSet::startWatching):
(JSC::WatchpointSet::notifyWrite):
(JSC::WatchpointSet::addressOfState):
(JSC::InlineWatchpointSet::InlineWatchpointSet):
(JSC::InlineWatchpointSet::hasBeenInvalidated):
(JSC::InlineWatchpointSet::startWatching):
(JSC::InlineWatchpointSet::notifyWrite):
(JSC::InlineWatchpointSet::decodeState):
(JSC::InlineWatchpointSet::encodeState):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitVarInjectionCheck):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emitVarInjectionCheck):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/JSFunction.cpp:
(JSC::JSFunction::JSFunction):
* runtime/JSFunctionInlines.h:
(JSC::JSFunction::JSFunction):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
* runtime/Structure.cpp:
(JSC::Structure::Structure):
* runtime/SymbolTable.cpp:
(JSC::SymbolTableEntry::attemptToWatch):
* runtime/SymbolTable.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerARMv7h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointh">trunk/Source/JavaScriptCore/bytecode/Watchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctioncpp">trunk/Source/JavaScriptCore/runtime/JSFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctionInlinesh">trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructurecpp">trunk/Source/JavaScriptCore/runtime/Structure.cpp</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 (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -1,5 +1,64 @@
</span><span class="cx"> 2013-11-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Simplify WatchpointSet state tracking
+        https://bugs.webkit.org/show_bug.cgi?id=124465
+
+        Reviewed by Sam Weinig.
+        
+        We previously represented the state of watchpoint sets using two booleans. But that
+        makes it awkward to case over the state.
+        
+        We also previously supported a watchpoint set being both watched and invalidated. We
+        never used that capability, and its presence was just purely confusing.
+        
+        This turns the whole thing into an enum.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::branch8):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::branch8):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::branch8):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::branch8):
+        * bytecode/Watchpoint.cpp:
+        (JSC::WatchpointSet::WatchpointSet):
+        (JSC::WatchpointSet::add):
+        (JSC::WatchpointSet::notifyWriteSlow):
+        (JSC::InlineWatchpointSet::inflateSlow):
+        * bytecode/Watchpoint.h:
+        (JSC::WatchpointSet::state):
+        (JSC::WatchpointSet::isStillValid):
+        (JSC::WatchpointSet::startWatching):
+        (JSC::WatchpointSet::notifyWrite):
+        (JSC::WatchpointSet::addressOfState):
+        (JSC::InlineWatchpointSet::InlineWatchpointSet):
+        (JSC::InlineWatchpointSet::hasBeenInvalidated):
+        (JSC::InlineWatchpointSet::startWatching):
+        (JSC::InlineWatchpointSet::notifyWrite):
+        (JSC::InlineWatchpointSet::decodeState):
+        (JSC::InlineWatchpointSet::encodeState):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitVarInjectionCheck):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitVarInjectionCheck):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::JSFunction):
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::JSFunction):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::JSGlobalObject):
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTableEntry::attemptToWatch):
+        * runtime/SymbolTable.h:
+
+2013-11-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         FTL should have an explicit notion of bytecode liveness
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=124181
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerARM64h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -1638,6 +1638,13 @@
</span><span class="cx">         return branch32(cond, memoryTempRegister, right);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
+    {
+        ASSERT(!(0xffffff00 &amp; right.m_value));
+        load8(left, getCachedMemoryTempRegisterIDAndInvalidate());
+        return branch32(cond, memoryTempRegister, right);
+    }
+    
</ins><span class="cx">     Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.tst&lt;32&gt;(reg, mask);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerARMv7h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -1377,6 +1377,12 @@
</span><span class="cx">         return branch32(cond, addressTempRegister, right);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
+    {
+        load8(left, addressTempRegister);
+        return branch32(cond, addressTempRegister, right);
+    }
+    
</ins><span class="cx">     Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.tst(reg, mask);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -56,6 +56,7 @@
</span><span class="cx">     using MacroAssemblerX86Common::loadDouble;
</span><span class="cx">     using MacroAssemblerX86Common::storeDouble;
</span><span class="cx">     using MacroAssemblerX86Common::convertInt32ToDouble;
</span><ins>+    using MacroAssemblerX86Common::branch8;
</ins><span class="cx">     using MacroAssemblerX86Common::branchTest8;
</span><span class="cx"> 
</span><span class="cx">     void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
</span><span class="lines">@@ -213,6 +214,12 @@
</span><span class="cx">         return DataLabelPtr(this);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
+    {
+        m_assembler.cmpb_im(right.m_value, left.m_ptr);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
</ins><span class="cx">     Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
</span><span class="cx">     {
</span><span class="cx">         ASSERT(mask.m_value &gt;= -128 &amp;&amp; mask.m_value &lt;= 255);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -611,6 +611,13 @@
</span><span class="cx">         return label;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    using MacroAssemblerX86Common::branch8;
+    Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
+    {
+        MacroAssemblerX86Common::move(TrustedImmPtr(left.m_ptr), scratchRegister);
+        return MacroAssemblerX86Common::branch8(cond, Address(scratchRegister), right);
+    }
+    
</ins><span class="cx">     using MacroAssemblerX86Common::branchTest8;
</span><span class="cx">     Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -38,9 +38,8 @@
</span><span class="cx">         remove();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WatchpointSet::WatchpointSet(InitialWatchpointSetMode mode)
-    : m_isWatched(mode == InitializedWatching)
-    , m_isInvalidated(false)
</del><ins>+WatchpointSet::WatchpointSet(WatchpointState state)
+    : m_state(state)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -57,19 +56,19 @@
</span><span class="cx"> void WatchpointSet::add(Watchpoint* watchpoint)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!isCompilationThread());
</span><ins>+    ASSERT(state() != IsInvalidated);
</ins><span class="cx">     if (!watchpoint)
</span><span class="cx">         return;
</span><span class="cx">     m_set.push(watchpoint);
</span><del>-    m_isWatched = true;
</del><ins>+    m_state = IsWatched;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WatchpointSet::notifyWriteSlow()
</span><span class="cx"> {
</span><del>-    ASSERT(m_isWatched);
</del><ins>+    ASSERT(state() == IsWatched);
</ins><span class="cx">     
</span><span class="cx">     fireAllWatchpoints();
</span><del>-    m_isWatched = false;
-    m_isInvalidated = true;
</del><ins>+    m_state = IsInvalidated;
</ins><span class="cx">     WTF::storeStoreFence();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -88,11 +87,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isThin());
</span><span class="cx">     ASSERT(!isCompilationThread());
</span><del>-    WatchpointSet* fat = adoptRef(new WatchpointSet(InitializedBlind)).leakRef();
-    if (m_data &amp; IsInvalidatedFlag)
-        fat-&gt;m_isInvalidated = true;
-    if (m_data &amp; IsWatchedFlag)
-        fat-&gt;m_isWatched = true;
</del><ins>+    WatchpointSet* fat = adoptRef(new WatchpointSet(decodeState(m_data))).leakRef();
</ins><span class="cx">     WTF::storeStoreFence();
</span><span class="cx">     m_data = bitwise_cast&lt;uintptr_t&gt;(fat);
</span><span class="cx">     return fat;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.h (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -45,16 +45,22 @@
</span><span class="cx">     virtual void fireInternal() = 0;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-enum InitialWatchpointSetMode { InitializedWatching, InitializedBlind };
</del><ins>+enum WatchpointState {
+    ClearWatchpoint,
+    IsWatched,
+    IsInvalidated
+};
</ins><span class="cx"> 
</span><span class="cx"> class InlineWatchpointSet;
</span><span class="cx"> 
</span><span class="cx"> class WatchpointSet : public ThreadSafeRefCounted&lt;WatchpointSet&gt; {
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx"> public:
</span><del>-    WatchpointSet(InitialWatchpointSetMode);
</del><ins>+    WatchpointSet(WatchpointState);
</ins><span class="cx">     ~WatchpointSet(); // Note that this will not fire any of the watchpoints; if you need to know when a WatchpointSet dies then you need a separate mechanism for this.
</span><span class="cx">     
</span><ins>+    WatchpointState state() const { return static_cast&lt;WatchpointState&gt;(m_state); }
+    
</ins><span class="cx">     // It is safe to call this from another thread.  It may return true
</span><span class="cx">     // even if the set actually had been invalidated, but that ought to happen
</span><span class="cx">     // only in the case of races, and should be rare. Guarantees that if you
</span><span class="lines">@@ -64,7 +70,7 @@
</span><span class="cx">     bool isStillValid() const
</span><span class="cx">     {
</span><span class="cx">         WTF::loadLoadFence();
</span><del>-        return !m_isInvalidated;
</del><ins>+        return state() != IsInvalidated;
</ins><span class="cx">     }
</span><span class="cx">     // Like isStillValid(), may be called from another thread.
</span><span class="cx">     bool hasBeenInvalidated() const { return !isStillValid(); }
</span><span class="lines">@@ -79,18 +85,21 @@
</span><span class="cx">     // watchpoint would have fired. That's a pretty good indication that you
</span><span class="cx">     // probably don't want to set watchpoints, since we typically don't want to
</span><span class="cx">     // set watchpoints that we believe will actually be fired.
</span><del>-    void startWatching() { m_isWatched = true; }
</del><ins>+    void startWatching()
+    {
+        ASSERT(state() != IsInvalidated);
+        m_state = IsWatched;
+    }
</ins><span class="cx">     
</span><span class="cx">     void notifyWrite()
</span><span class="cx">     {
</span><del>-        if (!m_isWatched)
</del><ins>+        if (state() != IsWatched)
</ins><span class="cx">             return;
</span><span class="cx">         notifyWriteSlow();
</span><span class="cx">     }
</span><ins>+
+    int8_t* addressOfState() { return &amp;m_state; }
</ins><span class="cx">     
</span><del>-    bool* addressOfIsWatched() { return &amp;m_isWatched; }
-    bool* addressOfIsInvalidated() { return &amp;m_isInvalidated; }
-    
</del><span class="cx">     JS_EXPORT_PRIVATE void notifyWriteSlow(); // Call only if you've checked isWatched.
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="lines">@@ -99,8 +108,7 @@
</span><span class="cx">     friend class InlineWatchpointSet;
</span><span class="cx">     
</span><span class="cx">     SentinelLinkedList&lt;Watchpoint, BasicRawSentinelNode&lt;Watchpoint&gt;&gt; m_set;
</span><del>-    bool m_isWatched;
-    bool m_isInvalidated;
</del><ins>+    int8_t m_state;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // InlineWatchpointSet is a low-overhead, non-copyable watchpoint set in which
</span><span class="lines">@@ -125,8 +133,8 @@
</span><span class="cx"> class InlineWatchpointSet {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(InlineWatchpointSet);
</span><span class="cx"> public:
</span><del>-    InlineWatchpointSet(InitialWatchpointSetMode mode)
-        : m_data((mode == InitializedWatching ? IsWatchedFlag : 0) | IsThinFlag)
</del><ins>+    InlineWatchpointSet(WatchpointState state)
+        : m_data(encodeState(state))
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -148,7 +156,7 @@
</span><span class="cx">             WTF::loadLoadFence();
</span><span class="cx">             return fat(data)-&gt;hasBeenInvalidated();
</span><span class="cx">         }
</span><del>-        return data &amp; IsInvalidatedFlag;
</del><ins>+        return decodeState(data) == IsInvalidated;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Like hasBeenInvalidated(), may be called from another thread.
</span><span class="lines">@@ -165,7 +173,8 @@
</span><span class="cx">             fat()-&gt;startWatching();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        m_data |= IsWatchedFlag;
</del><ins>+        ASSERT(decodeState(m_data) != IsInvalidated);
+        m_data = encodeState(IsWatched);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void notifyWrite()
</span><span class="lines">@@ -174,20 +183,31 @@
</span><span class="cx">             fat()-&gt;notifyWrite();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        if (!(m_data &amp; IsWatchedFlag))
</del><ins>+        if (decodeState(m_data) == ClearWatchpoint)
</ins><span class="cx">             return;
</span><del>-        m_data |= IsInvalidatedFlag;
</del><ins>+        m_data = encodeState(IsInvalidated);
</ins><span class="cx">         WTF::storeStoreFence();
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     static const uintptr_t IsThinFlag        = 1;
</span><del>-    static const uintptr_t IsInvalidatedFlag = 2;
-    static const uintptr_t IsWatchedFlag     = 4;
</del><ins>+    static const uintptr_t StateMask         = 6;
+    static const uintptr_t StateShift        = 1;
</ins><span class="cx">     
</span><span class="cx">     static bool isThin(uintptr_t data) { return data &amp; IsThinFlag; }
</span><span class="cx">     static bool isFat(uintptr_t data) { return !isThin(data); }
</span><span class="cx">     
</span><ins>+    static WatchpointState decodeState(uintptr_t data)
+    {
+        ASSERT(isThin(data));
+        return static_cast&lt;WatchpointState&gt;((data &amp; StateMask) &gt;&gt; StateShift);
+    }
+    
+    static uintptr_t encodeState(WatchpointState state)
+    {
+        return (state &lt;&lt; StateShift) | IsThinFlag;
+    }
+    
</ins><span class="cx">     bool isThin() const { return isThin(m_data); }
</span><span class="cx">     bool isFat() const { return isFat(m_data); };
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -637,7 +637,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!needsVarInjectionChecks)
</span><span class="cx">         return;
</span><del>-    addSlowCase(branchTest8(NonZero, AbsoluteAddress(m_codeBlock-&gt;globalObject()-&gt;varInjectionWatchpoint()-&gt;addressOfIsInvalidated())));
</del><ins>+    addSlowCase(branch8(Equal, AbsoluteAddress(m_codeBlock-&gt;globalObject()-&gt;varInjectionWatchpoint()-&gt;addressOfState()), TrustedImm32(IsInvalidated)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT::emitResolveClosure(int dst, bool needsVarInjectionChecks, unsigned depth)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -667,7 +667,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!needsVarInjectionChecks)
</span><span class="cx">         return;
</span><del>-    addSlowCase(branchTest8(NonZero, AbsoluteAddress(m_codeBlock-&gt;globalObject()-&gt;varInjectionWatchpoint()-&gt;addressOfIsInvalidated())));
</del><ins>+    addSlowCase(branch8(Equal, AbsoluteAddress(m_codeBlock-&gt;globalObject()-&gt;varInjectionWatchpoint()-&gt;addressOfState()), TrustedImm32(IsInvalidated)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT::emitResolveClosure(int dst, bool needsVarInjectionChecks, unsigned depth)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -71,6 +71,11 @@
</span><span class="cx"> const LowestTag = DeletedValueTag
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+# Watchpoint states
+const ClearWatchpoint = 0
+const IsWatched = 1
+const IsInvalidated = 2
+
</ins><span class="cx"> # Some register conventions.
</span><span class="cx"> if JSVALUE64
</span><span class="cx">     # - Use a pair of registers to represent the PC: one register for the
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -1987,7 +1987,7 @@
</span><span class="cx">     loadp CodeBlock[cfr], t0
</span><span class="cx">     loadp CodeBlock::m_globalObject[t0], t0
</span><span class="cx">     loadp JSGlobalObject::m_varInjectionWatchpoint[t0], t0
</span><del>-    btbnz WatchpointSet::m_isInvalidated[t0], slowPath
</del><ins>+    bbeq WatchpointSet::m_state[t0], IsInvalidated, slowPath
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro resolveScope()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -1800,7 +1800,7 @@
</span><span class="cx">     loadp CodeBlock[cfr], t0
</span><span class="cx">     loadp CodeBlock::m_globalObject[t0], t0
</span><span class="cx">     loadp JSGlobalObject::m_varInjectionWatchpoint[t0], t0
</span><del>-    btbnz WatchpointSet::m_isInvalidated[t0], slowPath
</del><ins>+    bbeq WatchpointSet::m_state[t0], IsInvalidated, slowPath
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro resolveScope()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunction.cpp (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx">     // was clobbered exactly once, but that seems like overkill. In almost all cases it will be
</span><span class="cx">     // clobbered once, and if it's clobbered more than once, that will probably only occur
</span><span class="cx">     // before we started optimizing, anyway.
</span><del>-    , m_allocationProfileWatchpoint(InitializedBlind)
</del><ins>+    , m_allocationProfileWatchpoint(ClearWatchpoint)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctionInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx">     : Base(vm, scope-&gt;globalObject()-&gt;functionStructure())
</span><span class="cx">     , m_executable(vm, this, executable)
</span><span class="cx">     , m_scope(vm, this, scope)
</span><del>-    , m_allocationProfileWatchpoint(InitializedBlind) // See comment in JSFunction.cpp concerning the reason for using InitializedBlind as opposed to InitializedWatching.
</del><ins>+    , m_allocationProfileWatchpoint(ClearWatchpoint) // See comment in JSFunction.cpp concerning the reason for using ClearWatchpoint as opposed to IsWatched.
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -150,9 +150,9 @@
</span><span class="cx"> 
</span><span class="cx"> JSGlobalObject::JSGlobalObject(VM&amp; vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
</span><span class="cx">     : Base(vm, structure, 0)
</span><del>-    , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
-    , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
-    , m_varInjectionWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
</del><ins>+    , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
+    , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
+    , m_varInjectionWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
</ins><span class="cx">     , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast&lt;unsigned&gt;(randomNumber() * (std::numeric_limits&lt;unsigned&gt;::max() + 1.0)))
</span><span class="cx">     , m_evalEnabled(true)
</span><span class="cx">     , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &amp;s_globalObjectMethodTable)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.cpp (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.cpp        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/runtime/Structure.cpp        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx">     , m_globalObject(vm, this, globalObject, WriteBarrier&lt;JSGlobalObject&gt;::MayBeNull)
</span><span class="cx">     , m_prototype(vm, this, prototype)
</span><span class="cx">     , m_classInfo(classInfo)
</span><del>-    , m_transitionWatchpointSet(InitializedWatching)
</del><ins>+    , m_transitionWatchpointSet(IsWatched)
</ins><span class="cx">     , m_offset(invalidOffset)
</span><span class="cx">     , m_typeInfo(typeInfo)
</span><span class="cx">     , m_indexingType(indexingType)
</span><span class="lines">@@ -185,7 +185,7 @@
</span><span class="cx">     : JSCell(CreatingEarlyCell)
</span><span class="cx">     , m_prototype(vm, this, jsNull())
</span><span class="cx">     , m_classInfo(info())
</span><del>-    , m_transitionWatchpointSet(InitializedWatching)
</del><ins>+    , m_transitionWatchpointSet(IsWatched)
</ins><span class="cx">     , m_offset(invalidOffset)
</span><span class="cx">     , m_typeInfo(CompoundType, OverridesVisitChildren)
</span><span class="cx">     , m_indexingType(0)
</span><span class="lines">@@ -207,7 +207,7 @@
</span><span class="cx">     : JSCell(vm, vm.structureStructure.get())
</span><span class="cx">     , m_prototype(vm, this, previous-&gt;storedPrototype())
</span><span class="cx">     , m_classInfo(previous-&gt;m_classInfo)
</span><del>-    , m_transitionWatchpointSet(InitializedWatching)
</del><ins>+    , m_transitionWatchpointSet(IsWatched)
</ins><span class="cx">     , m_offset(invalidOffset)
</span><span class="cx">     , m_typeInfo(previous-&gt;typeInfo().type(), previous-&gt;typeInfo().flags() &amp; ~StructureHasRareData)
</span><span class="cx">     , m_indexingType(previous-&gt;indexingTypeIncludingHistory())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -72,15 +72,9 @@
</span><span class="cx"> {
</span><span class="cx">     FatEntry* entry = inflate();
</span><span class="cx">     if (!entry-&gt;m_watchpoints)
</span><del>-        entry-&gt;m_watchpoints = adoptRef(new WatchpointSet(InitializedWatching));
</del><ins>+        entry-&gt;m_watchpoints = adoptRef(new WatchpointSet(IsWatched));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool* SymbolTableEntry::addressOfIsWatched()
-{
-    ASSERT(couldBeWatched());
-    return fatEntry()-&gt;m_watchpoints-&gt;addressOfIsWatched();
-}
-
</del><span class="cx"> void SymbolTableEntry::addWatchpoint(Watchpoint* watchpoint)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(couldBeWatched());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (159394 => 159395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2013-11-18 01:46:48 UTC (rev 159394)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2013-11-18 02:10:42 UTC (rev 159395)
</span><span class="lines">@@ -230,8 +230,6 @@
</span><span class="cx">     // immediately after a call to attemptToWatch().
</span><span class="cx">     void attemptToWatch();
</span><span class="cx">     
</span><del>-    bool* addressOfIsWatched();
-    
</del><span class="cx">     void addWatchpoint(Watchpoint*);
</span><span class="cx">     
</span><span class="cx">     WatchpointSet* watchpointSet()
</span></span></pre>
</div>
</div>

</body>
</html>