Title: [282651] releases/WebKitGTK/webkit-2.34/Source/_javascript_Core
Revision
282651
Author
carlo...@webkit.org
Date
2021-09-17 03:33:25 -0700 (Fri, 17 Sep 2021)

Log Message

Merge r282385 - [JSC] ASSERT failed in stress/for-in-tests.js (32bit)
https://bugs.webkit.org/show_bug.cgi?id=229543

Patch by Xan López <x...@igalia.com> on 2021-09-14
Reviewed by Yusuke Suzuki.

Since r280760 DFG::SpeculativeJIT::compileEnumeratorGetByVal uses
too many registers for 32bit. Revert to the slow path as a
temporary measure to avoid crashes, we'll try to reenable the
optimizations later on (see bug #230189).

* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION): define a generic call
operation for compileEnumeratorGetByVal.
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp: move the current version of
compileEnumeratorGetByVal to 64bit, since it won't work on 32bit.
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): call the generic call op always.
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): use the previous version here.
* runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH): refactor a bit the slow path
for enumeratorGetByVal so it can be called from DFG as a call
operation.
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::opEnumeratorGetByVal):

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/ChangeLog (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/ChangeLog	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/ChangeLog	2021-09-17 10:33:25 UTC (rev 282651)
@@ -1,3 +1,32 @@
+2021-09-14  Xan López  <x...@igalia.com>
+
+        [JSC] ASSERT failed in stress/for-in-tests.js (32bit)
+        https://bugs.webkit.org/show_bug.cgi?id=229543
+
+        Reviewed by Yusuke Suzuki.
+
+        Since r280760 DFG::SpeculativeJIT::compileEnumeratorGetByVal uses
+        too many registers for 32bit. Revert to the slow path as a
+        temporary measure to avoid crashes, we'll try to reenable the
+        optimizations later on (see bug #230189).
+
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION): define a generic call
+        operation for compileEnumeratorGetByVal.
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp: move the current version of
+        compileEnumeratorGetByVal to 64bit, since it won't work on 32bit.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): call the generic call op always.
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): use the previous version here.
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::JSC_DEFINE_COMMON_SLOW_PATH): refactor a bit the slow path
+        for enumeratorGetByVal so it can be called from DFG as a call
+        operation.
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::opEnumeratorGetByVal):
+
 2021-09-13  Xan López  <x...@igalia.com>
 
         [JSC][32bit] in-by-val fails inside for-in loop after delete

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGOperations.cpp (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-09-17 10:33:25 UTC (rev 282651)
@@ -2538,6 +2538,18 @@
     RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(globalObject, base, propertyName))));
 }
 
+JSC_DEFINE_JIT_OPERATION(operationEnumeratorGetByValGeneric, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* baseCell, 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::Mode mode = static_cast<JSPropertyNameEnumerator::Mode>(modeNumber);
+    RELEASE_AND_RETURN(scope, JSValue::encode(CommonSlowPaths::opEnumeratorGetByVal(globalObject, baseCell, property, index, mode, enumerator)));
+}
+
 JSC_DEFINE_JIT_OPERATION(operationEnumeratorHasOwnProperty, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue baseValue, EncodedJSValue propertyNameValue, uint32_t index, int32_t modeNumber))
 {
     VM& vm = globalObject->vm();

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGOperations.h (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGOperations.h	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGOperations.h	2021-09-17 10:33:25 UTC (rev 282651)
@@ -112,6 +112,7 @@
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorInByVal, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t));
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorHasOwnProperty, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t));
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject*, JSCell*, uint32_t, JSPropertyNameEnumerator*));
+JSC_DECLARE_JIT_OPERATION(operationEnumeratorGetByValGeneric, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue, uint32_t, int32_t, JSPropertyNameEnumerator*));
 
 JSC_DECLARE_JIT_OPERATION(operationNewRegexpWithLastIndex, JSCell*, (JSGlobalObject*, JSCell*, EncodedJSValue));
 JSC_DECLARE_JIT_OPERATION(operationNewArray, char*, (JSGlobalObject*, Structure*, void*, size_t));

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-09-17 10:33:25 UTC (rev 282651)
@@ -13623,114 +13623,6 @@
     jsValueResult(resultRegs, node);
 }
 
