Title: [292697] trunk
Revision
292697
Author
ysuz...@apple.com
Date
2022-04-10 21:57:33 -0700 (Sun, 10 Apr 2022)

Log Message

[JSC] DFG / FTL should be aware of JSString's String replacement
https://bugs.webkit.org/show_bug.cgi?id=238918

Reviewed by Saam Barati.

JSTests:

* stress/resolve-rope-get-by-val.js: Added.
(shouldBe):
(test):
* stress/resolve-rope-string-char-at.js: Added.
(shouldBe):
(test):
* stress/resolve-rope-string-char-code-at.js: Added.
(shouldBe):
(test):
* stress/resolve-rope-string-code-point-at.js: Added.
(shouldBe):
(test):

Source/_javascript_Core:

After r289359, String in JSString* can be replaced even after it is resolved. When atomizing String inside JSString*,
we may replace the existing one to new AtomStringImpl if different AtomStringImpl is already registered in the
AtomStringTable. However, DFG / FTL GetIndexedPropertyStorage assumes that StringImpl* in JSString* never changes after
resolving. And this is wrong.

This patch decouples String handling in GetIndexedPropertyStorage as ResolveRope DFG node. GetIndexedPropertyStorage no
longer handles JSString and it is now tailored to object cases. ResolveRope does not expose StringImpl::m_data pointer,
and instead it keeps resolved JSString*. After this change,

    GetByVal(String:@0, Untyped:@1, GetIndexedProperty(String:@0))

is changed to

    GetByVal(ResolveRope(String:@0), Untyped:@1)

Also, we revisit all the value(...) callsites (by changing function name) and ensure that we have no code assuming String
cannot be changed after resolving.

A/B test ensured that this is perf-neutral.

* b3/B3Generate.cpp:
(JSC::B3::generateToAir):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitEqualityOpImpl):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::checkArray):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasStorageChild const):
(JSC::DFG::Node::storageChildIndex):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::compileStringCodePointAt):
* dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetIndexedPropertyStorage):
(JSC::FTL::DFG::LowerDFGToB3::compileResolveRope):
(JSC::FTL::DFG::LowerDFGToB3::compileStringCharAtImpl):
(JSC::FTL::DFG::LowerDFGToB3::compileStringCharCodeAt):
(JSC::FTL::DFG::LowerDFGToB3::compileStringCodePointAt):
* jsc.cpp:
(JSC_DEFINE_HOST_FUNCTION):
* runtime/HashMapImplInlines.h:
(JSC::jsMapHashImpl):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::name):
(JSC::InternalFunction::displayName):
(JSC::InternalFunction::calculatedDisplayName):
* runtime/InternalFunction.h:
* runtime/JSBoundFunction.h:
* runtime/JSCJSValueInlines.h:
(JSC::toPreferredPrimitiveType):
* runtime/JSModuleLoader.cpp:
(JSC::JSModuleLoader::importModule):
* runtime/JSONObject.cpp:
(JSC::Stringifier::appendStringifiedValue):
* runtime/JSPropertyNameEnumerator.cpp:
(JSC::JSPropertyNameEnumerator::computeNext):
* runtime/JSRemoteFunction.h:
* runtime/Operations.h:
(JSC::jsString):
(JSC::compareBigIntToOtherPrimitive):
(JSC::compareBigInt32ToOtherPrimitive):
* runtime/RegExpMatchesArray.h:
(JSC::createRegExpMatchesArray):
* runtime/StringPrototype.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/SymbolConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* tools/JSDollarVM.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):

Source/WebCore:

* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::reportViolationForUnsafeEval):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (292696 => 292697)


--- trunk/JSTests/ChangeLog	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/JSTests/ChangeLog	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1,3 +1,23 @@
+2022-04-10  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] DFG / FTL should be aware of JSString's String replacement
+        https://bugs.webkit.org/show_bug.cgi?id=238918
+
+        Reviewed by Saam Barati.
+
+        * stress/resolve-rope-get-by-val.js: Added.
+        (shouldBe):
+        (test):
+        * stress/resolve-rope-string-char-at.js: Added.
+        (shouldBe):
+        (test):
+        * stress/resolve-rope-string-char-code-at.js: Added.
+        (shouldBe):
+        (test):
+        * stress/resolve-rope-string-code-point-at.js: Added.
+        (shouldBe):
+        (test):
+
 2022-04-07  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC] Fire structure transition watchpoint in Structure::finishCreation instead of Structure constructor

Added: trunk/JSTests/stress/resolve-rope-get-by-val.js (0 => 292697)


--- trunk/JSTests/stress/resolve-rope-get-by-val.js	                        (rev 0)
+++ trunk/JSTests/stress/resolve-rope-get-by-val.js	2022-04-11 04:57:33 UTC (rev 292697)
@@ -0,0 +1,32 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var hello0 = "Hello"; // Ensure that "Hello" is registered in AtomStringTable.
+var hello1 = createNonRopeNonAtomString("Hello");
+
+function test(string)
+{
+    var result = ["", "", "", ""];
+    var object = { };
+    for (var i = 0; i < 10000; ++i) {
+        var index = i % 4;
+        result[index] = string[index];
+        if (i === 5000) {
+            // Enforce JSValue::toPropertyKey. After this, string is atomic.
+            object[string];
+        }
+    }
+    return result;
+}
+noInline(test);
+
+for (var i = 0; i < 1000; ++i) {
+    var newString = createNonRopeNonAtomString("Hello");
+    var result = test(newString)
+    shouldBe(result[0], 'H');
+    shouldBe(result[1], 'e');
+    shouldBe(result[2], 'l');
+    shouldBe(result[3], 'l');
+}

Added: trunk/JSTests/stress/resolve-rope-string-char-at.js (0 => 292697)


--- trunk/JSTests/stress/resolve-rope-string-char-at.js	                        (rev 0)
+++ trunk/JSTests/stress/resolve-rope-string-char-at.js	2022-04-11 04:57:33 UTC (rev 292697)
@@ -0,0 +1,32 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var hello0 = "Hello"; // Ensure that "Hello" is registered in AtomStringTable.
+var hello1 = createNonRopeNonAtomString("Hello");
+
+function test(string)
+{
+    var result = ["", "", "", ""];
+    var object = { };
+    for (var i = 0; i < 10000; ++i) {
+        var index = i % 4;
+        result[index] = string.charAt(index);
+        if (i === 5000) {
+            // Enforce JSValue::toPropertyKey. After this, string is atomic.
+            object[string];
+        }
+    }
+    return result;
+}
+noInline(test);
+
+for (var i = 0; i < 1000; ++i) {
+    var newString = createNonRopeNonAtomString("Hello");
+    var result = test(newString)
+    shouldBe(result[0], 'H');
+    shouldBe(result[1], 'e');
+    shouldBe(result[2], 'l');
+    shouldBe(result[3], 'l');
+}

