<!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>[283098] 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/283098">283098</a></dd>
<dt>Author</dt> <dd>ysuzuki@apple.com</dd>
<dt>Date</dt> <dd>2021-09-26 22:02:37 -0700 (Sun, 26 Sep 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] Optimize PutByVal with for-in
https://bugs.webkit.org/show_bug.cgi?id=230801

Reviewed by Saam Barati.

JSTests:

* stress/for-in-sentinel.js: Added.
(shouldBe):
(test):

Source/JavaScriptCore:

We found that some of Speedometer2 subtests are heavily using for-in with PutByVal or the other DFG nodes.
And we also found that we are using polluted non-good type for the property names from for-in: String | Other.
The reason is that we are returning null when op_enumerator_next finishes instead of string. And this design
forces DFG and FTL to return null from EnumeratorNextUpdatePropertyName at the end of iteration. This pollutes
the type of property names as String | Other instead of String, and leading to suboptimal DFG nodes.

In this patch, we add special sentinel string in vm.smallString.sentinelString(). We know that this string cell
pointer will be never returned from EnumeratorNextUpdatePropertyName in the normal for-in iteration. This is easy
since we are always allocating a JSString when creating JSPropertyNameEnumerator. So this string cell (not the content)
is always different from pre-allocated vm.smallString.sentinelString(). So, we use this special string pointer
as a sentinel instead of null so that we can avoid polluting return type of EnumeratorNextUpdatePropertyName.

To check the sentinel in LLInt / Baseline, this patch adds jeq_ptr, which performs cell pointer comparison and do
not check string content equality. We do not need to have an implementation in DFG since we already have CompareEqPtr
for existing jneq_ptr bytecode.

We also clean up DFG operation related to PutByVal.

----------------------------------------------------------------------------------------------------------------------------------
|               subtest                |     ms      |     ms      |  b / a   | pValue (significance using False Discovery Rate) |
----------------------------------------------------------------------------------------------------------------------------------
| Elm-TodoMVC                          |116.010000   |112.701667   |0.971482  | 0.000000 (significant)                           |
| VueJS-TodoMVC                        |22.995000    |23.023333    |1.001232  | 0.907086                                         |
| EmberJS-TodoMVC                      |125.498333   |125.525000   |1.000212  | 0.932546                                         |
| BackboneJS-TodoMVC                   |45.700000    |45.975000    |1.006018  | 0.084799                                         |
| Preact-TodoMVC                       |16.681667    |16.610000    |0.995704  | 0.722758                                         |
| AngularJS-TodoMVC                    |123.753333   |123.740000   |0.999892  | 0.971431                                         |
| Vanilla-ES2015-TodoMVC               |61.255000    |61.380000    |1.002041  | 0.300654                                         |
| Inferno-TodoMVC                      |58.646667    |58.948333    |1.005144  | 0.267611                                         |
| Flight-TodoMVC                       |73.283333    |72.801667    |0.993427  | 0.207389                                         |
| Angular2-TypeScript-TodoMVC          |39.746667    |40.015000    |1.006751  | 0.449821                                         |
| VanillaJS-TodoMVC                    |50.096667    |49.823333    |0.994544  | 0.162020                                         |
| jQuery-TodoMVC                       |212.870000   |213.196667   |1.001535  | 0.371944                                         |
| EmberJS-Debug-TodoMVC                |331.878333   |332.710000   |1.002506  | 0.094499                                         |
| React-TodoMVC                        |83.078333    |82.726667    |0.995767  | 0.076143                                         |
| React-Redux-TodoMVC                  |136.018333   |133.935000   |0.984683  | 0.000000 (significant)                           |
| Vanilla-ES2015-Babel-Webpack-TodoMVC |59.743333    |59.643333    |0.998326  | 0.393671                                         |
----------------------------------------------------------------------------------------------------------------------------------
a mean = 271.75873
b mean = 272.45804
pValue = 0.0263030803
(Bigger means are better.)
1.003 times better
Results ARE significant