-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());
-    }
-}
-
 template<typename SlowPathFunctionType>
 void SpeculativeJIT::compileEnumeratorHasProperty(Node* node, SlowPathFunctionType slowPathFunction)
 {

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2021-09-17 10:33:25 UTC (rev 282651)
@@ -4480,6 +4480,29 @@
     doubleResult(result.fpr(), node);
 }
 
+// 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)
+{
+    SpeculateCellOperand baseOperand(this, m_graph.varArgChild(node, 0));
+    JSValueOperand property(this, m_graph.varArgChild(node, 1));
+    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 baseOperandGPR = baseOperand.gpr();
+    JSValueRegs propertyRegs = property.jsValueRegs();
+    GPRReg indexGPR = index.gpr();
+    GPRReg modeGPR = mode.gpr();
+    GPRReg enumeratorGPR = enumerator.gpr();
+
+    flushRegisters();
+
+    JSValueRegsFlushedCallResult result(this);
+    JSValueRegs resultRegs = result.regs();
+
+    callOperation(operationEnumeratorGetByValGeneric, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseOperandGPR, propertyRegs, indexGPR, modeGPR, enumeratorGPR);
+    m_jit.exceptionCheck();
+    jsValueResult(resultRegs, node);
+}
 #endif
 
 } } // namespace JSC::DFG

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2021-09-17 10:33:25 UTC (rev 282651)
@@ -6263,6 +6263,114 @@
     }
 }
 
+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());
+    }
+}
+
 #endif
 
 } } // namespace JSC::DFG

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2021-09-17 10:33:25 UTC (rev 282651)
@@ -1010,42 +1010,14 @@
     BEGIN();
     auto bytecode = pc->as<OpEnumeratorGetByVal>();
     JSValue baseValue = GET_C(bytecode.m_base).jsValue();
+    JSValue propertyName = GET(bytecode.m_propertyName).jsValue();
     auto& metadata = bytecode.metadata(codeBlock);
     auto mode = static_cast<JSPropertyNameEnumerator::Mode>(GET(bytecode.m_mode).jsValue().asUInt32());
     metadata.m_enumeratorMetadata |= static_cast<uint8_t>(mode);
-
     JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(GET(bytecode.m_enumerator).jsValue());
     unsigned index = GET(bytecode.m_index).jsValue().asInt32();
-    switch (mode) {
-    case JSPropertyNameEnumerator::IndexedMode: {
-        if (LIKELY(baseValue.isCell()))
-            metadata.m_arrayProfile.observeStructureID(baseValue.asCell()->structureID());
-        RETURN_PROFILED(baseValue.get(globalObject, static_cast<unsigned>(index)));
-    }
-    case JSPropertyNameEnumerator::OwnStructureMode: {
-        if (LIKELY(baseValue.isCell()) && baseValue.asCell()->structureID() == enumerator->cachedStructureID()) {
-            // We'll only match the structure ID if the base is an object.
-            ASSERT(index < enumerator->endStructurePropertyIndex());
-            RETURN_PROFILED(baseValue.getObject()->getDirect(index < enumerator->cachedInlineCapacity() ? index : index - enumerator->cachedInlineCapacity() + firstOutOfLineOffset));
-        } else
-            metadata.m_enumeratorMetadata |= static_cast<uint8_t>(JSPropertyNameEnumerator::HasSeenOwnStructureModeStructureMismatch);
-        FALLTHROUGH;
-    }
 
-    case JSPropertyNameEnumerator::GenericMode: {
-        if (baseValue.isCell() && mode != JSPropertyNameEnumerator::OwnStructureMode)
-            metadata.m_arrayProfile.observeStructureID(baseValue.asCell()->structureID());
-        JSString* string = asString(GET(bytecode.m_propertyName).jsValue());
-        auto propertyName = string->toIdentifier(globalObject);
-        CHECK_EXCEPTION();
-        RETURN_PROFILED(baseValue.get(globalObject, propertyName));
-    }
-
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        break;
-    };
-    RELEASE_ASSERT_NOT_REACHED();
+    RETURN_PROFILED(CommonSlowPaths::opEnumeratorGetByVal(globalObject, baseValue, propertyName, index, mode, enumerator, &metadata.m_arrayProfile, &metadata.m_enumeratorMetadata));
 }
 
 JSC_DEFINE_COMMON_SLOW_PATH(slow_path_enumerator_in_by_val)