Added: trunk/JSTests/stress/resolve-rope-string-char-code-at.js (0 => 292697)


--- trunk/JSTests/stress/resolve-rope-string-char-code-at.js	                        (rev 0)
+++ trunk/JSTests/stress/resolve-rope-string-char-code-at.js	2022-04-11 04:57:33 UTC (rev 292697)
@@ -0,0 +1,32 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var hello0 = "Hello"; // Ensure that "Hello" is registered in AtomStringTable.
+var hello1 = createNonRopeNonAtomString("Hello");
+
+function test(string)
+{
+    var result = [0, 0, 0, 0];
+    var object = { };
+    for (var i = 0; i < 10000; ++i) {
+        var index = i % 4;
+        result[index] = string.charCodeAt(index);
+        if (i === 5000) {
+            // Enforce JSValue::toPropertyKey. After this, string is atomic.
+            object[string];
+        }
+    }
+    return result;
+}
+noInline(test);
+
+for (var i = 0; i < 1000; ++i) {
+    var newString = createNonRopeNonAtomString("Hello");
+    var result = test(newString)
+    shouldBe(result[0], 72);
+    shouldBe(result[1], 101);
+    shouldBe(result[2], 108);
+    shouldBe(result[3], 108);
+}

Added: trunk/JSTests/stress/resolve-rope-string-code-point-at.js (0 => 292697)


--- trunk/JSTests/stress/resolve-rope-string-code-point-at.js	                        (rev 0)
+++ trunk/JSTests/stress/resolve-rope-string-code-point-at.js	2022-04-11 04:57:33 UTC (rev 292697)
@@ -0,0 +1,32 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var hello0 = "Hello"; // Ensure that "Hello" is registered in AtomStringTable.
+var hello1 = createNonRopeNonAtomString("Hello");
+
+function test(string)
+{
+    var result = [0, 0, 0, 0];
+    var object = { };
+    for (var i = 0; i < 10000; ++i) {
+        var index = i % 4;
+        result[index] = string.codePointAt(index);
+        if (i === 5000) {
+            // Enforce JSValue::toPropertyKey. After this, string is atomic.
+            object[string];
+        }
+    }
+    return result;
+}
+noInline(test);
+
+for (var i = 0; i < 1000; ++i) {
+    var newString = createNonRopeNonAtomString("Hello");
+    var result = test(newString)
+    shouldBe(result[0], 72);
+    shouldBe(result[1], 101);
+    shouldBe(result[2], 108);
+    shouldBe(result[3], 108);
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (292696 => 292697)


--- trunk/Source/_javascript_Core/ChangeLog	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1,3 +1,111 @@
+2022-04-10  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] DFG / FTL should be aware of JSString's String replacement
+        https://bugs.webkit.org/show_bug.cgi?id=238918
+
+        Reviewed by Saam Barati.
+
+        After r289359, String in JSString* can be replaced even after it is resolved. When atomizing String inside JSString*,
+        we may replace the existing one to new AtomStringImpl if different AtomStringImpl is already registered in the
+        AtomStringTable. However, DFG / FTL GetIndexedPropertyStorage assumes that StringImpl* in JSString* never changes after
+        resolving. And this is wrong.
+
+        This patch decouples String handling in GetIndexedPropertyStorage as ResolveRope DFG node. GetIndexedPropertyStorage no
+        longer handles JSString and it is now tailored to object cases. ResolveRope does not expose StringImpl::m_data pointer,
+        and instead it keeps resolved JSString*. After this change,
+
+            GetByVal(String:@0, Untyped:@1, GetIndexedProperty(String:@0))
+
+        is changed to
+
+            GetByVal(ResolveRope(String:@0), Untyped:@1)
+
+        Also, we revisit all the value(...) callsites (by changing function name) and ensure that we have no code assuming String
+        cannot be changed after resolving.
+
+        A/B test ensured that this is perf-neutral.
+
+        * b3/B3Generate.cpp:
+        (JSC::B3::generateToAir):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitEqualityOpImpl):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::checkArray):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasStorageChild const):
+        (JSC::DFG::Node::storageChildIndex):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::compileStringCodePointAt):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetIndexedPropertyStorage):
+        (JSC::FTL::DFG::LowerDFGToB3::compileResolveRope):
+        (JSC::FTL::DFG::LowerDFGToB3::compileStringCharAtImpl):
+        (JSC::FTL::DFG::LowerDFGToB3::compileStringCharCodeAt):
+        (JSC::FTL::DFG::LowerDFGToB3::compileStringCodePointAt):
+        * jsc.cpp:
+        (JSC_DEFINE_HOST_FUNCTION):
+        * runtime/HashMapImplInlines.h:
+        (JSC::jsMapHashImpl):
+        * runtime/InternalFunction.cpp:
+        (JSC::InternalFunction::name):
+        (JSC::InternalFunction::displayName):
+        (JSC::InternalFunction::calculatedDisplayName):
+        * runtime/InternalFunction.h:
+        * runtime/JSBoundFunction.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::toPreferredPrimitiveType):
+        * runtime/JSModuleLoader.cpp:
+        (JSC::JSModuleLoader::importModule):
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::appendStringifiedValue):
+        * runtime/JSPropertyNameEnumerator.cpp:
+        (JSC::JSPropertyNameEnumerator::computeNext):
+        * runtime/JSRemoteFunction.h:
+        * runtime/Operations.h:
+        (JSC::jsString):
+        (JSC::compareBigIntToOtherPrimitive):
+        (JSC::compareBigInt32ToOtherPrimitive):
+        * runtime/RegExpMatchesArray.h:
+        (JSC::createRegExpMatchesArray):
+        * runtime/StringPrototype.cpp:
+        (JSC::JSC_DEFINE_JIT_OPERATION):
+        (JSC::JSC_DEFINE_HOST_FUNCTION):
+        * runtime/SymbolConstructor.cpp:
+        (JSC::JSC_DEFINE_HOST_FUNCTION):
+        * tools/JSDollarVM.cpp:
+        (JSC::JSC_DEFINE_HOST_FUNCTION):
+
 2022-04-09  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC] Use Vector with inline capacity in ObjectPropertyConditionSet creation

Modified: trunk/Source/_javascript_Core/b3/B3Generate.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/b3/B3Generate.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/b3/B3Generate.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -136,6 +136,8 @@
     }
 
     lowerToAir(procedure);
