Title: [285541] branches/safari-612-branch
Revision
285541
Author
ysuz...@apple.com
Date
2021-11-09 16:29:58 -0800 (Tue, 09 Nov 2021)

Log Message

EnumeratorGetByVal for IndexedMode+OwnStructureMode doesn't always recover the property name
https://bugs.webkit.org/show_bug.cgi?id=231321
<rdar://problem/84211697>

Reviewed by Yusuke Suzuki.

JSTests:

* stress/enumerator-get-by-val-needs-to-recover-property-name.js: Added.

Source/_javascript_Core:

When running an EnumeratorGetByVal in IndexedMode+OwnStructureMode, we may
go to the slow path. However, we were incorrectly going to the slow path
before recovering the actual property name. Instead, we were passing in
the integer index value to the get by val.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):

Canonical link: https://commits.webkit.org/243803@main

Modified Paths

Added Paths

Diff

Modified: branches/safari-612-branch/JSTests/ChangeLog (285540 => 285541)


--- branches/safari-612-branch/JSTests/ChangeLog	2021-11-10 00:03:09 UTC (rev 285540)
+++ branches/safari-612-branch/JSTests/ChangeLog	2021-11-10 00:29:58 UTC (rev 285541)
@@ -1,3 +1,13 @@
+2021-11-02  Saam Barati  <sbar...@apple.com>
+
+        EnumeratorGetByVal for IndexedMode+OwnStructureMode doesn't always recover the property name
+        https://bugs.webkit.org/show_bug.cgi?id=231321
+        <rdar://problem/84211697>
+
+        Reviewed by Yusuke Suzuki.
+
+        * stress/enumerator-get-by-val-needs-to-recover-property-name.js: Added.
+
 2021-11-08  Kocsen Chung  <kocsen_ch...@apple.com>
 
         Cherry-pick r283938. rdar://problem/85166798

Added: branches/safari-612-branch/JSTests/stress/enumerator-get-by-val-needs-to-recover-property-name.js (0 => 285541)


--- branches/safari-612-branch/JSTests/stress/enumerator-get-by-val-needs-to-recover-property-name.js	                        (rev 0)
+++ branches/safari-612-branch/JSTests/stress/enumerator-get-by-val-needs-to-recover-property-name.js	2021-11-10 00:29:58 UTC (rev 285541)
@@ -0,0 +1,32 @@
+//@ runDefault("--validateOptions=true", "--useConcurrentJIT=false", "--useConcurrentGC=false", "--thresholdForJITSoon=10", "--thresholdForJITAfterWarmUp=10", "--thresholdForOptimizeAfterWarmUp=100", "--thresholdForOptimizeAfterLongWarmUp=100", "--thresholdForOptimizeSoon=100", "--thresholdForFTLOptimizeAfterWarmUp=1000", "--thresholdForFTLOptimizeSoon=1000", "--validateBCE=true", "--useFTLJIT=true")
+
+function assert(b) {
+    if (!b)
+        throw new Error;
+}
+
+function main() {
+    let result;
+    const v35 = [0, 0, {b:"AAAAA"}];
+    
+    async function v36(arr) {
+        edenGC();  // This is needed
+        for (let i = 0; i < 2; i++) {
+            const v201 = ` 
+                var someVar; // this is needed
+
+                for (let j = 0; j < 60000; j++) { }
+
+                const v222 = {"__proto__":[[]], "a":0, "b":0};
+                for (const prop in v222) {
+                    result = arr[prop];
+                    v222.__proto__ = {};
+                }
+            `;
+            eval(v201); // moving code out of eval breaks differential
+        }
+    }
+    v35.filter(v36);
+    assert(result === "AAAAA");
+}
+main();

Modified: branches/safari-612-branch/Source/_javascript_Core/ChangeLog (285540 => 285541)


--- branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-11-10 00:03:09 UTC (rev 285540)
+++ branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-11-10 00:29:58 UTC (rev 285541)
@@ -1,3 +1,21 @@
+2021-11-02  Saam Barati  <sbar...@apple.com>
+
+        EnumeratorGetByVal for IndexedMode+OwnStructureMode doesn't always recover the property name
+        https://bugs.webkit.org/show_bug.cgi?id=231321
+        <rdar://problem/84211697>
+
+        Reviewed by Yusuke Suzuki.
+
+        When running an EnumeratorGetByVal in IndexedMode+OwnStructureMode, we may
+        go to the slow path. However, we were incorrectly going to the slow path
+        before recovering the actual property name. Instead, we were passing in
+        the integer index value to the get by val.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+
 2021-11-08  Kocsen Chung  <kocsen_ch...@apple.com>
 
         Cherry-pick r283938. rdar://problem/85166798

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.cpp (285540 => 285541)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-11-10 00:03:09 UTC (rev 285540)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-11-10 00:29:58 UTC (rev 285541)
@@ -2506,7 +2506,7 @@
     return result;
 }
 
-JSC_DEFINE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, uint32_t index, JSPropertyNameEnumerator* enumerator))
+JSC_DEFINE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue baseValue, uint32_t index, JSPropertyNameEnumerator* enumerator))
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -2517,7 +2517,8 @@
     PropertyName propertyName = string->toIdentifier(globalObject);
     // This should only really return for TerminationException since we know string is backed by a UUID.
     RETURN_IF_EXCEPTION(scope, { });
