<!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>[284700] 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/284700">284700</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2021-10-22 11:31:50 -0700 (Fri, 22 Oct 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC][32bit] Re-enable compileEnumeratorGetByVal fast path
https://bugs.webkit.org/show_bug.cgi?id=232052

Patch by Mikhail R. Gadelha <mikhail@igalia.com> on 2021-10-22
Reviewed by Yusuke Suzuki.

In https://bugs.webkit.org/show_bug.cgi?id=229543, the compileEnumeratorGetByVal
fast path had to be disabled in 32 bits due to not having enough registers.
There are enough registers available now, so we can re-enable the fast path and
removed the speculation that the baseEdge of both enumeratorGetByVal and
getByVal is a Cell in 32 bits.

I've also updated the 32 bits version of compileGetByVal to be closer to the 64
bits version: using DFG_CRASH instead of RELEASE_ASSERT_NOT_REACHED, using nullptr
instead of 0, and removed some whitespaces.

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByVal):
(JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): Deleted.
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.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="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/ChangeLog       2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2021-10-22  Mikhail R. Gadelha  <mikhail@igalia.com>
+
+        [JSC][32bit] Re-enable compileEnumeratorGetByVal fast path
+        https://bugs.webkit.org/show_bug.cgi?id=232052
+
+        Reviewed by Yusuke Suzuki.
+
+        In https://bugs.webkit.org/show_bug.cgi?id=229543, the compileEnumeratorGetByVal
+        fast path had to be disabled in 32 bits due to not having enough registers.
+        There are enough registers available now, so we can re-enable the fast path and
+        removed the speculation that the baseEdge of both enumeratorGetByVal and
+        getByVal is a Cell in 32 bits.
+
+        I've also updated the 32 bits version of compileGetByVal to be closer to the 64
+        bits version: using DFG_CRASH instead of RELEASE_ASSERT_NOT_REACHED, using nullptr
+        instead of 0, and removed some whitespaces.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetByVal):
+        (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): Deleted.
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): Deleted.
+
</ins><span class="cx"> 2021-10-22  Saam Barati  <sbarati@apple.com>
</span><span class="cx"> 
</span><span class="cx">         canDoFastSpread should also check that the Structure is from the global object we're watching
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp   2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -1124,9 +1124,6 @@
</span><span class="cx">                         break;
</span><span class="cx">                     }
</span><span class="cx">                 }
</span><del>-#if USE(JSVALUE32_64)
-                fixEdge<CellUse>(m_graph.varArgChild(node, 0)); // Speculating cell due to register pressure on 32-bit.
-#endif
</del><span class="cx">                 break;
</span><span class="cx">             case Array::ForceExit:
</span><span class="cx">                 break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp   2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -749,35 +749,6 @@
</span><span class="cx">     return JSValue::encode(jsNumber(truncatedValueOfArgument));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSC_DEFINE_JIT_OPERATION(operationGetByValCell, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue encodedProperty))
-{
-    VM& vm = globalObject->vm();
-    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
-    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSValue property = JSValue::decode(encodedProperty);
-
-    if (std::optional<uint32_t> index = property.tryGetAsUint32Index())
-        RELEASE_AND_RETURN(scope, getByValWithIndex(globalObject, base, *index));
-
-    if (property.isString()) {
-        Structure& structure = *base->structure(vm);
-        if (JSCell::canUseFastGetOwnProperty(structure)) {
-            RefPtr<AtomStringImpl> existingAtomString = asString(property)->toExistingAtomString(globalObject);
-            RETURN_IF_EXCEPTION(scope, encodedJSValue());
-            if (existingAtomString) {
-                if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomString.get()))
-                    return JSValue::encode(result);
-            }
-        }
-    }
-
-    auto propertyName = property.toPropertyKey(globalObject);
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
-    RELEASE_AND_RETURN(scope, JSValue::encode(JSValue(base).get(globalObject, propertyName)));
-}
-
</del><span class="cx"> ALWAYS_INLINE EncodedJSValue getByValCellInt(JSGlobalObject* globalObject, VM& vm, JSCell* base, int32_t index)
</span><span class="cx"> {
</span><span class="cx">     if (index < 0) {
</span><span class="lines">@@ -2507,7 +2478,7 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSC_DEFINE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, uint32_t index, JSPropertyNameEnumerator* enumerator))
</del><ins>+JSC_DEFINE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue baseValue, uint32_t index, 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">@@ -2518,7 +2489,8 @@
</span><span class="cx">     PropertyName propertyName = string->toIdentifier(globalObject);
</span><span class="cx">     // This should only really return for TerminationException since we know string is backed by a UUID.
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, { });
</span><del>-    JSObject* object = base->toObject(globalObject);
</del><ins>+    JSValue base = JSValue::decode(baseValue);
+    JSObject* object = base.toObject(globalObject);
</ins><span class="cx">     RETURN_IF_EXCEPTION(scope, { });
</span><span class="cx"> 
</span><span class="cx">     RELEASE_AND_RETURN(scope, JSValue::encode(object->get(globalObject, propertyName)));
</span><span class="lines">@@ -2539,19 +2511,6 @@
</span><span class="cx">     RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(globalObject, base, propertyName))));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSC_DEFINE_JIT_OPERATION(operationEnumeratorGetByValGeneric, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue baseValue, EncodedJSValue propertyNameValue, uint32_t index, int32_t modeNumber, JSPropertyNameEnumerator* enumerator))
-{
-    VM& vm = globalObject->vm();
-    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
-    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSValue property = JSValue::decode(propertyNameValue);
-    JSPropertyNameEnumerator::Flag mode = static_cast<JSPropertyNameEnumerator::Flag>(modeNumber);
-    JSValue base = JSValue::decode(baseValue);
-    RELEASE_AND_RETURN(scope, JSValue::encode(CommonSlowPaths::opEnumeratorGetByVal(globalObject, base, property, index, mode, enumerator)));
-}
-
</del><span class="cx"> JSC_DEFINE_JIT_OPERATION(operationEnumeratorHasOwnProperty, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue baseValue, EncodedJSValue propertyNameValue, uint32_t index, int32_t modeNumber))
</span><span class="cx"> {
</span><span class="cx">     VM& vm = globalObject->vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h  2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h     2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -90,7 +90,6 @@
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationArithFloor, EncodedJSValue, (JSGlobalObject*, EncodedJSValue));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationArithCeil, EncodedJSValue, (JSGlobalObject*, EncodedJSValue));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationArithTrunc, EncodedJSValue, (JSGlobalObject*, EncodedJSValue));
</span><del>-JSC_DECLARE_JIT_OPERATION(operationGetByValCell, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue encodedProperty));
</del><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationGetByValObjectInt, EncodedJSValue, (JSGlobalObject*, JSObject*, int32_t));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationGetByValStringInt, EncodedJSValue, (JSGlobalObject*, JSString*, int32_t));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationGetByValObjectString, EncodedJSValue, (JSGlobalObject*, JSCell*, JSCell* string));
</span><span class="lines">@@ -111,8 +110,7 @@
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, JSString*, (JSGlobalObject*, uint32_t, int32_t, JSPropertyNameEnumerator*));
</span><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><del>-JSC_DECLARE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject*, JSCell*, uint32_t, JSPropertyNameEnumerator*));
-JSC_DECLARE_JIT_OPERATION(operationEnumeratorGetByValGeneric, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t, JSPropertyNameEnumerator*));
</del><ins>+JSC_DECLARE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, uint32_t, JSPropertyNameEnumerator*));
</ins><span class="cx"> 
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationNewRegexpWithLastIndex, JSCell*, (JSGlobalObject*, JSCell*, EncodedJSValue));
</span><span class="cx"> JSC_DECLARE_JIT_OPERATION(operationNewArray, char*, (JSGlobalObject*, Structure*, void*, size_t));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp    2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp       2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -15854,6 +15854,118 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileEnumeratorGetByVal(Node* node)
+{
+    Edge baseEdge = m_graph.varArgChild(node, 0);
+    auto generate = [&] (JSValueRegs baseRegs) {
+        MacroAssembler::JumpList doneCases;
+        JSValueRegsTemporary result;
+        JSValueRegs resultRegs;
+        GPRReg indexGPR;
+        GPRReg enumeratorGPR;
+        MacroAssembler::Jump badStructureSlowPath;
+
+        compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat)>([&] (DataFormat) {
+            Edge storageEdge = m_graph.varArgChild(node, 2);
+            StorageOperand storage;
+            if (storageEdge)
+                storage.emplace(this, storageEdge);
+            SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 3));
+            SpeculateStrictInt32Operand mode(this, m_graph.varArgChild(node, 4));
+            SpeculateCellOperand enumerator(this, m_graph.varArgChild(node, 5));
+
+            GPRReg modeGPR = mode.gpr();
+            indexGPR = index.gpr();
+            enumeratorGPR = enumerator.gpr();
+
+            bool haveStorage = !!storageEdge;
+            GPRTemporary storageTemporary;
+            GPRReg storageGPR;
+            if (!haveStorage) {
+                storageTemporary = GPRTemporary(this, Reuse, enumerator);
+                storageGPR = storageTemporary.gpr();
+            } else
+                storageGPR = storage.gpr();
+
+            result = JSValueRegsTemporary(this);
+            resultRegs = result.regs();
+            GPRReg scratchGPR = resultRegs.payloadGPR();
+
+            MacroAssembler::JumpList notFastNamedCases;
+
+            // FIXME: We shouldn't generate this code if we know base is not an object.
+            notFastNamedCases.append(m_jit.branchTest32(MacroAssembler::NonZero, modeGPR, TrustedImm32(JSPropertyNameEnumerator::IndexedMode | JSPropertyNameEnumerator::GenericMode)));
+            {
+                if (!m_state.forNode(baseEdge).isType(SpecCell))
+                    notFastNamedCases.append(m_jit.branchIfNotCell(baseRegs));
+
+                // Check the structure
+                // FIXME: If we know there's only one structure for base we can just embed it here.
+                m_jit.load32(MacroAssembler::Address(baseRegs.payloadGPR(), JSCell::structureIDOffset()), scratchGPR);
+
+                auto badStructure = m_jit.branch32(
+                    MacroAssembler::NotEqual,
+                    scratchGPR,
+                    MacroAssembler::Address(
+                        enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset()));
+
+                // FIXME: Maybe we should have a better way to represent Indexed+Named?
+                if (m_graph.varArgChild(node, 1).node() == m_graph.varArgChild(node, 3).node())
+                    badStructureSlowPath = badStructure;
+                else
+                    notFastNamedCases.append(badStructure);
+
+                // Compute the offset
+                // If index is less than the enumerator's cached inline storage, then it's an inline access
+                MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual,
+                    indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
+
+                m_jit.loadValue(MacroAssembler::BaseIndex(baseRegs.payloadGPR(), indexGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage()), resultRegs);
+
+                doneCases.append(m_jit.jump());
+
+                // Otherwise it's out of line
+                outOfLineAccess.link(&m_jit);
+                m_jit.move(indexGPR, scratchGPR);
+                m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR);
+                m_jit.neg32(scratchGPR);
+                m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
+                if (!haveStorage)
+                    m_jit.loadPtr(MacroAssembler::Address(baseRegs.payloadGPR(), JSObject::butterflyOffset()), storageGPR);
+                constexpr intptr_t offsetOfFirstProperty = offsetInButterfly(firstOutOfLineOffset) * static_cast<intptr_t>(sizeof(EncodedJSValue));
+                m_jit.loadValue(MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty), resultRegs);
+                doneCases.append(m_jit.jump());
+            }
+
+            notFastNamedCases.link(&m_jit);
+            return std::make_pair(resultRegs, DataFormatJS);
+        }));
+
+        // We rely on compileGetByVal to call jsValueResult for us.
+        // FIXME: This is kinda hacky...
+        ASSERT(generationInfo(node).jsValueRegs() == resultRegs && generationInfo(node).registerFormat() == DataFormatJS);
+
+        if (badStructureSlowPath.isSet()) {
+            if (baseRegs.tagGPR() == InvalidGPRReg)
+                addSlowPathGenerator(slowPathCall(badStructureSlowPath, this, operationEnumeratorRecoverNameAndGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), CCallHelpers::CellValue(baseRegs.payloadGPR()), indexGPR, enumeratorGPR));
+            else
+                addSlowPathGenerator(slowPathCall(badStructureSlowPath, this, operationEnumeratorRecoverNameAndGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseRegs, indexGPR, enumeratorGPR));
+        }
+
+        doneCases.link(&m_jit);
+    };
+
+    if (isCell(baseEdge.useKind())) {
+        // Use manual operand speculation since Fixup may have picked a UseKind more restrictive than CellUse.
+        SpeculateCellOperand base(this, baseEdge, ManualOperandSpeculation);
+        speculate(node, baseEdge);
+        generate(JSValueRegs::payloadOnly(base.gpr()));
+    } else {
+        JSValueOperand base(this, baseEdge);
+        generate(base.regs());
+    }
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp       2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp  2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -1818,12 +1818,14 @@
</span><span class="cx"> void SpeculativeJIT::compileGetByVal(Node* node, const ScopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat preferredFormat)>& prefix)
</span><span class="cx"> {
</span><span class="cx">     switch (node->arrayMode().type()) {
</span><ins>+    case Array::AnyTypedArray:
+    case Array::ForceExit:
+    case Array::SelectUsingArguments:
</ins><span class="cx">     case Array::SelectUsingPredictions:
</span><del>-    case Array::ForceExit:
-        RELEASE_ASSERT_NOT_REACHED();
-#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
-        terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
-#endif
</del><ins>+    case Array::Unprofiled:
+    case Array::BigInt64Array:
+    case Array::BigUint64Array:
+        DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
</ins><span class="cx">         break;
</span><span class="cx">     case Array::Undecided: {
</span><span class="cx">         SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 1));
</span><span class="lines">@@ -1846,18 +1848,18 @@
</span><span class="cx">             if (m_graph.varArgChild(node, 0).useKind() == ObjectUse) {
</span><span class="cx">                 if (m_graph.varArgChild(node, 1).useKind() == StringUse) {
</span><span class="cx">                     compileGetByValForObjectWithString(node, prefix);
</span><del>-                    break;
</del><ins>+                    return;
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 if (m_graph.varArgChild(node, 1).useKind() == SymbolUse) {
</span><span class="cx">                     compileGetByValForObjectWithSymbol(node, prefix);
</span><del>-                    break;
</del><ins>+                    return;
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0)); // Save a register, speculate cell. We'll probably be right.
</del><ins>+            JSValueOperand base(this, m_graph.varArgChild(node, 0));
</ins><span class="cx">             JSValueOperand property(this, m_graph.varArgChild(node, 1));
</span><del>-            GPRReg baseGPR = base.gpr();
</del><ins>+            JSValueRegs baseGPR = base.jsValueRegs();
</ins><span class="cx">             JSValueRegs propertyRegs = property.jsValueRegs();
</span><span class="cx"> 
</span><span class="cx">             JSValueRegs resultRegs;
</span><span class="lines">@@ -1864,56 +1866,70 @@
</span><span class="cx">             std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
</span><span class="cx"> 
</span><span class="cx">             flushRegisters();
</span><del>-            callOperation(operationGetByValCell, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, propertyRegs);
</del><ins>+            callOperation(operationGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, propertyRegs);
</ins><span class="cx">             m_jit.exceptionCheck();
</span><span class="cx"> 
</span><span class="cx">             jsValueResult(resultRegs, node);
</span><del>-            break;
</del><ins>+            return;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        speculate(node, m_graph.varArgChild(node, 0));
</del><ins>+        JSValueOperand property(this, m_graph.varArgChild(node, 1), ManualOperandSpeculation);
+        JSValueRegs propertyRegs = property.jsValueRegs();
</ins><span class="cx">         speculate(node, m_graph.varArgChild(node, 1));
</span><span class="cx"> 
</span><del>-        JSValueOperand base(this, m_graph.varArgChild(node, 0), ManualOperandSpeculation);
-        JSValueOperand property(this, m_graph.varArgChild(node, 1), ManualOperandSpeculation);
</del><ins>+        auto generate = [&] (JSValueRegs baseRegs) {
+            JSValueRegs resultRegs;
+            std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
</ins><span class="cx"> 
</span><del>-        JSValueRegs baseRegs = base.jsValueRegs();
-        JSValueRegs propertyRegs = property.jsValueRegs();
</del><ins>+            CodeOrigin codeOrigin = node->origin.semantic;
+            CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
+            RegisterSet usedRegisters = this->usedRegisters();
</ins><span class="cx"> 
</span><del>-        JSValueRegs resultRegs;
-        std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
</del><ins>+            JITCompiler::JumpList slowCases;
+            if (!m_state.forNode(m_graph.varArgChild(node, 0)).isType(SpecCell))
+                slowCases.append(m_jit.branchIfNotCell(baseRegs));
</ins><span class="cx"> 
</span><del>-        CodeOrigin codeOrigin = node->origin.semantic;
-        CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
-        RegisterSet usedRegisters = this->usedRegisters();
</del><ins>+            JITGetByValGenerator gen(
+                m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::GetByVal, usedRegisters,
+                baseRegs, propertyRegs, resultRegs, InvalidGPRReg);
</ins><span class="cx"> 
</span><del>-        JITCompiler::JumpList slowCases;
-        if (!m_state.forNode(m_graph.varArgChild(node, 0)).isType(SpecCell))
-            slowCases.append(m_jit.branchIfNotCell(baseRegs.tagGPR()));
</del><ins>+            if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecString))
+                gen.stubInfo()->propertyIsString = true;
+            else if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecInt32Only))
+                gen.stubInfo()->propertyIsInt32 = true;
+            else if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecSymbol))
+                gen.stubInfo()->propertyIsSymbol = true;
</ins><span class="cx"> 
</span><del>-        JITGetByValGenerator gen(
-            m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::GetByVal, usedRegisters,
-            baseRegs, propertyRegs, resultRegs, InvalidGPRReg);
</del><ins>+            gen.generateFastPath(m_jit);
</ins><span class="cx"> 
</span><del>-        if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecString))
-            gen.stubInfo()->propertyIsString = true;
-        else if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecInt32Only))
-            gen.stubInfo()->propertyIsInt32 = true;
-        else if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecSymbol))
-            gen.stubInfo()->propertyIsSymbol = true;
</del><ins>+            slowCases.append(gen.slowPathJump());
</ins><span class="cx"> 
</span><del>-        gen.generateFastPath(m_jit);
</del><ins>+            std::unique_ptr<SlowPathGenerator> slowPath;
+            if (baseRegs.tagGPR() == InvalidGPRReg) {
+                slowPath = slowPathCall(
+                    slowCases, this, operationGetByValOptimize,
+                    resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), nullptr, CCallHelpers::CellValue(baseRegs.payloadGPR()), propertyRegs);
+            } else {
+                slowPath = slowPathCall(
+                    slowCases, this, operationGetByValOptimize,
+                    resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), nullptr, baseRegs, propertyRegs);
+            }
</ins><span class="cx"> 
</span><del>-        slowCases.append(gen.slowPathJump());
</del><ins>+            m_jit.addGetByVal(gen, slowPath.get());
+            addSlowPathGenerator(WTFMove(slowPath));
</ins><span class="cx"> 
</span><del>-        std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall(
-            slowCases, this, operationGetByValOptimize,
-            resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), nullptr, baseRegs, propertyRegs);
</del><ins>+            jsValueResult(resultRegs, node);
+        };
</ins><span class="cx"> 
</span><del>-        m_jit.addGetByVal(gen, slowPath.get());
-        addSlowPathGenerator(WTFMove(slowPath));
-
-        jsValueResult(resultRegs, node);
</del><ins>+        if (isCell(m_graph.varArgChild(node, 0).useKind())) {
+            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0), ManualOperandSpeculation);
+            speculate(node, m_graph.varArgChild(node, 0));
+            generate(JSValueRegs::payloadOnly(base.gpr()));
+        } else {
+            JSValueOperand base(this, m_graph.varArgChild(node, 0), ManualOperandSpeculation);
+            speculate(node, m_graph.varArgChild(node, 0));
+            generate(base.jsValueRegs());
+        }
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case Array::Int32:
</span><span class="lines">@@ -1932,7 +1948,7 @@
</span><span class="cx">             DataFormat format;
</span><span class="cx">             std::tie(resultRegs, format) = prefix(node->arrayMode().type() == Array::Int32 ? DataFormatInt32 : DataFormatJS);
</span><span class="cx"> 
</span><del>-            speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</del><ins>+            speculationCheck(OutOfBounds, JSValueRegs(), nullptr, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</ins><span class="cx"> 
</span><span class="cx">             if (format == DataFormatInt32) {
</span><span class="cx">                 ASSERT(!node->arrayMode().isInBoundsSaneChain());
</span><span class="lines">@@ -1994,8 +2010,8 @@
</span><span class="cx">         slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</span><span class="cx"> 
</span><span class="cx">         m_jit.loadValue(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultRegs);
</span><ins>+
</ins><span class="cx">         slowCases.append(m_jit.branchIfEmpty(resultRegs.tagGPR()));
</span><del>-
</del><span class="cx">         addSlowPathGenerator(
</span><span class="cx">             slowPathCall(
</span><span class="cx">                 slowCases, this, operationGetByValObjectInt,
</span><span class="lines">@@ -2016,22 +2032,23 @@
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><span class="cx">             FPRTemporary result(this);
</span><ins>+            FPRReg resultReg = result.fpr();
</ins><span class="cx"> 
</span><span class="cx">             JSValueRegs resultRegs;
</span><span class="cx">             DataFormat format;
</span><span class="cx">             std::tie(resultRegs, format) = prefix(DataFormatDouble);
</span><span class="cx"> 
</span><del>-            speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</del><ins>+            speculationCheck(OutOfBounds, JSValueRegs(), nullptr, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</ins><span class="cx"> 
</span><del>-            m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.fpr());
</del><ins>+            m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
</ins><span class="cx">             if (!node->arrayMode().isInBoundsSaneChain())
</span><del>-                speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchIfNaN(result.fpr()));
</del><ins>+                speculationCheck(LoadFromHole, JSValueRegs(), nullptr, m_jit.branchIfNaN(resultReg));
</ins><span class="cx">             if (format == DataFormatJS) {
</span><del>-                boxDouble(result.fpr(), resultRegs);
</del><ins>+                boxDouble(resultReg, resultRegs);
</ins><span class="cx">                 jsValueResult(resultRegs, node);
</span><span class="cx">             } else {
</span><span class="cx">                 ASSERT(format == DataFormatDouble && !resultRegs);
</span><del>-                doubleResult(result.fpr(), node);
</del><ins>+                doubleResult(resultReg, node);
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -2083,7 +2100,7 @@
</span><span class="cx">             JSValueRegs resultRegs;
</span><span class="cx">             std::tie(resultRegs, std::ignore) = prefix(DataFormatJS);
</span><span class="cx"> 
</span><del>-            speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
</del><ins>+            speculationCheck(OutOfBounds, JSValueRegs(), nullptr, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
</ins><span class="cx"> 
</span><span class="cx">             m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultRegs.tagGPR());
</span><span class="cx">             speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchIfEmpty(resultRegs.tagGPR()));
</span><span class="lines">@@ -2096,9 +2113,10 @@
</span><span class="cx">         SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
</span><span class="cx">         SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
</span><span class="cx">         StorageOperand storage(this, m_graph.varArgChild(node, 2));
</span><ins>+
+        GPRReg baseReg = base.gpr();
</ins><span class="cx">         GPRReg propertyReg = property.gpr();
</span><span class="cx">         GPRReg storageReg = storage.gpr();
</span><del>-        GPRReg baseReg = base.gpr();
</del><span class="cx"> 
</span><span class="cx">         if (!m_compileOkay)
</span><span class="cx">             return;
</span><span class="lines">@@ -2120,8 +2138,7 @@
</span><span class="cx">         addSlowPathGenerator(
</span><span class="cx">             slowPathCall(
</span><span class="cx">                 slowCases, this, operationGetByValObjectInt,
</span><del>-                resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)),
-                baseReg, propertyReg));
</del><ins>+                resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseReg, propertyReg));
</ins><span class="cx"> 
</span><span class="cx">         jsValueResult(resultRegs, node);
</span><span class="cx">         break;
</span><span class="lines">@@ -2135,8 +2152,15 @@
</span><span class="cx">     case Array::ScopedArguments:
</span><span class="cx">         compileGetByValOnScopedArguments(node, prefix);
</span><span class="cx">         break;
</span><del>-    default: {
-        ASSERT(node->arrayMode().isSomeTypedArrayView());
</del><ins>+    case Array::Int8Array:
+    case Array::Int16Array:
+    case Array::Int32Array:
+    case Array::Uint8Array:
+    case Array::Uint8ClampedArray:
+    case Array::Uint16Array:
+    case Array::Uint32Array:
+    case Array::Float32Array:
+    case Array::Float64Array: {
</ins><span class="cx">         TypedArrayType type = node->arrayMode().typedArrayType();
</span><span class="cx">         if (isInt(type))
</span><span class="cx">             compileGetByValOnIntTypedArray(node, type, prefix);
</span><span class="lines">@@ -4498,43 +4522,6 @@
</span><span class="cx">     doubleResult(result.fpr(), node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: we are always taking the slow path here, we should be able to do the equivalent to the 64bit version if we add more available (callee-save registers) to ARMv7 and/or if we reduce the number of registers compileEnumeratorGetByVal uses. See bug #230189.
-void SpeculativeJIT::compileEnumeratorGetByVal(Node* node)
-{
-    Edge baseEdge = m_graph.varArgChild(node, 0);
-    auto generate = [&] (JSValueRegs baseRegs) {
-        JSValueOperand property(this, m_graph.varArgChild(node, 1), ManualOperandSpeculation);
-        SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 3));
-        SpeculateStrictInt32Operand mode(this, m_graph.varArgChild(node, 4));
-        SpeculateCellOperand enumerator(this, m_graph.varArgChild(node, 5));
-        JSValueRegs propertyRegs = property.jsValueRegs();
-        GPRReg indexGPR = index.gpr();
-        GPRReg modeGPR = mode.gpr();
-        GPRReg enumeratorGPR = enumerator.gpr();
-
-        flushRegisters();
-
-        JSValueRegsFlushedCallResult result(this);
-        JSValueRegs resultRegs = result.regs();
-
-        if (baseRegs.tagGPR() == InvalidGPRReg)
-            callOperation(operationEnumeratorGetByValGeneric, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), CCallHelpers::CellValue(baseRegs.payloadGPR()), propertyRegs, indexGPR, modeGPR, enumeratorGPR);
-        else
-            callOperation(operationEnumeratorGetByValGeneric, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseRegs, propertyRegs, indexGPR, modeGPR, enumeratorGPR);
-        m_jit.exceptionCheck();
-        jsValueResult(resultRegs, node);
-    };
-
-    if (isCell(baseEdge.useKind())) {
-        // Use manual operand speculation since Fixup may have picked a UseKind more restrictive than CellUse.
-        speculate(node, baseEdge);
-        SpeculateCellOperand base(this, baseEdge, ManualOperandSpeculation);
-        generate(JSValueRegs::payloadOnly(base.gpr()));
-    } else {
-        JSValueOperand base(this, baseEdge);
-        generate(base.regs());
-    }
-}
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp  2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp     2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -6466,114 +6466,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SpeculativeJIT::compileEnumeratorGetByVal(Node* node)
-{
-    Edge baseEdge = m_graph.varArgChild(node, 0);
-    auto generate = [&] (GPRReg baseCellGPR) {
-        MacroAssembler::JumpList doneCases;
-        JSValueRegsTemporary result;
-        JSValueRegs resultRegs;
-        GPRReg indexGPR;
-        GPRReg enumeratorGPR;
-        MacroAssembler::Jump badStructureSlowPath;
-
-        compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat)>([&] (DataFormat) {
-            Edge storageEdge = m_graph.varArgChild(node, 2);
-            StorageOperand storage;
-            if (storageEdge)
-                storage.emplace(this, storageEdge);
-            SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 3));
-            SpeculateStrictInt32Operand mode(this, m_graph.varArgChild(node, 4));
-            SpeculateCellOperand enumerator(this, m_graph.varArgChild(node, 5));
-
-            GPRReg modeGPR = mode.gpr();
-            indexGPR = index.gpr();
-            enumeratorGPR = enumerator.gpr();
-
-            result = JSValueRegsTemporary(this);
-            resultRegs = result.regs();
-            GPRReg scratchGPR = resultRegs.payloadGPR();
-
-            bool haveStorage = !!storageEdge;
-            GPRTemporary storageTemporary;
-            GPRReg storageGPR;
-            if (!haveStorage) {
-                storageTemporary = GPRTemporary(this, Reuse, enumerator);
-                storageGPR = storageTemporary.gpr();
-            } else
-                storageGPR = storage.gpr();
-
-            MacroAssembler::JumpList notFastNamedCases;
-
-            // FIXME: We shouldn't generate this code if we know base is not an object.
-            notFastNamedCases.append(m_jit.branchTest32(MacroAssembler::NonZero, modeGPR, TrustedImm32(JSPropertyNameEnumerator::IndexedMode | JSPropertyNameEnumerator::GenericMode)));
-            {
-                if (!m_state.forNode(baseEdge).isType(SpecCell))
-                    notFastNamedCases.append(m_jit.branchIfNotCell(baseCellGPR));
-
-                // Check the structure
-                // FIXME: If we know there's only one structure for base we can just embed it here.
-                m_jit.load32(MacroAssembler::Address(baseCellGPR, JSCell::structureIDOffset()), scratchGPR);
-
-                auto badStructure = m_jit.branch32(
-                    MacroAssembler::NotEqual,
-                    scratchGPR,
-                    MacroAssembler::Address(
-                        enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset()));
-
-                // FIXME: Maybe we should have a better way to represent Indexed+Named?
-                if (m_graph.varArgChild(node, 1).node() == m_graph.varArgChild(node, 3).node())
-                    badStructureSlowPath = badStructure;
-                else
-                    notFastNamedCases.append(badStructure);
-
-                // Compute the offset
-                // If index is less than the enumerator's cached inline storage, then it's an inline access
-                MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual,
-                    indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
-
-                m_jit.loadValue(MacroAssembler::BaseIndex(baseCellGPR, indexGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage()), resultRegs);
-
-                doneCases.append(m_jit.jump());
-
-                // Otherwise it's out of line
-                outOfLineAccess.link(&m_jit);
-                m_jit.move(indexGPR, scratchGPR);
-                m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR);
-                m_jit.neg32(scratchGPR);
-                m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
-                if (!haveStorage)
-                    m_jit.loadPtr(MacroAssembler::Address(baseCellGPR, JSObject::butterflyOffset()), storageGPR);
-                constexpr intptr_t offsetOfFirstProperty = offsetInButterfly(firstOutOfLineOffset) * static_cast<intptr_t>(sizeof(EncodedJSValue));
-                m_jit.loadValue(MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty), resultRegs);
-                doneCases.append(m_jit.jump());
-            }
-
-            notFastNamedCases.link(&m_jit);
-            return std::make_pair(resultRegs, DataFormatJS);
-        }));
-
-        // We rely on compileGetByVal to call jsValueResult for us.
-        // FIXME: This is kinda hacky...
-        ASSERT(generationInfo(node).jsValueRegs() == resultRegs && generationInfo(node).registerFormat() == DataFormatJS);
-
-        if (badStructureSlowPath.isSet())
-            addSlowPathGenerator(slowPathCall(badStructureSlowPath, this, operationEnumeratorRecoverNameAndGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseCellGPR, indexGPR, enumeratorGPR));
-
-        doneCases.link(&m_jit);
-    };
-
-    if (isCell(baseEdge.useKind())) {
-        // Use manual operand speculation since Fixup may have picked a UseKind more restrictive than CellUse.
-        speculate(node, baseEdge);
-        SpeculateCellOperand baseOperand(this, baseEdge, ManualOperandSpeculation);
-        generate(baseOperand.gpr());
-    } else {
-        JSValueOperand baseOperand(this, baseEdge);
-        generate(baseOperand.gpr());
-    }
-}
-
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (284699 => 284700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h    2021-10-22 18:23:09 UTC (rev 284699)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h       2021-10-22 18:31:50 UTC (rev 284700)
</span><span class="lines">@@ -118,21 +118,6 @@
</span><span class="cx">     case JSPropertyNameEnumerator::GenericMode: {
</span><span class="cx">         if (arrayProfile && baseValue.isCell() && mode != JSPropertyNameEnumerator::OwnStructureMode)
</span><span class="cx">             arrayProfile->observeStructureID(baseValue.asCell()->structureID());
</span><del>-#if USE(JSVALUE32_64)
-        if (!propertyNameValue.isCell()) {
-            // This branch is only needed because we use this method
-            // both as a slow_path and as a DFG call op. We'll end up
-            // here if propertyName is not a cell then we are in
-            // index+named mode, so do what RecoverNameAndGetVal
-            // does. This can probably be removed if we re-enable the
-            // optimizations for enumeratorGetByVal in DFG, see bug
-            // #230189.
-            JSString* string = enumerator->propertyNameAtIndex(index);
-            auto propertyName = string->toIdentifier(globalObject);
-            RETURN_IF_EXCEPTION(scope, { });
-            RELEASE_AND_RETURN(scope, baseValue.get(globalObject, propertyName));
-        }
-#endif
</del><span class="cx">         JSString* string = asString(propertyNameValue);
</span><span class="cx">         auto propertyName = string->toIdentifier(globalObject);
</span><span class="cx">         RETURN_IF_EXCEPTION(scope, { });
</span></span></pre>
</div>
</div>

</body>
</html>