+    if (shouldDumpIR(procedure, B3Mode))
+        procedure.setShouldDumpIR();
     procedure.freeUnneededB3ValuesAfterLowering();
 }
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1729,7 +1729,7 @@
             && src1->isTemporary()
             && src2->virtualRegister().isConstant()
             && m_codeBlock->constantRegister(src2->virtualRegister()).get().isString()) {
-            const String& value = asString(m_codeBlock->constantRegister(src2->virtualRegister()).get())->tryGetValue();
+            String value = asString(m_codeBlock->constantRegister(src2->virtualRegister()).get())->tryGetValue();
             if (value == "undefined") {
                 rewind();
                 OpTypeofIsUndefined::emit(this, dst, op.m_value);

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -3792,6 +3792,7 @@
         break;
     }
     case GetIndexedPropertyStorage: {
+        ASSERT(node->arrayMode().type() != Array::String);
         JSArrayBufferView* view = m_graph.tryGetFoldableView(
             forNode(node->child1()).m_value, node->arrayMode());
         if (view)
@@ -3799,6 +3800,22 @@
         clearForNode(node);
         break;
     }
+    case ResolveRope: {
+        JSValue childConst = forNode(node->child1()).value();
+        if (childConst && childConst.isString() && !asString(childConst)->isRope()) {
+            setConstant(node, *m_graph.freeze(childConst));
+            break;
+        }
+
+        if (!(forNode(node->child1()).m_type & ~SpecStringIdent)) {
+            m_state.setShouldTryConstantFolding(true);
+            setForNode(node, forNode(node->child1()));
+            break;
+        }
+
+        setTypeForNode(node, SpecString);
+        break;
+    }
     case ConstantStoragePointer: {
         clearForNode(node);
         break; 

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1338,14 +1338,15 @@
         return;
         
     case GetIndexedPropertyStorage:
-        if (node->arrayMode().type() == Array::String) {
-            def(PureValue(node, node->arrayMode().asWord()));
-            return;
-        }
+        ASSERT(node->arrayMode().type() != Array::String);
         read(MiscFields);
         def(HeapLocation(IndexedPropertyStorageLoc, MiscFields, node->child1()), LazyNode(node));
         return;
-        
+
+    case ResolveRope:
+        def(PureValue(node));
+        return;
+
     case GetTypedArrayByteOffset:
         read(MiscFields);
         def(HeapLocation(TypedArrayByteOffsetLoc, MiscFields, node->child1()), LazyNode(node));

Modified: trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -897,6 +897,15 @@
                 break;
             }
 
+            case ResolveRope: {
+                if (m_state.forNode(node->child1()).m_type & ~SpecStringIdent)
+                    break;
+
+                node->convertToIdentity();
+                changed = true;
+                break;
+            }
+
             case ToNumber:
             case CallNumberConstructor: {
                 if (m_state.forNode(node->child1()).m_type & ~SpecBytecodeNumber)

Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -501,6 +501,8 @@
         return true;
 
     case GetIndexedPropertyStorage:
+        return false;
+
     case GetByVal:
     case EnumeratorGetByVal:
         if (node->arrayMode().type() == Array::String)
@@ -507,6 +509,9 @@
             return true;
         return false;
 
+    case ResolveRope:
+        return true;
+
     case EnumeratorNextExtractMode:
     case EnumeratorNextExtractIndex:
         return false;

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1018,7 +1018,7 @@
         case StringCodePointAt: {
             // Currently we have no good way of refining these.
             ASSERT(node->arrayMode() == ArrayMode(Array::String, Array::Read));
-            blessArrayOperation(node->child1(), node->child2(), node->child3());
+            blessArrayOperation(node->child1(), node->child2(), node->child1()); // Rewrite child1 with ResolveRope.
             fixEdge<KnownStringUse>(node->child1());
             fixEdge<Int32Use>(node->child2());
             break;
@@ -1083,7 +1083,11 @@
                 break;
             }
 
-            blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
+            if (node->arrayMode().type() == Array::String) {
+                // Rewrite first child with ResolveRope.
+                blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 0));
+            } else
+                blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
             
             ArrayMode arrayMode = node->arrayMode();
             switch (arrayMode.type()) {
@@ -2206,6 +2210,7 @@
         case Upsilon:
         case EntrySwitch:
         case GetIndexedPropertyStorage:
+        case ResolveRope:
         case LastNodeType:
         case CheckTierUpInLoop:
         case CheckTierUpAtReturn:
@@ -3705,6 +3710,9 @@
                 m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
         }
         
+        if (arrayMode.type() == Array::String)
+            return m_insertionSet.insertNode(m_indexInBlock, SpecNone, ResolveRope, origin, Edge(array, KnownStringUse));
+
         return m_insertionSet.insertNode(
             m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
             OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1965,9 +1965,6 @@
     bool hasStorageChild() const
     {
         switch (op()) {
-        case StringCharAt:
-        case StringCharCodeAt:
-        case StringCodePointAt:
         case EnumeratorGetByVal:
         case GetByVal:
         case PutByValDirect:
@@ -2000,9 +1997,6 @@
     {
         ASSERT(hasStorageChild());
         switch (op()) {
-        case StringCharAt:
-        case StringCharCodeAt:
-        case StringCodePointAt:
         case EnumeratorGetByVal:
         case GetByVal:
             return 2;

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -251,6 +251,7 @@
     macro(Arrayify, NodeMustGenerate) \
     macro(ArrayifyToStructure, NodeMustGenerate) \
     macro(GetIndexedPropertyStorage, NodeResultStorage) \
+    macro(ResolveRope, NodeResultJS) \
     macro(ConstantStoragePointer, NodeResultStorage) \
     macro(GetGetter, NodeResultJS) \
     macro(GetSetter, NodeResultJS) \

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -2515,6 +2515,16 @@
     return string->value(globalObject).impl();
 }
 
+JSC_DEFINE_JIT_OPERATION(operationResolveRopeString, JSString*, (JSGlobalObject* globalObject, JSRopeString* string))
+{
+    VM& vm = globalObject->vm();
+    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
+    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
+
+    string->resolveRope(globalObject);
+    return string;
+}
+
 JSC_DEFINE_JIT_OPERATION(operationStringValueOf, JSString*, (JSGlobalObject* globalObject, EncodedJSValue encodedArgument))
 {
     VM& vm = globalObject->vm();
@@ -2685,7 +2695,7 @@
     String string = description->value(globalObject);
     RETURN_IF_EXCEPTION(scope, nullptr);
 
-    return Symbol::createWithDescription(vm, string);
+    return Symbol::createWithDescription(vm, WTFMove(string));
 }
 
 JSC_DEFINE_JIT_OPERATION(operationNewSymbolWithDescription, Symbol*, (JSGlobalObject* globalObject, EncodedJSValue encodedDescription))

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -36,6 +36,7 @@
 class DateInstance;
 class JSBigInt;
 class JSPropertyNameEnumerator;
+class JSRopeString;
 class OptimizingCallLinkInfo;
 struct UnlinkedStringJumpTable;
 
@@ -234,6 +235,7 @@
 JSC_DECLARE_JIT_OPERATION(operationEnsureContiguous, char*, (VM*, JSCell*));
 JSC_DECLARE_JIT_OPERATION(operationEnsureArrayStorage, char*, (VM*, JSCell*));
 JSC_DECLARE_JIT_OPERATION(operationResolveRope, StringImpl*, (JSGlobalObject*, JSString*));
+JSC_DECLARE_JIT_OPERATION(operationResolveRopeString, JSString*, (JSGlobalObject*, JSRopeString*));
 JSC_DECLARE_JIT_OPERATION(operationSingleCharacterString, JSString*, (VM*, int32_t));
 
 JSC_DECLARE_JIT_OPERATION(operationStringSubstr, JSCell*, (JSGlobalObject*, JSCell*, int32_t, int32_t));

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1078,6 +1078,10 @@
             break;
         }
 
+        case ResolveRope:
+            setPrediction(SpecString);
+            break;
+
         case CheckJSCast:
         case CheckNotJSCast:
             break;

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -320,6 +320,7 @@
     case DateGetTime:
     case DataViewGetInt:
     case DataViewGetFloat:
+    case ResolveRope:
         return true;
 
     case GetButterfly:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -2877,11 +2877,9 @@
 {
     SpeculateCellOperand string(this, node->child1());
     SpeculateStrictInt32Operand index(this, node->child2());
-    StorageOperand storage(this, node->child3());
 
     GPRReg stringReg = string.gpr();
     GPRReg indexReg = index.gpr();
-    GPRReg storageReg = storage.gpr();
     
     ASSERT(speculationChecked(m_state.forNode(node->child1()).m_type, SpecString));
 
@@ -2896,12 +2894,14 @@
     // Load the character into scratchReg
     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
 
-    m_jit.load8(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesOne, 0), scratchReg);
+    m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
+    m_jit.load8(MacroAssembler::BaseIndex(scratchReg, indexReg, MacroAssembler::TimesOne, 0), scratchReg);
     JITCompiler::Jump cont8Bit = m_jit.jump();
 
     is16Bit.link(&m_jit);
 
-    m_jit.load16(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesTwo, 0), scratchReg);
+    m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
+    m_jit.load16(MacroAssembler::BaseIndex(scratchReg, indexReg, MacroAssembler::TimesTwo, 0), scratchReg);
 
     cont8Bit.link(&m_jit);
 
@@ -2912,10 +2912,8 @@
 {
     SpeculateCellOperand base(this, m_graph.child(node, 0));
     SpeculateStrictInt32Operand property(this, m_graph.child(node, 1));
-    StorageOperand storage(this, m_graph.child(node, 2));
     GPRReg baseReg = base.gpr();
     GPRReg propertyReg = property.gpr();
-    GPRReg storageReg = storage.gpr();
 
     JSValueRegs resultRegs;
     DataFormat format;
@@ -2933,12 +2931,14 @@
     // Load the character into scratchReg
     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
 
-    m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne, 0), scratchReg);
+    m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
+    m_jit.load8(MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesOne, 0), scratchReg);
     JITCompiler::Jump cont8Bit = m_jit.jump();
 
     is16Bit.link(&m_jit);
 