-    JSObject* object = base->toObject(globalObject);
+    JSValue base = JSValue::decode(baseValue);
+    JSObject* object = base.toObject(globalObject);
     RETURN_IF_EXCEPTION(scope, { });
 
     RELEASE_AND_RETURN(scope, JSValue::encode(object->get(globalObject, propertyName)));

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.h (285540 => 285541)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.h	2021-11-10 00:03:09 UTC (rev 285540)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.h	2021-11-10 00:29:58 UTC (rev 285541)
@@ -111,7 +111,7 @@
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, JSString*, (JSGlobalObject*, uint32_t, int32_t, JSPropertyNameEnumerator*));
 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(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, uint32_t, JSPropertyNameEnumerator*));
 
 JSC_DECLARE_JIT_OPERATION(operationNewRegexpWithLastIndex, JSCell*, (JSGlobalObject*, JSCell*, EncodedJSValue));
 JSC_DECLARE_JIT_OPERATION(operationNewArray, char*, (JSGlobalObject*, Structure*, void*, size_t));

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (285540 => 285541)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-11-10 00:03:09 UTC (rev 285540)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-11-10 00:29:58 UTC (rev 285541)
@@ -13699,7 +13699,7 @@
         JSValueRegs resultRegs;
         GPRReg indexGPR;
         GPRReg enumeratorGPR;
-        MacroAssembler::Jump badStructureSlowPath;
+        MacroAssembler::JumpList recoverGenericCase;
 
         compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat)>([&] (DataFormat) {
             Edge storageEdge = m_graph.varArgChild(node, 2);
@@ -13728,12 +13728,15 @@
                 storageGPR = storage.gpr();
 
             MacroAssembler::JumpList notFastNamedCases;
+            // FIXME: Maybe we should have a better way to represent IndexedMode+OwnStructureMode?
+            bool indexedAndOwnStructureMode = m_graph.varArgChild(node, 1).node() == m_graph.varArgChild(node, 3).node();
+            MacroAssembler::JumpList& genericOrRecoverCase = indexedAndOwnStructureMode ? recoverGenericCase : 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));
+                    genericOrRecoverCase.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.
@@ -13745,11 +13748,7 @@
                     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);
+                genericOrRecoverCase.append(badStructure);
 
                 // Compute the offset
                 // If index is less than the enumerator's cached inline storage, then it's an inline access
@@ -13781,8 +13780,8 @@
         // 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));
+        if (!recoverGenericCase.empty())
+            addSlowPathGenerator(slowPathCall(recoverGenericCase, this, operationEnumeratorRecoverNameAndGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseCellGPR, indexGPR, enumeratorGPR));
 
         doneCases.link(&m_jit);
     };

Modified: branches/safari-612-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (285540 => 285541)


--- branches/safari-612-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-11-10 00:03:09 UTC (rev 285540)
+++ branches/safari-612-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-11-10 00:29:58 UTC (rev 285541)
@@ -13572,7 +13572,15 @@
         LBasicBlock outOfLineLoadBlock = m_out.newBlock();
         LBasicBlock genericICBlock = m_out.newBlock();
         LBasicBlock continuation = m_out.newBlock();
+        LBasicBlock genericOrRecover;
 
+        // FIXME: This is not the cleanest way to say we're using IndexedMode+OwnStructureMode mode. 
+        bool indexedAndOwnStructureMode = indexEdge.node() == propertyNameEdge.node();
+        if (indexedAndOwnStructureMode)
+            genericOrRecover = m_out.newBlock();
+        else
+            genericOrRecover = genericICBlock;
+
         Vector<ValueFromBlock, 4> results;
 
         LValue isNotNamed = m_out.testNonZero32(mode, m_out.constInt32(JSPropertyNameEnumerator::IndexedMode | JSPropertyNameEnumerator::GenericMode));
@@ -13579,7 +13587,7 @@
         m_out.branch(isNotNamed, unsure(genericICBlock), unsure(checkIsCellBlock));
 
         m_out.appendTo(checkIsCellBlock);
-        m_out.branch(isCell(base, provenType(baseEdge)), usually(checkStructureBlock), rarely(genericICBlock));
+        m_out.branch(isCell(base, provenType(baseEdge)), usually(checkStructureBlock), rarely(genericOrRecover));
 
         m_out.appendTo(checkStructureBlock);
         LValue structureID;
@@ -13591,16 +13599,8 @@
 
         LValue hasEnumeratorStructure = m_out.equal(structureID, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedStructureID));
 
-        if (indexEdge.node() == propertyNameEdge.node()) {
-            JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
-            LBasicBlock badStructureSlowPath = m_out.newBlock();
-            m_out.branch(hasEnumeratorStructure, usually(checkInlineOrOutOfLineBlock), rarely(genericICBlock));
+        m_out.branch(hasEnumeratorStructure, usually(checkInlineOrOutOfLineBlock), rarely(genericOrRecover));
 
-            m_out.appendTo(badStructureSlowPath);
-            results.append(m_out.anchor(vmCall(Int64, operationEnumeratorRecoverNameAndGetByVal, weakPointer(globalObject), base, index, enumerator)));
-        } else
-            m_out.branch(hasEnumeratorStructure, usually(checkInlineOrOutOfLineBlock), rarely(genericICBlock));
-
         m_out.appendTo(checkInlineOrOutOfLineBlock);
         LValue inlineCapacity = nullptr;
         bool hasNoOutOfLineProperties = false;
@@ -13644,6 +13644,12 @@
         results.append(m_out.anchor(genericResult));
         m_out.jump(continuation);
 
+        if (indexedAndOwnStructureMode) {
+            m_out.appendTo(genericOrRecover);
+            results.append(m_out.anchor(vmCall(Int64, operationEnumeratorRecoverNameAndGetByVal, weakPointer(m_graph.globalObjectFor(m_origin.semantic)), base, index, enumerator)));
+            m_out.jump(continuation);
+        }
+
         m_out.appendTo(continuation);
         ASSERT(results.size());
         LValue result = m_out.phi(Int64, results);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to