* builtins/BuiltinNames.h:
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecode/LinkTimeConstant.h:
* bytecode/Opcode.h:
(JSC::isBranch):
* bytecode/PreciseJumpTargetsInlines.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::GenericLabel<JSGeneratorTraits>::setLocation):
(JSC::BytecodeGenerator::emitJumpIfSentinelString):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ForInNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGOperations.cpp:
(JSC::DFG::putByVal):
(JSC::DFG::putByValInternal):
(JSC::DFG::putByValCellInternal):
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdatePropertyName):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_jeq_ptr):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_jeq_ptr):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_enumerator_next):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/SmallStrings.cpp:
(JSC::SmallStrings::initializeCommonStrings):
(JSC::SmallStrings::visitStrongReferences):
* runtime/SmallStrings.h:
(JSC::SmallStrings::sentinelString const):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsBuiltinNamesh">trunk/Source/JavaScriptCore/builtins/BuiltinNames.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListrb">trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefcpp">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeLinkTimeConstanth">trunk/Source/JavaScriptCore/bytecode/LinkTimeConstant.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeOpcodeh">trunk/Source/JavaScriptCore/bytecode/Opcode.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePreciseJumpTargetsInlinesh">trunk/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</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="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSmallStringscpp">trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSmallStringsh">trunk/Source/JavaScriptCore/runtime/SmallStrings.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressforinsentineljs">trunk/JSTests/stress/for-in-sentinel.js</a></li>
<li><a href="#trunkJSTestsstressforinsentinel2js">trunk/JSTests/stress/for-in-sentinel2.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog  2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/JSTests/ChangeLog     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2021-09-26  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Optimize PutByVal with for-in
+        https://bugs.webkit.org/show_bug.cgi?id=230801
+
+        Reviewed by Saam Barati.
+
+        * stress/for-in-sentinel.js: Added.
+        (shouldBe):
+        (test):
+
</ins><span class="cx"> 2021-09-26  Commit Queue  <commit-queue@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, reverting r283095.
</span></span></pre></div>
<a id="trunkJSTestsstressforinsentineljs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/for-in-sentinel.js (0 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/for-in-sentinel.js                          (rev 0)
+++ trunk/JSTests/stress/for-in-sentinel.js     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var object = {
+    $: 32,
+    test: 33,
+    hey: 34,
+};
+
+function test(object) {
+    var count = 0;
+    for (var i in object) {
+        ++count;
+    }
+    return count;
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+    shouldBe(test(object), 3);
</ins></span></pre></div>
<a id="trunkJSTestsstressforinsentinel2js"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/for-in-sentinel2.js (0 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/for-in-sentinel2.js                         (rev 0)
+++ trunk/JSTests/stress/for-in-sentinel2.js    2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var object = {
+    $: 32,
+    test: 33,
+    hey: 34,
+};
+
+function test(object) {
+    var string = '$';
+    var count = 0;
+    for (var i in object) {
+        ++count;
+    }
+    for (var i in object) {
+        ++count;
+    }
+    return count + string;
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+    shouldBe(test(object), `6$`);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/ChangeLog       2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -1,3 +1,108 @@
</span><ins>+2021-09-26  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Optimize PutByVal with for-in
+        https://bugs.webkit.org/show_bug.cgi?id=230801
+
+        Reviewed by Saam Barati.
+
+        We found that some of Speedometer2 subtests are heavily using for-in with PutByVal or the other DFG nodes.
+        And we also found that we are using polluted non-good type for the property names from for-in: String | Other.
+        The reason is that we are returning null when op_enumerator_next finishes instead of string. And this design
+        forces DFG and FTL to return null from EnumeratorNextUpdatePropertyName at the end of iteration. This pollutes
+        the type of property names as String | Other instead of String, and leading to suboptimal DFG nodes.
+
+        In this patch, we add special sentinel string in vm.smallString.sentinelString(). We know that this string cell
+        pointer will be never returned from EnumeratorNextUpdatePropertyName in the normal for-in iteration. This is easy
+        since we are always allocating a JSString when creating JSPropertyNameEnumerator. So this string cell (not the content)
+        is always different from pre-allocated vm.smallString.sentinelString(). So, we use this special string pointer
+        as a sentinel instead of null so that we can avoid polluting return type of EnumeratorNextUpdatePropertyName.
+
+        To check the sentinel in LLInt / Baseline, this patch adds jeq_ptr, which performs cell pointer comparison and do
+        not check string content equality. We do not need to have an implementation in DFG since we already have CompareEqPtr
+        for existing jneq_ptr bytecode.
+
+        We also clean up DFG operation related to PutByVal.
+
+        ----------------------------------------------------------------------------------------------------------------------------------
+        |               subtest                |     ms      |     ms      |  b / a   | pValue (significance using False Discovery Rate) |
+        ----------------------------------------------------------------------------------------------------------------------------------
+        | Elm-TodoMVC                          |116.010000   |112.701667   |0.971482  | 0.000000 (significant)                           |
+        | VueJS-TodoMVC                        |22.995000    |23.023333    |1.001232  | 0.907086                                         |
+        | EmberJS-TodoMVC                      |125.498333   |125.525000   |1.000212  | 0.932546                                         |
+        | BackboneJS-TodoMVC                   |45.700000    |45.975000    |1.006018  | 0.084799                                         |
+        | Preact-TodoMVC                       |16.681667    |16.610000    |0.995704  | 0.722758                                         |
+        | AngularJS-TodoMVC                    |123.753333   |123.740000   |0.999892  | 0.971431                                         |
+        | Vanilla-ES2015-TodoMVC               |61.255000    |61.380000    |1.002041  | 0.300654                                         |
+        | Inferno-TodoMVC                      |58.646667    |58.948333    |1.005144  | 0.267611                                         |
+        | Flight-TodoMVC                       |73.283333    |72.801667    |0.993427  | 0.207389                                         |
+        | Angular2-TypeScript-TodoMVC          |39.746667    |40.015000    |1.006751  | 0.449821                                         |
+        | VanillaJS-TodoMVC                    |50.096667    |49.823333    |0.994544  | 0.162020                                         |
+        | jQuery-TodoMVC                       |212.870000   |213.196667   |1.001535  | 0.371944                                         |
+        | EmberJS-Debug-TodoMVC                |331.878333   |332.710000   |1.002506  | 0.094499                                         |
+        | React-TodoMVC                        |83.078333    |82.726667    |0.995767  | 0.076143                                         |
+        | React-Redux-TodoMVC                  |136.018333   |133.935000   |0.984683  | 0.000000 (significant)                           |
+        | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.743333    |59.643333    |0.998326  | 0.393671                                         |
+        ----------------------------------------------------------------------------------------------------------------------------------
+        a mean = 271.75873
+        b mean = 272.45804
+        pValue = 0.0263030803
+        (Bigger means are better.)
+        1.003 times better
+        Results ARE significant
+
+        * builtins/BuiltinNames.h:
+        * bytecode/BytecodeList.rb:
+        * bytecode/BytecodeUseDef.cpp:
+        (JSC::computeUsesForBytecodeIndexImpl):
+        (JSC::computeDefsForBytecodeIndexImpl):
+        * bytecode/LinkTimeConstant.h:
+        * bytecode/Opcode.h:
+        (JSC::isBranch):
+        * bytecode/PreciseJumpTargetsInlines.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::GenericLabel<JSGeneratorTraits>::setLocation):
+        (JSC::BytecodeGenerator::emitJumpIfSentinelString):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitBytecode):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::putByVal):
+        (JSC::DFG::putByValInternal):
+        (JSC::DFG::putByValCellInternal):
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdatePropertyName):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_jeq_ptr):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_jeq_ptr):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_enumerator_next):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::JSC_DEFINE_COMMON_SLOW_PATH):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStrings::initializeCommonStrings):
+        (JSC::SmallStrings::visitStrongReferences):
+        * runtime/SmallStrings.h:
+        (JSC::SmallStrings::sentinelString const):
+
</ins><span class="cx"> 2021-09-26  Commit Queue  <commit-queue@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, reverting r283095.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsBuiltinNamesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/BuiltinNames.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/BuiltinNames.h      2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/builtins/BuiltinNames.h 2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -182,7 +182,8 @@
</span><span class="cx">     macro(createPrivateSymbol) \
</span><span class="cx">     macro(entries) \
</span><span class="cx">     macro(outOfLineReactionCounts) \
</span><del>-    macro(emptyPropertyNameEnumerator)
</del><ins>+    macro(emptyPropertyNameEnumerator) \
+    macro(sentinelString) \
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> namespace Symbols {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb     2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb        2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -762,6 +762,13 @@
</span><span class="cx">         targetLabel: BoundLabel,
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+op :jeq_ptr,
+    args: {
+        value: VirtualRegister,
+        specialPointer: VirtualRegister,
+        targetLabel: BoundLabel,
+    }
+
</ins><span class="cx"> op :jneq_ptr,
</span><span class="cx">     args: {
</span><span class="cx">         value: VirtualRegister,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp  2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -80,7 +80,6 @@
</span><span class="cx">     // No uses.
</span><span class="cx">     case op_new_regexp:
</span><span class="cx">     case op_debug:
</span><del>-    case op_jneq_ptr:
</del><span class="cx">     case op_loop_hint:
</span><span class="cx">     case op_jmp:
</span><span class="cx">     case op_new_object:
</span><span class="lines">@@ -135,6 +134,9 @@
</span><span class="cx">     USES(OpJnstricteq, lhs, rhs)
</span><span class="cx">     USES(OpJbelow, lhs, rhs)
</span><span class="cx">     USES(OpJbeloweq, lhs, rhs)
</span><ins>+    USES(OpJeqPtr, value, specialPointer)
+    USES(OpJneqPtr, value, specialPointer)
+
</ins><span class="cx">     USES(OpSetFunctionName, function, name)
</span><span class="cx">     USES(OpLogShadowChickenTail, thisValue, scope)
</span><span class="cx"> 
</span><span class="lines">@@ -365,6 +367,7 @@
</span><span class="cx">     case op_jneq_null:
</span><span class="cx">     case op_jundefined_or_null:
</span><span class="cx">     case op_jnundefined_or_null:
</span><ins>+    case op_jeq_ptr:
</ins><span class="cx">     case op_jneq_ptr:
</span><span class="cx">     case op_jless:
</span><span class="cx">     case op_jlesseq:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeLinkTimeConstanth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/LinkTimeConstant.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/LinkTimeConstant.h  2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecode/LinkTimeConstant.h     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -112,6 +112,7 @@
</span><span class="cx">     v(hasOwnPropertyFunction, nullptr) \
</span><span class="cx">     v(createPrivateSymbol, nullptr) \
</span><span class="cx">     v(emptyPropertyNameEnumerator, nullptr) \
</span><ins>+    v(sentinelString, nullptr) \
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> #define DECLARE_LINK_TIME_CONSTANT(name, code) name,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeOpcodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Opcode.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Opcode.h    2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecode/Opcode.h       2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -199,6 +199,7 @@
</span><span class="cx">     case op_jneq_null:
</span><span class="cx">     case op_jundefined_or_null:
</span><span class="cx">     case op_jnundefined_or_null:
</span><ins>+    case op_jeq_ptr:
</ins><span class="cx">     case op_jneq_ptr:
</span><span class="cx">     case op_jless:
</span><span class="cx">     case op_jlesseq:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePreciseJumpTargetsInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h 2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h    2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     CASE_OP(OpJneqNull) \
</span><span class="cx">     CASE_OP(OpJundefinedOrNull) \
</span><span class="cx">     CASE_OP(OpJnundefinedOrNull) \
</span><ins>+    CASE_OP(OpJeqPtr) \
</ins><span class="cx">     CASE_OP(OpJneqPtr) \
</span><span class="cx">     \
</span><span class="cx">     CASE_OP(OpJless) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp   2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp      2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -105,6 +105,7 @@
</span><span class="cx">         CASE(OpJeq)
</span><span class="cx">         CASE(OpJstricteq)
</span><span class="cx">         CASE(OpJneq)
</span><ins>+        CASE(OpJeqPtr)
</ins><span class="cx">         CASE(OpJneqPtr)
</span><span class="cx">         CASE(OpJnstricteq)
</span><span class="cx">         CASE(OpJless)
</span><span class="lines">@@ -1497,6 +1498,11 @@
</span><span class="cx">     OpJneqPtr::emit(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::applyFunction), target.bind(this));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BytecodeGenerator::emitJumpIfSentinelString(RegisterID* cond, Label& target)
+{
+    OpJeqPtr::emit(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::sentinelString), target.bind(this));
+}
+
</ins><span class="cx"> unsigned BytecodeGenerator::emitWideJumpIfNotFunctionHasOwnProperty(RegisterID* cond, Label& target)
</span><span class="cx"> {
</span><span class="cx">     OpJneqPtr::emit<OpcodeSize::Wide32>(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::hasOwnPropertyFunction), target.bind(this));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h     2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -858,6 +858,7 @@
</span><span class="cx">         void emitJumpIfFalse(RegisterID* cond, Label& target);
</span><span class="cx">         void emitJumpIfNotFunctionCall(RegisterID* cond, Label& target);
</span><span class="cx">         void emitJumpIfNotFunctionApply(RegisterID* cond, Label& target);
</span><ins>+        void emitJumpIfSentinelString(RegisterID* cond, Label& target);
</ins><span class="cx">         unsigned emitWideJumpIfNotFunctionHasOwnProperty(RegisterID* cond, Label& target);
</span><span class="cx">         void recordHasOwnPropertyInForInLoop(ForInContext&, unsigned branchOffset, Label& genericPath);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp   2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -4227,10 +4227,8 @@
</span><span class="cx"> 
</span><span class="cx">         // FIXME: We should have a way to see if anyone is actually using the propertyName for something other than a get_by_val. If not, we could eliminate the toString in this opcode.
</span><span class="cx">         generator.emitEnumeratorNext(propertyName.get(), mode.get(), index.get(), base.get(), enumerator.get());
</span><ins>+        generator.emitJumpIfSentinelString(propertyName.get(), scope->breakTarget());
</ins><span class="cx"> 
</span><del>-        // Note, choosing undefined or null helps please DFG's Abstract Interpreter as it doesn't distinguish null and undefined as types (via SpecOther).
-        generator.emitJumpIfTrue(generator.emitIsUndefinedOrNull(generator.newTemporary(), propertyName.get()), scope->breakTarget());
-
</del><span class="cx">         this->emitLoopHeader(generator, propertyName.get());
</span><span class="cx"> 
</span><span class="cx">         generator.emitProfileControlFlow(profilerStartOffset);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h  2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -4323,7 +4323,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case EnumeratorNextUpdatePropertyName: {
</span><del>-        setTypeForNode(node, SpecString | SpecOther);
</del><ins>+        setTypeForNode(node, SpecStringIdent);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp    2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp       2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -7632,6 +7632,18 @@
</span><span class="cx">             NEXT_OPCODE(op_iterator_next);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case op_jeq_ptr: {
+            auto bytecode = currentInstruction->as<OpJeqPtr>();
+            JSValue constant = m_inlineStackTop->m_codeBlock->getConstant(bytecode.m_specialPointer);
+            FrozenValue* frozenPointer = m_graph.freezeStrong(constant);
+            ASSERT(frozenPointer->cell() == constant);
+            unsigned relativeOffset = jumpTarget(bytecode.m_targetLabel);
+            Node* child = get(bytecode.m_value);
+            Node* condition = addToGraph(CompareEqPtr, OpInfo(frozenPointer), child);
+            addToGraph(Branch, OpInfo(branchData(m_currentIndex.offset() + relativeOffset, m_currentIndex.offset() + currentInstruction->size())), condition);
+            LAST_OPCODE(op_jeq_ptr);
+        }
+
</ins><span class="cx">         case op_jneq_ptr: {
</span><span class="cx">             auto bytecode = currentInstruction->as<OpJneqPtr>();
</span><span class="cx">             FrozenValue* frozenPointer = m_graph.freezeStrong(m_inlineStackTop->m_codeBlock->getConstant(bytecode.m_specialPointer));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp      2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp 2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -240,6 +240,7 @@
</span><span class="cx">     case op_get_from_arguments:
</span><span class="cx">     case op_put_to_arguments:
</span><span class="cx">     case op_get_argument:
</span><ins>+    case op_jeq_ptr:
</ins><span class="cx">     case op_jneq_ptr:
</span><span class="cx">     case op_typeof:
</span><span class="cx">     case op_to_number:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp   2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -86,10 +86,10 @@
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><span class="cx"> template<bool strict, bool direct>
</span><del>-static inline void putByVal(JSGlobalObject* globalObject, VM& vm, JSValue baseValue, uint32_t index, JSValue value)
</del><ins>+static ALWAYS_INLINE void putByVal(JSGlobalObject* globalObject, VM& vm, JSValue baseValue, uint32_t index, JSValue value)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isIndex(index));
</span><del>-    if (direct) {
</del><ins>+    if constexpr (direct) {
</ins><span class="cx">         RELEASE_ASSERT(baseValue.isObject());
</span><span class="cx">         asObject(baseValue)->putDirectIndex(globalObject, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
</span><span class="cx">         return;
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, void());
</span><span class="cx"> 
</span><span class="cx">     PutPropertySlot slot(baseValue, strict);
</span><del>-    if (direct) {
</del><ins>+    if constexpr (direct) {
</ins><span class="cx">         RELEASE_ASSERT(baseValue.isObject());
</span><span class="cx">         JSObject* baseObject = asObject(baseValue);
</span><span class="cx">         if (std::optional<uint32_t> index = parseIndex(propertyName)) {
</span><span class="lines">@@ -148,7 +148,7 @@
</span><span class="cx"> ALWAYS_INLINE static void putByValCellInternal(JSGlobalObject* globalObject, VM& vm, JSCell* base, PropertyName propertyName, JSValue value)
</span><span class="cx"> {
</span><span class="cx">     PutPropertySlot slot(base, strict);
</span><del>-    if (direct) {
</del><ins>+    if constexpr (direct) {
</ins><span class="cx">         RELEASE_ASSERT(base->isObject());
</span><span class="cx">         JSObject* baseObject = asObject(base);
</span><span class="cx">         if (std::optional<uint32_t> index = parseIndex(propertyName)) {
</span><span class="lines">@@ -2486,7 +2486,7 @@
</span><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSC_DEFINE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, EncodedJSValue, (JSGlobalObject* globalObject, uint32_t index, int32_t modeNumber, JSPropertyNameEnumerator* enumerator))
</del><ins>+JSC_DEFINE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, JSString*, (JSGlobalObject* globalObject, uint32_t index, int32_t modeNumber, JSPropertyNameEnumerator* enumerator))
</ins><span class="cx"> {
</span><span class="cx">     VM& vm = globalObject->vm();
</span><span class="cx">     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
</span><span class="lines">@@ -2494,15 +2494,15 @@
</span><span class="cx"> 
</span><span class="cx">     if (modeNumber == JSPropertyNameEnumerator::IndexedMode) {
</span><span class="cx">         if (index < enumerator->indexedLength())
</span><del>-            return JSValue::encode(jsString(vm, Identifier::from(vm, index).string()));
-        return JSValue::encode(jsNull());
</del><ins>+            return jsString(vm, Identifier::from(vm, index).string());
+        return vm.smallStrings.sentinelString();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JSString* result = enumerator->propertyNameAtIndex(index);
</span><span class="cx">     if (!result)
</span><del>-        return JSValue::encode(jsNull());
</del><ins>+        return vm.smallStrings.sentinelString();
</ins><span class="cx"> 
</span><del>-    return JSValue::encode(result);
</del><ins>+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC_DEFINE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, uint32_t index, JSPropertyNameEnumerator* enumerator))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h  2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationGetPropertyEnumerator, JSCell*, (JSGlobalObject*, EncodedJSValue));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationGetPropertyEnumeratorCell, JSCell*, (JSGlobalObject*, JSCell*));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdateIndexAndMode, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, uint32_t, int32_t, JSPropertyNameEnumerator*));
</span><del>-JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, EncodedJSValue, (JSGlobalObject*, uint32_t, int32_t, JSPropertyNameEnumerator*));
</del><ins>+JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, JSString*, (JSGlobalObject*, uint32_t, int32_t, JSPropertyNameEnumerator*));
</ins><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationEnumeratorInByVal, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationEnumeratorHasOwnProperty, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject*, JSCell*, uint32_t, JSPropertyNameEnumerator*));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp   2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -1233,7 +1233,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case EnumeratorNextUpdatePropertyName: {
</span><del>-            setPrediction(SpecString | SpecOther);
</del><ins>+            setPrediction(SpecStringIdent);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp    2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp       2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -13646,12 +13646,12 @@
</span><span class="cx">     SpeculateStrictInt32Operand indexOperand(this, node->child1());
</span><span class="cx">     SpeculateStrictInt32Operand modeOperand(this, node->child2());
</span><span class="cx">     SpeculateCellOperand enumeratorOperand(this, node->child3());
</span><del>-    JSValueRegsTemporary resultTemp(this);
</del><ins>+    GPRTemporary result(this);
</ins><span class="cx"> 
</span><span class="cx">     GPRReg index = indexOperand.gpr();
</span><span class="cx">     GPRReg mode = modeOperand.gpr();
</span><span class="cx">     GPRReg enumerator = enumeratorOperand.gpr();
</span><del>-    JSValueRegs resultRegs = resultTemp.regs();
</del><ins>+    GPRReg resultGPR = result.gpr();
</ins><span class="cx"> 
</span><span class="cx">     OptionSet seenModes = node->enumeratorMetadata();
</span><span class="cx"> 
</span><span class="lines">@@ -13667,24 +13667,21 @@
</span><span class="cx"> 
</span><span class="cx">         auto outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, index, MacroAssembler::Address(enumerator, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
</span><span class="cx"> 
</span><del>-        m_jit.loadPtr(MacroAssembler::Address(enumerator, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), resultRegs.payloadGPR());
-        m_jit.loadPtr(MacroAssembler::BaseIndex(resultRegs.payloadGPR(), index, MacroAssembler::ScalePtr), resultRegs.payloadGPR());
-#if USE(JSVALUE32_64)
-        m_jit.move(TrustedImm32(JSValue::CellTag), resultRegs.tagGPR());
-#endif
</del><ins>+        m_jit.loadPtr(MacroAssembler::Address(enumerator, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), resultGPR);
+        m_jit.loadPtr(MacroAssembler::BaseIndex(resultGPR, index, MacroAssembler::ScalePtr), resultGPR);
</ins><span class="cx">         doneCases.append(m_jit.jump());
</span><span class="cx"> 
</span><span class="cx">         outOfBounds.link(&m_jit);
</span><del>-        m_jit.moveTrustedValue(jsNull(), resultRegs);
</del><ins>+        m_jit.move(TrustedImmPtr::weakPointer(m_graph, vm().smallStrings.sentinelString()), resultGPR);
</ins><span class="cx">         doneCases.append(m_jit.jump());
</span><span class="cx">         operationCall.link(&m_jit);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    callOperation(operationEnumeratorNextUpdatePropertyName, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), index, mode, enumerator);
</del><ins>+    callOperation(operationEnumeratorNextUpdatePropertyName, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), index, mode, enumerator);
</ins><span class="cx">     m_jit.exceptionCheck();
</span><span class="cx"> 
</span><span class="cx">     doneCases.link(&m_jit);
</span><del>-    jsValueResult(resultRegs, node);
</del><ins>+    cellResult(resultGPR, node);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template<typename SlowPathFunctionType>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp      2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp 2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -13526,7 +13526,7 @@
</span><span class="cx"> 
</span><span class="cx">             {
</span><span class="cx">                 m_out.appendTo(outOfBoundsBlock);
</span><del>-                results.append(m_out.anchor(m_out.constInt64(JSValue::encode(jsNull()))));
</del><ins>+                results.append(m_out.anchor(weakPointer(vm().smallStrings.sentinelString())));
</ins><span class="cx">                 m_out.jump(continuation);
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -13533,7 +13533,7 @@
</span><span class="cx">             {
</span><span class="cx">                 m_out.appendTo(loadPropertyNameBlock);
</span><span class="cx">                 LValue namesVector = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
</span><del>-                results.append(m_out.anchor(m_out.zeroExtPtr(m_out.loadPtr(m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents.atAnyIndex(), namesVector, m_out.zeroExt(index, Int64), ScalePtr)))));
</del><ins>+                results.append(m_out.anchor(m_out.loadPtr(m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents.atAnyIndex(), namesVector, m_out.zeroExt(index, Int64), ScalePtr))));
</ins><span class="cx">                 m_out.jump(continuation);
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -13541,7 +13541,7 @@
</span><span class="cx">         if (operationBlock)
</span><span class="cx">             m_out.appendTo(operationBlock);
</span><span class="cx">         // Note: We can't omit the operation because we have no guarantee that the mode will match what we profiled.
</span><del>-        results.append(m_out.anchor(vmCall(Int64, operationEnumeratorNextUpdatePropertyName, weakPointer(globalObject), index, mode, enumerator)));
</del><ins>+        results.append(m_out.anchor(vmCall(pointerType(), operationEnumeratorNextUpdatePropertyName, weakPointer(globalObject), index, mode, enumerator)));
</ins><span class="cx">         if (continuation) {
</span><span class="cx">             m_out.jump(continuation);
</span><span class="cx">             m_out.appendTo(continuation);
</span><span class="lines">@@ -13548,7 +13548,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         ASSERT(results.size());
</span><del>-        LValue result = m_out.phi(Int64, results);
</del><ins>+        LValue result = m_out.phi(pointerType(), results);
</ins><span class="cx">         setJSValue(result);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp  2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -387,6 +387,7 @@
</span><span class="cx">         DEFINE_OP(op_jneq_null)
</span><span class="cx">         DEFINE_OP(op_jundefined_or_null)
</span><span class="cx">         DEFINE_OP(op_jnundefined_or_null)
</span><ins>+        DEFINE_OP(op_jeq_ptr)
</ins><span class="cx">         DEFINE_OP(op_jneq_ptr)
</span><span class="cx">         DEFINE_OP(op_jless)
</span><span class="cx">         DEFINE_OP(op_jlesseq)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h    2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/jit/JIT.h       2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -461,6 +461,7 @@
</span><span class="cx">         void emit_op_jneq_null(const Instruction*);
</span><span class="cx">         void emit_op_jundefined_or_null(const Instruction*);
</span><span class="cx">         void emit_op_jnundefined_or_null(const Instruction*);
</span><ins>+        void emit_op_jeq_ptr(const Instruction*);
</ins><span class="cx">         void emit_op_jneq_ptr(const Instruction*);
</span><span class="cx">         void emit_op_jless(const Instruction*);
</span><span class="cx">         void emit_op_jlesseq(const Instruction*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp   2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp      2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -579,6 +579,18 @@
</span><span class="cx">     addJump(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsNull()))), target);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_jeq_ptr(const Instruction* currentInstruction)
+{
+    auto bytecode = currentInstruction->as<OpJeqPtr>();
+    VirtualRegister src = bytecode.m_value;
+    JSValue specialPointer = getConstantOperand(bytecode.m_specialPointer);
+    ASSERT(specialPointer.isCell());
+    unsigned target = jumpTarget(currentInstruction, bytecode.m_targetLabel);
+
+    emitGetVirtualRegister(src, regT0);
+    addJump(branchPtr(Equal, regT0, TrustedImmPtr(specialPointer.asCell())), target);
+}
+
</ins><span class="cx"> void JIT::emit_op_jneq_ptr(const Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     auto bytecode = currentInstruction->as<OpJneqPtr>();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp      2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp 2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -501,6 +501,21 @@
</span><span class="cx">     addJump(branchIfNotNull(regT0), target);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_jeq_ptr(const Instruction* currentInstruction)
+{
+    auto bytecode = currentInstruction->as<OpJeqPtr>();
+    auto& metadata = bytecode.metadata(m_profiledCodeBlock);
+    VirtualRegister src = bytecode.m_value;
+    JSValue specialPointer = getConstantOperand(bytecode.m_specialPointer);
+    ASSERT(specialPointer.isCell());
+    unsigned target = jumpTarget(currentInstruction, bytecode.m_targetLabel);
+
+    emitLoad(src, regT1, regT0);
+    Jump notCell = branchIfNotCell(regT1);
+    addJump(branchPtr(Equal, regT0, TrustedImmPtr(specialPointer.asCell())), target);
+    notCell.link(this);
+}
+
</ins><span class="cx"> void JIT::emit_op_jneq_ptr(const Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     auto bytecode = currentInstruction->as<OpJneqPtr>();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp    2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp       2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -2866,7 +2866,7 @@
</span><span class="cx">         done.append(jump());
</span><span class="cx"> 
</span><span class="cx">         outOfBounds.link(this);
</span><del>-        storeTrustedValue(jsNull(), addressFor(propertyName));
</del><ins>+        storeTrustedValue(vm().smallStrings.sentinelString(), addressFor(propertyName));
</ins><span class="cx">         done.append(jump());
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm   2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm      2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -1944,6 +1944,20 @@
</span><span class="cx"> undefinedOrNullJumpOp(jnundefined_or_null, OpJnundefinedOrNull,
</span><span class="cx">     macro (value, target) bineq value, NullTag, target end)
</span><span class="cx"> 
</span><ins>+llintOpWithReturn(op_jeq_ptr, OpJeqPtr, macro (size, get, dispatch, return)
+    get(m_value, t0)
+    get(m_specialPointer, t1)
+    loadConstant(size, t1, t3, t2)
+    bineq TagOffset[cfr, t0, 8], CellTag, .opJeqPtrFallThrough
+    bpneq PayloadOffset[cfr, t0, 8], t2, .opJeqPtrFallThrough
+.opJeqPtrBranch:
+    get(m_targetLabel, t0)
+    jumpImpl(dispatchIndirect, t0)
+.opJeqPtrFallThrough:
+    dispatch()
+end)
+
+
</ins><span class="cx"> llintOpWithMetadata(op_jneq_ptr, OpJneqPtr, macro (size, get, dispatch, metadata, return)
</span><span class="cx">     get(m_value, t0)
</span><span class="cx">     get(m_specialPointer, t1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm      2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm 2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -2072,6 +2072,19 @@
</span><span class="cx"> undefinedOrNullJumpOp(jnundefined_or_null, OpJnundefinedOrNull,
</span><span class="cx">     macro (value, target) bqneq value, ValueNull, target end)
</span><span class="cx"> 
</span><ins>+llintOpWithReturn(op_jeq_ptr, OpJeqPtr, macro (size, get, dispatch, return)
+    get(m_value, t0)
+    get(m_specialPointer, t1)
+    loadConstant(size, t1, t2)
+    bpeq t2, [cfr, t0, 8], .opJeqPtrTarget
+    dispatch()
+
+.opJeqPtrTarget:
+    get(m_targetLabel, t0)
+    jumpImpl(dispatchIndirect, t0)
+end)
+
+
</ins><span class="cx"> llintOpWithMetadata(op_jneq_ptr, OpJneqPtr, macro (size, get, dispatch, metadata, return)
</span><span class="cx">     get(m_value, t0)
</span><span class="cx">     get(m_specialPointer, t1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp  2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp     2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -1001,7 +1001,7 @@
</span><span class="cx">     metadata.m_enumeratorMetadata |= static_cast<uint8_t>(mode);
</span><span class="cx">     modeRegister = jsNumber(static_cast<uint8_t>(mode));
</span><span class="cx">     indexRegister = jsNumber(index);
</span><del>-    nameRegister = name ? name : jsNull();
</del><ins>+    nameRegister = name ? name : vm.smallStrings.sentinelString();
</ins><span class="cx">     END();
</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 (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp   2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp      2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -981,6 +981,8 @@
</span><span class="cx">     m_setIteratorPrototype.set(vm, this, setIteratorPrototype);
</span><span class="cx">     m_setIteratorStructure.set(vm, this, JSSetIterator::createStructure(vm, this, setIteratorPrototype));
</span><span class="cx"> 
</span><ins>+    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::sentinelString)].set(vm, this, vm.smallStrings.sentinelString());
+
</ins><span class="cx">     JSFunction* defaultPromiseThen = JSFunction::create(vm, promisePrototypeThenCodeGenerator(vm), this);
</span><span class="cx">     m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::defaultPromiseThen)].set(vm, this, defaultPromiseThen);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSmallStringscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp     2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/runtime/SmallStrings.cpp        2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -62,6 +62,7 @@
</span><span class="cx">     initialize(&vm, m_notEqualString, "not-equal");
</span><span class="cx">     initialize(&vm, m_timedOutString, "timed-out");
</span><span class="cx">     initialize(&vm, m_okString, "ok");
</span><ins>+    initialize(&vm, m_sentinelString, "$");
</ins><span class="cx"> 
</span><span class="cx">     setIsInitialized(true);
</span><span class="cx"> }
</span><span class="lines">@@ -83,6 +84,7 @@
</span><span class="cx">     visitor.appendUnbarriered(m_notEqualString);
</span><span class="cx">     visitor.appendUnbarriered(m_timedOutString);
</span><span class="cx">     visitor.appendUnbarriered(m_okString);
</span><ins>+    visitor.appendUnbarriered(m_sentinelString);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template void SmallStrings::visitStrongReferences(AbstractSlotVisitor&);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSmallStringsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SmallStrings.h (283097 => 283098)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SmallStrings.h       2021-09-27 04:40:08 UTC (rev 283097)
+++ trunk/Source/JavaScriptCore/runtime/SmallStrings.h  2021-09-27 05:02:37 UTC (rev 283098)
</span><span class="lines">@@ -119,6 +119,7 @@
</span><span class="cx">     JSString* notEqualString() const { return m_notEqualString; }
</span><span class="cx">     JSString* timedOutString() const { return m_timedOutString; }
</span><span class="cx">     JSString* okString() const { return m_okString; }
</span><ins>+    JSString* sentinelString() const { return m_sentinelString; }
</ins><span class="cx"> 
</span><span class="cx">     bool needsToBeVisited(CollectionScope scope) const
</span><span class="cx">     {
</span><span class="lines">@@ -143,6 +144,7 @@
</span><span class="cx">     JSString* m_notEqualString { nullptr };
</span><span class="cx">     JSString* m_timedOutString { nullptr };
</span><span class="cx">     JSString* m_okString { nullptr };
</span><ins>+    JSString* m_sentinelString { nullptr };
</ins><span class="cx">     JSString* m_singleCharacterStrings[singleCharacterStringCount] { nullptr };
</span><span class="cx">     bool m_needsToBeVisited { true };
</span><span class="cx">     bool m_isInitialized { false };
</span></span></pre>
</div>
</div>

</body>
</html>