-    m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
+    m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
+    m_jit.load16(MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
 
     JITCompiler::Jump bigCharacter =
         m_jit.branch32(MacroAssembler::Above, scratchReg, TrustedImm32(maxSingleCharacterString));
@@ -8355,29 +8355,35 @@
     GPRTemporary storage(this);
     GPRReg storageReg = storage.gpr();
     
-    switch (node->arrayMode().type()) {
-    case Array::String:
-        m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                m_jit.branchIfRopeStringImpl(storageReg),
-                this, operationResolveRope, storageReg, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseReg));
+    ASSERT(node->arrayMode().type() != Array::String);
 
-        m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg);
-        break;
+    auto typedArrayType = node->arrayMode().typedArrayType();
+    ASSERT_UNUSED(typedArrayType, isTypedView(typedArrayType));
 
-    default: {
-        auto typedArrayType = node->arrayMode().typedArrayType();
-        ASSERT_UNUSED(typedArrayType, isTypedView(typedArrayType));
+    m_jit.loadPtr(JITCompiler::Address(baseReg, JSArrayBufferView::offsetOfVector()), storageReg);
+    cageTypedArrayStorage(baseReg, storageReg);
+    storageResult(storageReg, node);
+}
 
-        m_jit.loadPtr(JITCompiler::Address(baseReg, JSArrayBufferView::offsetOfVector()), storageReg);
-        cageTypedArrayStorage(baseReg, storageReg);
-        break;
-    }
-    }
+void SpeculativeJIT::compileResolveRope(Node* node)
+{
+    SpeculateCellOperand base(this, node->child1());
+    GPRTemporary result(this);
 
-    storageResult(storageReg, node);
+    GPRReg baseGPR = base.gpr();
+    GPRReg resultGPR = result.gpr();
+
+    m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSString::offsetOfValue()), resultGPR);
+
+    CCallHelpers::JumpList slowCases;
+    slowCases.append(m_jit.branchIfRopeStringImpl(resultGPR));
+    m_jit.move(baseGPR, resultGPR);
+
+    addSlowPathGenerator(
+        slowPathCall(
+            slowCases,
+            this, operationResolveRopeString, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR));
+    cellResult(resultGPR, node);
 }
 
 void SpeculativeJIT::compileGetTypedArrayByteOffset(Node* node)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1437,6 +1437,7 @@
     void compileArithMinMax(Node*);
     void compileConstantStoragePointer(Node*);
     void compileGetIndexedPropertyStorage(Node*);
+    void compileResolveRope(Node*);
     JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR, GPRReg scratchGPR);
     JITCompiler::Jump jumpForTypedArrayIsDetachedIfOutOfBounds(Node*, GPRReg baseGPR, JITCompiler::Jump outOfBounds);
     void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR, GPRReg scratchGPR);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -3344,6 +3344,10 @@
         break;
     }
 
+    case ResolveRope:
+        compileResolveRope(node);
+        break;
+
     case ConstantStoragePointer: {
         compileConstantStoragePointer(node);
         break;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -4458,7 +4458,11 @@
         compileGetIndexedPropertyStorage(node);
         break;
     }