Modified: releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/runtime/CommonSlowPaths.h (282650 => 282651)


--- releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/runtime/CommonSlowPaths.h	2021-09-17 10:33:17 UTC (rev 282650)
+++ releases/WebKitGTK/webkit-2.34/Source/_javascript_Core/runtime/CommonSlowPaths.h	2021-09-17 10:33:25 UTC (rev 282651)
@@ -31,6 +31,7 @@
 #include "ExceptionHelpers.h"
 #include "FunctionCodeBlock.h"
 #include "JSImmutableButterfly.h"
+#include "JSPropertyNameEnumerator.h"
 #include "ScopedArguments.h"
 #include "SlowPathFunction.h"
 #include "StackAlignment.h"
@@ -91,6 +92,60 @@
     return padding;
 }
 
+inline JSValue opEnumeratorGetByVal(JSGlobalObject* globalObject, JSValue baseValue, JSValue propertyNameValue, unsigned index, JSPropertyNameEnumerator::Mode mode, JSPropertyNameEnumerator* enumerator, ArrayProfile* arrayProfile = nullptr, uint8_t* enumeratorMetadata = nullptr)
+{
+    VM& vm = getVM(globalObject);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    switch (mode) {
+    case JSPropertyNameEnumerator::IndexedMode: {
+        if (arrayProfile && LIKELY(baseValue.isCell()))
+            arrayProfile->observeStructureID(baseValue.asCell()->structureID());
+        RELEASE_AND_RETURN(scope, baseValue.get(globalObject, static_cast<unsigned>(index)));
+    }
+    case JSPropertyNameEnumerator::OwnStructureMode: {
+        if (LIKELY(baseValue.isCell()) && baseValue.asCell()->structureID() == enumerator->cachedStructureID()) {
+            // We'll only match the structure ID if the base is an object.
+            ASSERT(index < enumerator->endStructurePropertyIndex());
+            RELEASE_AND_RETURN(scope, baseValue.getObject()->getDirect(index < enumerator->cachedInlineCapacity() ? index : index - enumerator->cachedInlineCapacity() + firstOutOfLineOffset));
+        } else {
+            if (enumeratorMetadata)
+                *enumeratorMetadata |= static_cast<uint8_t>(JSPropertyNameEnumerator::HasSeenOwnStructureModeStructureMismatch);
+        }
+        FALLTHROUGH;
+    }
+
+    case JSPropertyNameEnumerator::GenericMode: {
+        if (arrayProfile && baseValue.isCell() && mode != JSPropertyNameEnumerator::OwnStructureMode)
+            arrayProfile->observeStructureID(baseValue.asCell()->structureID());
+#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
+        JSString* string = asString(propertyNameValue);
+        auto propertyName = string->toIdentifier(globalObject);
+        RETURN_IF_EXCEPTION(scope, { });
+        RELEASE_AND_RETURN(scope, baseValue.get(globalObject, propertyName));
+    }
+
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    };
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
 inline bool opInByVal(JSGlobalObject* globalObject, JSValue baseVal, JSValue propName, ArrayProfile* arrayProfile = nullptr)
 {
     VM& vm = getVM(globalObject);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to