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()