-        
+
+    case ResolveRope:
+        compileResolveRope(node);
+        break;
+
     case ConstantStoragePointer: {
         compileConstantStoragePointer(node);
         break;
@@ -6166,17 +6170,17 @@
     // And CheckArray also ensures that this String is not a rope.
     SpeculateCellOperand string(this, node->child1());
     SpeculateStrictInt32Operand index(this, node->child2());
-    StorageOperand storage(this, node->child3());
     GPRTemporary scratch1(this);
     GPRTemporary scratch2(this);
     GPRTemporary scratch3(this);
+    GPRTemporary scratch4(this);
 
     GPRReg stringGPR = string.gpr();
     GPRReg indexGPR = index.gpr();
-    GPRReg storageGPR = storage.gpr();
     GPRReg scratch1GPR = scratch1.gpr();
     GPRReg scratch2GPR = scratch2.gpr();
     GPRReg scratch3GPR = scratch3.gpr();
+    GPRReg scratch4GPR = scratch4.gpr();
 
     m_jit.loadPtr(CCallHelpers::Address(stringGPR, JSString::offsetOfValue()), scratch1GPR);
     m_jit.load32(CCallHelpers::Address(scratch1GPR, StringImpl::lengthMemoryOffset()), scratch2GPR);
@@ -6185,21 +6189,22 @@
     speculationCheck(Uncountable, JSValueRegs(), nullptr, m_jit.branch32(CCallHelpers::AboveOrEqual, indexGPR, scratch2GPR));
 
     // Load the character into scratch1GPR
+    m_jit.loadPtr(CCallHelpers::Address(scratch1GPR, StringImpl::dataOffset()), scratch4GPR);
     auto is16Bit = m_jit.branchTest32(CCallHelpers::Zero, CCallHelpers::Address(scratch1GPR, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
 
     CCallHelpers::JumpList done;
 
-    m_jit.load8(CCallHelpers::BaseIndex(storageGPR, indexGPR, CCallHelpers::TimesOne, 0), scratch1GPR);
+    m_jit.load8(CCallHelpers::BaseIndex(scratch4GPR, indexGPR, CCallHelpers::TimesOne, 0), scratch1GPR);
     done.append(m_jit.jump());
 
     is16Bit.link(&m_jit);
-    m_jit.load16(CCallHelpers::BaseIndex(storageGPR, indexGPR, CCallHelpers::TimesTwo, 0), scratch1GPR);
+    m_jit.load16(CCallHelpers::BaseIndex(scratch4GPR, indexGPR, CCallHelpers::TimesTwo, 0), scratch1GPR);
     // This is ok. indexGPR must be positive int32_t here and adding 1 never causes overflow if we treat indexGPR as uint32_t.
     m_jit.add32(CCallHelpers::TrustedImm32(1), indexGPR, scratch3GPR);
     done.append(m_jit.branch32(CCallHelpers::AboveOrEqual, scratch3GPR, scratch2GPR));
     m_jit.and32(CCallHelpers::TrustedImm32(0xfffffc00), scratch1GPR, scratch2GPR);
     done.append(m_jit.branch32(CCallHelpers::NotEqual, scratch2GPR, CCallHelpers::TrustedImm32(0xd800)));
-    m_jit.load16(CCallHelpers::BaseIndex(storageGPR, scratch3GPR, CCallHelpers::TimesTwo, 0), scratch3GPR);
+    m_jit.load16(CCallHelpers::BaseIndex(scratch4GPR, scratch3GPR, CCallHelpers::TimesTwo, 0), scratch3GPR);
     m_jit.and32(CCallHelpers::TrustedImm32(0xfffffc00), scratch3GPR, scratch2GPR);
     done.append(m_jit.branch32(CCallHelpers::NotEqual, scratch2GPR, CCallHelpers::TrustedImm32(0xdc00)));
     m_jit.lshift32(CCallHelpers::TrustedImm32(10), scratch1GPR);

Modified: trunk/Source/_javascript_Core/dfg/DFGTypeCheckHoistingPhase.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGTypeCheckHoistingPhase.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGTypeCheckHoistingPhase.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -283,6 +283,7 @@
                 case CheckArray:
                 case CheckDetached:
                 case GetIndexedPropertyStorage:
+                case ResolveRope:
                 case GetTypedArrayByteOffset:
                 case GetTypedArrayByteOffsetAsInt52:
                 case Phantom:
@@ -363,6 +364,7 @@
                 case GetArrayLength:
                 case GetTypedArrayLengthAsInt52:
                 case GetIndexedPropertyStorage:
+                case ResolveRope:
                 case Phantom:
                 case MovHint:
                 case MultiGetByOffset:

Modified: trunk/Source/_javascript_Core/dfg/DFGValidate.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -382,6 +382,9 @@
                         VALIDATE((node), inlineCallFrame->isVarargs());
                     break;
                 }
+                case GetIndexedPropertyStorage:
+                    VALIDATE((node), node->arrayMode().type() != Array::String);
+                    break;
                 case NewArray:
                     VALIDATE((node), node->vectorLengthHint() >= node->numChildren());
                     break;

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -289,6 +289,7 @@
     case BooleanToNumber:
     case HasIndexedProperty:
     case GetIndexedPropertyStorage:
+    case ResolveRope:
     case GetPropertyEnumerator:
     case EnumeratorNextUpdateIndexAndMode:
     case EnumeratorNextExtractMode:

Modified: trunk/Source/_javascript_Core/ftl/FTLCompile.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -58,7 +58,7 @@
     if (shouldDumpDisassembly() || vm.m_perBytecodeProfiler)
         state.proc->code().setDisassembler(makeUnique<B3::Air::Disassembler>());
 
-    if (!shouldDumpDisassembly() && !Options::asyncDisassembly() && !graph.compilation() && !state.proc->needsPCToOriginMap())
+    if (!shouldDumpDisassembly() && !verboseCompilationEnabled() && !Options::asyncDisassembly() && !graph.compilation() && !state.proc->needsPCToOriginMap())
         graph.freeDFGIRAfterLowering();
 
     {

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1015,6 +1015,9 @@
         case GetIndexedPropertyStorage:
             compileGetIndexedPropertyStorage();
             break;
+        case ResolveRope:
+            compileResolveRope();
+            break;
         case CheckArray:
             compileCheckArray();
             break;
@@ -4767,34 +4770,36 @@
     
     void compileGetIndexedPropertyStorage()
     {
-        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
         LValue cell = lowCell(m_node->child1());
         
-        if (m_node->arrayMode().type() == Array::String) {
-            LBasicBlock slowPath = m_out.newBlock();
-            LBasicBlock continuation = m_out.newBlock();
-
-            LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
-            ValueFromBlock fastResult = m_out.anchor(fastResultValue);
-            
-            m_out.branch(isRopeString(cell, m_node->child1()), rarely(slowPath), usually(continuation));
-            
-            LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
-            
-            ValueFromBlock slowResult = m_out.anchor(vmCall(pointerType(), operationResolveRope, weakPointer(globalObject), cell));
-            
-            m_out.jump(continuation);
-            
-            m_out.appendTo(continuation, lastNext);
-            
-            setStorage(m_out.loadPtr(m_out.phi(pointerType(), fastResult, slowResult), m_heaps.StringImpl_data));
-            return;
-        }
-
+        ASSERT(m_node->arrayMode().type() != Array::String);
         DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType()), m_node->arrayMode().typedArrayType());
         LValue vector = m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector);
         setStorage(caged(Gigacage::Primitive, vector, cell));
     }
+
+    void compileResolveRope()
+    {
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
+        LValue string = lowCell(m_node->child1());
+
+        LBasicBlock slowPath = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        ValueFromBlock fastResult = m_out.anchor(string);
+
+        m_out.branch(isRopeString(string, m_node->child1()), rarely(slowPath), usually(continuation));
+
+        LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
+
+        ValueFromBlock slowResult = m_out.anchor(vmCall(pointerType(), operationResolveRopeString, weakPointer(globalObject), string));
+
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+
+        setJSValue(m_out.phi(pointerType(), fastResult, slowResult));
+    }
     
     void compileCheckArray()
     {
@@ -8872,7 +8877,6 @@
     {
         LValue base = lowString(m_graph.child(m_node, 0));
         LValue index = lowInt32(m_graph.child(m_node, 1));
-        LValue storage = lowStorage(m_graph.child(m_node, 2));
             
         LBasicBlock fastPath = m_out.newBlock();
         LBasicBlock slowPath = m_out.newBlock();
@@ -8903,7 +8907,7 @@
         // https://bugs.webkit.org/show_bug.cgi?id=174924
         ValueFromBlock char8Bit = m_out.anchor(
             m_out.load8ZeroExt32(m_out.baseIndex(
-                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
+                m_heaps.characters8, m_out.loadPtr(stringImpl, m_heaps.StringImpl_data), m_out.zeroExtPtr(index),
                 provenValue(m_graph.child(m_node, 1)))));
         m_out.jump(bitsContinuation);
             
@@ -8911,7 +8915,7 @@
 
         LValue char16BitValue = m_out.load16ZeroExt32(
             m_out.baseIndex(
-                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
+                m_heaps.characters16, m_out.loadPtr(stringImpl, m_heaps.StringImpl_data), m_out.zeroExtPtr(index),
                 provenValue(m_graph.child(m_node, 1))));
         ValueFromBlock char16Bit = m_out.anchor(char16BitValue);
         m_out.branch(
@@ -8992,7 +8996,6 @@
 
         LValue base = lowString(m_node->child1());
         LValue index = lowInt32(m_node->child2());
-        LValue storage = lowStorage(m_node->child3());
         
         LValue stringImpl = m_out.loadPtr(base, m_heaps.JSString_value);
 
@@ -9013,7 +9016,7 @@
         // https://bugs.webkit.org/show_bug.cgi?id=174924
         ValueFromBlock char8Bit = m_out.anchor(
             m_out.load8ZeroExt32(m_out.baseIndex(
-                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
+                m_heaps.characters8, m_out.loadPtr(stringImpl, m_heaps.StringImpl_data), m_out.zeroExtPtr(index),
                 provenValue(m_node->child2()))));
         m_out.jump(continuation);
             
@@ -9021,7 +9024,7 @@
             
         ValueFromBlock char16Bit = m_out.anchor(
             m_out.load16ZeroExt32(m_out.baseIndex(
-                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
+                m_heaps.characters16, m_out.loadPtr(stringImpl, m_heaps.StringImpl_data), m_out.zeroExtPtr(index),
                 provenValue(m_node->child2()))));
         m_out.jump(continuation);
         
@@ -9043,7 +9046,6 @@
 
         LValue base = lowString(m_node->child1());
         LValue index = lowInt32(m_node->child2());
-        LValue storage = lowStorage(m_node->child3());
 
         LValue stringImpl = m_out.loadPtr(base, m_heaps.JSString_value);
         LValue length = m_out.load32NonNegative(stringImpl, m_heaps.StringImpl_length);
@@ -9061,12 +9063,12 @@
         // https://bugs.webkit.org/show_bug.cgi?id=174924
         ValueFromBlock char8Bit = m_out.anchor(
             m_out.load8ZeroExt32(m_out.baseIndex(
-                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
+                m_heaps.characters8, m_out.loadPtr(stringImpl, m_heaps.StringImpl_data), m_out.zeroExtPtr(index),
                 provenValue(m_node->child2()))));
         m_out.jump(continuation);
 
         m_out.appendTo(is16Bit, isLeadSurrogate);
-        LValue leadCharacter = m_out.load16ZeroExt32(m_out.baseIndex(m_heaps.characters16, storage, m_out.zeroExtPtr(index), provenValue(m_node->child2())));
+        LValue leadCharacter = m_out.load16ZeroExt32(m_out.baseIndex(m_heaps.characters16, m_out.loadPtr(stringImpl, m_heaps.StringImpl_data), m_out.zeroExtPtr(index), provenValue(m_node->child2())));
         ValueFromBlock char16Bit = m_out.anchor(leadCharacter);
         LValue nextIndex = m_out.add(index, m_out.int32One);
         m_out.branch(m_out.aboveOrEqual(nextIndex, length), unsure(continuation), unsure(isLeadSurrogate));
@@ -9079,7 +9081,7 @@
         JSValue nextIndexValue;
         if (indexValue && indexValue.isInt32() && indexValue.asInt32() != INT32_MAX)
             nextIndexValue = jsNumber(indexValue.asInt32() + 1);
-        LValue trailCharacter = m_out.load16ZeroExt32(m_out.baseIndex(m_heaps.characters16, storage, m_out.zeroExtPtr(nextIndex), nextIndexValue));
+        LValue trailCharacter = m_out.load16ZeroExt32(m_out.baseIndex(m_heaps.characters16, m_out.loadPtr(stringImpl, m_heaps.StringImpl_data), m_out.zeroExtPtr(nextIndex), nextIndexValue));
         m_out.branch(m_out.notEqual(m_out.bitAnd(trailCharacter, m_out.constInt32(0xfffffc00)), m_out.constInt32(0xdc00)), unsure(continuation), unsure(hasTrailSurrogate));
 
         m_out.appendTo(hasTrailSurrogate, continuation);

Modified: trunk/Source/_javascript_Core/jsc.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/jsc.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/jsc.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -277,6 +277,7 @@
 static JSC_DECLARE_HOST_FUNCTION(functionUseBigInt32);
 static JSC_DECLARE_HOST_FUNCTION(functionIsBigInt32);
 static JSC_DECLARE_HOST_FUNCTION(functionIsHeapBigInt);
+static JSC_DECLARE_HOST_FUNCTION(functionCreateNonRopeNonAtomString);
 
 static JSC_DECLARE_HOST_FUNCTION(functionPrintStdOut);
 static JSC_DECLARE_HOST_FUNCTION(functionPrintStdErr);
@@ -592,6 +593,8 @@
         addFunction(vm, "isBigInt32"_s, functionIsBigInt32, 1);
         addFunction(vm, "isHeapBigInt"_s, functionIsHeapBigInt, 1);
 
+        addFunction(vm, "createNonRopeNonAtomString"_s, functionCreateNonRopeNonAtomString, 1);
+
         addFunction(vm, "dumpTypesForAllVariables"_s, functionDumpTypesForAllVariables , 0);
 
         addFunction(vm, "drainMicrotasks"_s, functionDrainMicrotasks, 0);
@@ -2648,6 +2651,29 @@
     return JSValue::encode(jsBoolean(callFrame->argument(0).isHeapBigInt()));
 }
 
+JSC_DEFINE_HOST_FUNCTION(functionCreateNonRopeNonAtomString, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    String source = callFrame->argument(0).toWTFString(globalObject);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    if (source.isEmpty() || source.length() == 1)
+        return throwVMTypeError(globalObject, scope, "empty / one-length string can be always atom string"_s);
+
+    if (source.impl()->isAtom()) {
+        if (source.is8Bit())
+            source = StringImpl::create(source.characters8(), source.length());
+        else
+            source = StringImpl::create(source.characters16(), source.length());
+    }
+
+    RELEASE_ASSERT(!source.impl()->isAtom());
+
+    return JSValue::encode(jsString(vm, WTFMove(source)));
+}
+
 JSC_DEFINE_HOST_FUNCTION(functionCheckModuleSyntax, (JSGlobalObject* globalObject, CallFrame* callFrame))
 {
     VM& vm = globalObject->vm();

Modified: trunk/Source/_javascript_Core/runtime/HashMapImplInlines.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/HashMapImplInlines.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/HashMapImplInlines.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -93,7 +93,7 @@
 
     if (value.isString()) {
         auto scope = DECLARE_THROW_SCOPE(vm);
-        const String& wtfString = asString(value)->value(globalObject);
+        String wtfString = asString(value)->value(globalObject);
         if constexpr (expection == ExceptionExpectation::CanThrow)
             RETURN_IF_EXCEPTION(scope, UINT_MAX);
         else

Modified: trunk/Source/_javascript_Core/runtime/InternalFunction.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/InternalFunction.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/InternalFunction.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -82,7 +82,7 @@
 
 DEFINE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE, InternalFunction);
 
-const String& InternalFunction::name()
+String InternalFunction::name()
 {
     const String& name = m_originalName->tryGetValue();
     ASSERT(name); // m_originalName was built from a String, and hence, there is no rope to resolve.
@@ -89,7 +89,7 @@
     return name;
 }
 
-const String InternalFunction::displayName(VM& vm)
+String InternalFunction::displayName(VM& vm)
 {
     JSValue displayName = getDirect(vm, vm.propertyNames->displayName);
     
@@ -123,9 +123,9 @@
     return constructData;
 }
 
-const String InternalFunction::calculatedDisplayName(VM& vm)
+String InternalFunction::calculatedDisplayName(VM& vm)
 {
-    const String explicitName = displayName(vm);
+    String explicitName = displayName(vm);
     
     if (!explicitName.isEmpty())
         return explicitName;

Modified: trunk/Source/_javascript_Core/runtime/InternalFunction.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/InternalFunction.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/InternalFunction.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -48,9 +48,9 @@
 
     DECLARE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE);
 
-    JS_EXPORT_PRIVATE const String& name();
-    const String displayName(VM&);
-    const String calculatedDisplayName(VM&);
+    JS_EXPORT_PRIVATE String name();
+    String displayName(VM&);
+    String calculatedDisplayName(VM&);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
     { 

Modified: trunk/Source/_javascript_Core/runtime/JSBoundFunction.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/JSBoundFunction.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/JSBoundFunction.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -57,7 +57,7 @@
     JSImmutableButterfly* boundArgs() { return m_boundArgs.get(); } // DO NOT allow this array to be mutated!
     JSArray* boundArgsCopy(JSGlobalObject*);
     JSString* nameMayBeNull() { return m_nameMayBeNull.get(); }
-    const String& nameString()
+    String nameString()
     {
         if (!m_nameMayBeNull)
             return emptyString();

Modified: trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -839,7 +839,7 @@
         return NoPreference;
     }
 
-    StringImpl* hintString = asString(value)->value(globalObject).impl();
+    String hintString = asString(value)->value(globalObject);
     RETURN_IF_EXCEPTION(scope, NoPreference);
 
     if (WTF::equal(hintString, "default"))

Modified: trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -257,7 +257,7 @@
     RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
 
     scope.release();
-    promise->reject(globalObject, createError(globalObject, makeString("Could not import the module '", moduleNameString, "'.")));
+    promise->reject(globalObject, createError(globalObject, makeString("Could not import the module '", WTFMove(moduleNameString), "'.")));
     return promise;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSONObject.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -371,9 +371,9 @@
     }
 
     if (value.isString()) {
-        const String& string = asString(value)->value(m_globalObject);
+        String string = asString(value)->value(m_globalObject);
         RETURN_IF_EXCEPTION(scope, StringifyFailed);
-        builder.appendQuotedJSONString(string);
+        builder.appendQuotedJSONString(WTFMove(string));
         return StringifySucceeded;
     }
 

Modified: trunk/Source/_javascript_Core/runtime/JSPropertyNameEnumerator.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/JSPropertyNameEnumerator.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/JSPropertyNameEnumerator.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -193,7 +193,7 @@
                 break;
             if (index < endStructurePropertyIndex() && base->structureID() == cachedStructureID())
                 break;
-            auto id = Identifier::fromString(vm, name->value(globalObject));
+            auto id = name->toIdentifier(globalObject);
             RETURN_IF_EXCEPTION(scope, nullptr);
             if (base->hasEnumerableProperty(globalObject, id))
                 break;

Modified: trunk/Source/_javascript_Core/runtime/JSRemoteFunction.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/JSRemoteFunction.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/JSRemoteFunction.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -58,7 +58,7 @@
     JSObject* targetFunction() { return m_targetFunction.get(); }
     JSGlobalObject* targetGlobalObject() { return targetFunction()->globalObject(); }
     JSString* nameMayBeNull() const { return m_nameMayBeNull.get(); }
-    const String& nameString()
+    String nameString()
     {
         if (!m_nameMayBeNull)
             return emptyString();

Modified: trunk/Source/_javascript_Core/runtime/JSString.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/JSString.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/JSString.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -573,6 +573,10 @@
         return newString;
     }
 
+    // If nullOrExecForOOM is null, resolveRope() will be do nothing in the event of an OOM error.
+    // The rope value will remain a null string in that case.
+    JS_EXPORT_PRIVATE const String& resolveRope(JSGlobalObject* nullOrGlobalObjectForOOM) const;
+
 private:
     static JSRopeString* create(VM& vm, JSString* s1, JSString* s2)
     {
@@ -602,9 +606,6 @@
 
     friend JSValue jsStringFromRegisterArray(JSGlobalObject*, Register*, unsigned);
 
-    // If nullOrExecForOOM is null, resolveRope() will be do nothing in the event of an OOM error.
-    // The rope value will remain a null string in that case.
-    JS_EXPORT_PRIVATE const String& resolveRope(JSGlobalObject* nullOrGlobalObjectForOOM) const;
     template<typename Function> const String& resolveRopeWithFunction(JSGlobalObject* nullOrGlobalObjectForOOM, Function&&) const;
     JS_EXPORT_PRIVATE AtomString resolveRopeToAtomString(JSGlobalObject*) const;
     JS_EXPORT_PRIVATE RefPtr<AtomStringImpl> resolveRopeToExistingAtomString(JSGlobalObject*) const;

Modified: trunk/Source/_javascript_Core/runtime/Operations.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/Operations.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/Operations.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -103,9 +103,9 @@
         return JSRopeString::create(vm, jsString(vm, u1), s2);
 
     ASSERT(!s2->isRope());
-    const String& u2 = s2->value(globalObject);
+    String u2 = s2->value(globalObject);
     scope.assertNoException();
-    String newString = tryMakeString(u1, u2);
+    String newString = tryMakeString(u1, WTFMove(u2));
     if (!newString) {
         throwOutOfMemoryError(globalObject, scope);
         return nullptr;
@@ -136,9 +136,9 @@
         return JSRopeString::create(vm, s1, jsString(vm, u2));
 
     ASSERT(!s1->isRope());
-    const String& u1 = s1->value(globalObject);
+    String u1 = s1->value(globalObject);
     scope.assertNoException();
-    String newString = tryMakeString(u1, u2);
+    String newString = tryMakeString(WTFMove(u1), u2);
     if (!newString) {
         throwOutOfMemoryError(globalObject, scope);
         return nullptr;
@@ -309,7 +309,7 @@
     if (primValue.isString()) {
         String string = asString(primValue)->value(globalObject);
         RETURN_IF_EXCEPTION(scope, JSBigInt::ComparisonResult::Undefined);
-        JSValue bigIntValue = JSBigInt::stringToBigInt(globalObject, string);
+        JSValue bigIntValue = JSBigInt::stringToBigInt(globalObject, WTFMove(string));
         RETURN_IF_EXCEPTION(scope, JSBigInt::ComparisonResult::Undefined);
         if (!bigIntValue)
             return JSBigInt::ComparisonResult::Undefined;
@@ -349,7 +349,7 @@
     if (primValue.isString()) {
         String string = asString(primValue)->value(globalObject);
         RETURN_IF_EXCEPTION(scope, JSBigInt::ComparisonResult::Undefined);
-        JSValue bigIntValue = JSBigInt::stringToBigInt(globalObject, string);
+        JSValue bigIntValue = JSBigInt::stringToBigInt(globalObject, WTFMove(string));
         RETURN_IF_EXCEPTION(scope, JSBigInt::ComparisonResult::Undefined);
         if (!bigIntValue)
             return JSBigInt::ComparisonResult::Undefined;

Modified: trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h	2022-04-11 04:57:33 UTC (rev 292697)
@@ -232,7 +232,7 @@
     String input = string->value(globalObject);
     RETURN_IF_EXCEPTION(scope, { });
 
-    RELEASE_AND_RETURN(scope, createRegExpMatchesArray(vm, globalObject, string, input, regExp, startOffset, ignoredResult));
+    RELEASE_AND_RETURN(scope, createRegExpMatchesArray(vm, globalObject, string, WTFMove(input), regExp, startOffset, ignoredResult));
 }
 JSArray* createEmptyRegExpMatchesArray(JSGlobalObject*, JSString*, RegExp*);
 Structure* createRegExpMatchesArrayStructure(VM&, JSGlobalObject*);

Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -709,7 +709,7 @@
         RETURN_IF_EXCEPTION(scope, nullptr);
         String source = thisValue->value(globalObject);
         RETURN_IF_EXCEPTION(scope, nullptr);
-        RELEASE_AND_RETURN(scope, removeUsingRegExpSearch(vm, globalObject, thisValue, source, regExp));
+        RELEASE_AND_RETURN(scope, removeUsingRegExpSearch(vm, globalObject, thisValue, WTFMove(source), regExp));
     }
 
     CallData callData;
@@ -1484,7 +1484,7 @@
     String lowercasedString = s.convertToLowercaseWithoutLocale();
     if (lowercasedString.impl() == s.impl())
         return JSValue::encode(sVal);
-    RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, lowercasedString)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, WTFMove(lowercasedString))));
 }
 
 JSC_DEFINE_HOST_FUNCTION(stringProtoFuncToUpperCase, (JSGlobalObject* globalObject, CallFrame* callFrame))
@@ -1502,7 +1502,7 @@
     String uppercasedString = s.convertToUppercaseWithoutLocale();
     if (uppercasedString.impl() == s.impl())
         return JSValue::encode(sVal);
-    RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, uppercasedString)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, WTFMove(uppercasedString))));
 }
 
 JSC_DEFINE_HOST_FUNCTION(stringProtoFuncLocaleCompare, (JSGlobalObject* globalObject, CallFrame* callFrame))

Modified: trunk/Source/_javascript_Core/runtime/SymbolConstructor.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/runtime/SymbolConstructor.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/runtime/SymbolConstructor.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -105,7 +105,7 @@
     String string = stringKey->value(globalObject);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
 
-    return JSValue::encode(Symbol::create(vm, vm.symbolRegistry().symbolForKey(string)));
+    return JSValue::encode(Symbol::create(vm, vm.symbolRegistry().symbolForKey(WTFMove(string))));
 }
 
 const ASCIILiteral SymbolKeyForTypeError { "Symbol.keyFor requires that the first argument be a symbol"_s };

Modified: trunk/Source/_javascript_Core/tools/JSDollarVM.cpp (292696 => 292697)


--- trunk/Source/_javascript_Core/tools/JSDollarVM.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/_javascript_Core/tools/JSDollarVM.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -3150,7 +3150,7 @@
     String functionText = asString(callFrame->argument(0))->value(globalObject);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
 
-    SourceCode source = makeSource(functionText, { });
+    SourceCode source = makeSource(WTFMove(functionText), { });
     JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(vm, "foo"_s), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), globalObject);
 
     return JSValue::encode(func);

Modified: trunk/Source/WebCore/ChangeLog (292696 => 292697)


--- trunk/Source/WebCore/ChangeLog	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/WebCore/ChangeLog	2022-04-11 04:57:33 UTC (rev 292697)
@@ -1,3 +1,13 @@
+2022-04-10  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] DFG / FTL should be aware of JSString's String replacement
+        https://bugs.webkit.org/show_bug.cgi?id=238918
+
+        Reviewed by Saam Barati.
+
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::JSDOMWindowBase::reportViolationForUnsafeEval):
+
 2022-04-10  Chris Dumez  <cdu...@apple.com>
 
         Finish porting code base to String::fromLatin1() and make String(const char*) private

Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp (292696 => 292697)


--- trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp	2022-04-11 04:40:11 UTC (rev 292696)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp	2022-04-11 04:57:33 UTC (rev 292697)
@@ -272,7 +272,10 @@
     if (!contentSecurityPolicy)
         return;
 
-    contentSecurityPolicy->allowEval(object, LogToConsole::No, source ? source->tryGetValue() : StringView());
+    String sourceString;
+    if (source)
+        sourceString = source->tryGetValue();
+    contentSecurityPolicy->allowEval(object, LogToConsole::No, sourceString);
 }
 
 void JSDOMWindowBase::willRemoveFromWindowProxy()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to