Title: [285525] trunk
Revision
285525
Author
sbar...@apple.com
Date
2021-11-09 12:49:41 -0800 (Tue, 09 Nov 2021)

Log Message

When inlining NewSymbol in the DFG don't universally call ToString on the input
https://bugs.webkit.org/show_bug.cgi?id=232754

Reviewed by Robin Morisset.

JSTests:

* stress/inline-new-symbol-dfg-undefined-first-arg.js: Added.
(assert):
(foo):

Source/_javascript_Core:

When inlining Symbol(x) in the DFG, we were always calling ToString on x.
However, this is wrong spec wise. If x is undefined, the symbol should
produce a description value of `undefined`, but calling ToString on x was causing
us to produce a description with the string `"undefined"`.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGMayExit.cpp:
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewSymbol):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewSymbol):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (285524 => 285525)


--- trunk/JSTests/ChangeLog	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/JSTests/ChangeLog	2021-11-09 20:49:41 UTC (rev 285525)
@@ -1,3 +1,14 @@
+2021-11-09  Saam Barati  <sbar...@apple.com>
+
+        When inlining NewSymbol in the DFG don't universally call ToString on the input
+        https://bugs.webkit.org/show_bug.cgi?id=232754
+
+        Reviewed by Robin Morisset.
+
+        * stress/inline-new-symbol-dfg-undefined-first-arg.js: Added.
+        (assert):
+        (foo):
+
 2021-11-09  Angelos Oikonomopoulos  <ange...@igalia.com>
 
         Unskip array-buffer-view-watchpoint-can-be-fired-in-really-add-in-dfg on ARM

Added: trunk/JSTests/stress/inline-new-symbol-dfg-undefined-first-arg.js (0 => 285525)


--- trunk/JSTests/stress/inline-new-symbol-dfg-undefined-first-arg.js	                        (rev 0)
+++ trunk/JSTests/stress/inline-new-symbol-dfg-undefined-first-arg.js	2021-11-09 20:49:41 UTC (rev 285525)
@@ -0,0 +1,13 @@
+function assert(b) {
+    if (!b)
+        throw new Error;
+}
+
+function foo(arg) {
+    return Symbol(arg);
+}
+noInline(foo);
+
+for (let i = 0; i < 10000; ++i) {
+    assert(foo(undefined).description === undefined);
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (285524 => 285525)


--- trunk/Source/_javascript_Core/ChangeLog	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-11-09 20:49:41 UTC (rev 285525)
@@ -1,3 +1,35 @@
+2021-11-09  Saam Barati  <sbar...@apple.com>
+
+        When inlining NewSymbol in the DFG don't universally call ToString on the input
+        https://bugs.webkit.org/show_bug.cgi?id=232754
+
+        Reviewed by Robin Morisset.
+
+        When inlining Symbol(x) in the DFG, we were always calling ToString on x.
+        However, this is wrong spec wise. If x is undefined, the symbol should
+        produce a description value of `undefined`, but calling ToString on x was causing
+        us to produce a description with the string `"undefined"`.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGClobbersExitState.cpp:
+        (JSC::DFG::clobbersExitState):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGMayExit.cpp:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewSymbol):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewSymbol):
+
 2021-11-09  Yusuke Suzuki  <ysuz...@apple.com>
 
         Unreviewed, suppress scope check failures on Debug JSC tests

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2021-11-09 20:49:41 UTC (rev 285525)
@@ -2888,6 +2888,8 @@
     }
 
     case NewSymbol: {
+        if (node->child1() && node->child1().useKind() != StringUse)
+            clobberWorld();
         setForNode(node, m_vm.symbolStructure.get());
         break;
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2021-11-09 20:49:41 UTC (rev 285525)
@@ -4169,7 +4169,7 @@
         if (argumentCountIncludingThis <= 1)
             resultNode = addToGraph(NewSymbol);
         else
-            resultNode = addToGraph(NewSymbol, addToGraph(ToString, get(virtualRegisterForArgumentIncludingThis(1, registerOffset))));
+            resultNode = addToGraph(NewSymbol, get(virtualRegisterForArgumentIncludingThis(1, registerOffset)));
 
         set(result, resultNode);
         return true;

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2021-11-09 20:49:41 UTC (rev 285525)
@@ -1732,12 +1732,19 @@
         }
     }
 
+    case NewSymbol:
+        if (!node->child1() || node->child1().useKind() == StringUse) {
+            read(HeapObjectCount);
+            write(HeapObjectCount);
+        } else
+            clobberTop();
+        return;
+
     case NewObject:
     case NewGenerator:
     case NewAsyncGenerator:
     case NewInternalFieldObject:
     case NewRegexp:
-    case NewSymbol:
     case NewStringObject:
     case PhantomNewObject:
     case MaterializeNewObject:

Modified: trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp	2021-11-09 20:49:41 UTC (rev 285525)
@@ -59,7 +59,6 @@
     case NewAsyncGenerator:
     case NewInternalFieldObject:
     case NewRegexp:
-    case NewSymbol:
     case NewStringObject:
     case PhantomNewObject:
     case MaterializeNewObject:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2021-11-09 20:49:41 UTC (rev 285525)
@@ -1637,8 +1637,11 @@
         }
 
         case NewSymbol: {
-            if (node->child1())
-                fixEdge<KnownStringUse>(node->child1());
+            if (node->child1() && node->child1()->shouldSpeculateString())
+                fixEdge<StringUse>(node->child1());
+
+            if (!node->child1() || node->child1().useKind() == StringUse)
+                node->clearFlags(NodeMustGenerate);
             break;
         }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp	2021-11-09 20:49:41 UTC (rev 285525)
@@ -133,7 +133,6 @@
     case NewAsyncFunction:
     case NewAsyncGeneratorFunction:
     case NewStringObject:
-    case NewSymbol:
     case NewInternalFieldObject:
     case NewRegexp:
     case ToNumber:

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2021-11-09 20:49:41 UTC (rev 285525)
@@ -376,7 +376,7 @@
     macro(NewInternalFieldObject, NodeResultJS) \
     macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
     macro(NewRegexp, NodeResultJS) \
-    macro(NewSymbol, NodeResultJS) \
+    macro(NewSymbol, NodeResultJS | NodeMustGenerate) \
     macro(NewStringObject, NodeResultJS) \
     /* Rest Parameter */\
     macro(GetRestLength, NodeResultInt32) \

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-11-09 20:49:41 UTC (rev 285525)
@@ -2710,7 +2710,7 @@
     return Symbol::create(vm);
 }
 
-JSC_DEFINE_JIT_OPERATION(operationNewSymbolWithDescription, Symbol*, (JSGlobalObject* globalObject, JSString* description))
+JSC_DEFINE_JIT_OPERATION(operationNewSymbolWithStringDescription, Symbol*, (JSGlobalObject* globalObject, JSString* description))
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -2723,6 +2723,23 @@
     return Symbol::createWithDescription(vm, string);
 }
 
+JSC_DEFINE_JIT_OPERATION(operationNewSymbolWithDescription, Symbol*, (JSGlobalObject* globalObject, EncodedJSValue encodedDescription))
+{
+    VM& vm = globalObject->vm();
+    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
+    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSValue description = JSValue::decode(encodedDescription);
+    if (description.isUndefined())
+        return Symbol::create(vm);
+
+    String string = description.toWTFString(globalObject);
+    RETURN_IF_EXCEPTION(scope, nullptr);
+
+    return Symbol::createWithDescription(vm, string);
+}
+
 JSC_DEFINE_JIT_OPERATION(operationNewStringObject, JSCell*, (VM* vmPointer, JSString* string, Structure* structure))
 {
     VM& vm = *vmPointer;

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2021-11-09 20:49:41 UTC (rev 285525)
@@ -264,7 +264,8 @@
 JSC_DECLARE_JIT_OPERATION(operationParseIntGeneric, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, int32_t));
 
 JSC_DECLARE_JIT_OPERATION(operationNewSymbol, Symbol*, (VM*));
-JSC_DECLARE_JIT_OPERATION(operationNewSymbolWithDescription, Symbol*, (JSGlobalObject*, JSString*));
+JSC_DECLARE_JIT_OPERATION(operationNewSymbolWithStringDescription, Symbol*, (JSGlobalObject*, JSString*));
+JSC_DECLARE_JIT_OPERATION(operationNewSymbolWithDescription, Symbol*, (JSGlobalObject*, EncodedJSValue));
 JSC_DECLARE_JIT_OPERATION(operationNewStringObject, JSCell*, (VM*, JSString*, Structure*));
 JSC_DECLARE_JIT_OPERATION(operationToStringOnCell, JSString*, (JSGlobalObject*, JSCell*));
 JSC_DECLARE_JIT_OPERATION(operationToString, JSString*, (JSGlobalObject*, EncodedJSValue));

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (285524 => 285525)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-11-09 20:49:41 UTC (rev 285525)
@@ -11142,15 +11142,26 @@
     }
 
 
-    ASSERT(node->child1().useKind() == KnownStringUse);
-    SpeculateCellOperand operand(this, node->child1());
+    if (node->child1().useKind() == StringUse) {
+        SpeculateCellOperand operand(this, node->child1());
+        GPRReg stringGPR = operand.gpr();
+        speculateString(node->child1(), stringGPR);
 
-    GPRReg stringGPR = operand.gpr();
+        flushRegisters();
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+        callOperation(operationNewSymbolWithStringDescription, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), stringGPR);
+        m_jit.exceptionCheck();
+        cellResult(resultGPR, node);
+        return;
+    }
 
+    JSValueOperand operand(this, node->child1());
+    JSValueRegs inputRegs = operand.jsValueRegs();
     flushRegisters();
     GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
-    callOperation(operationNewSymbolWithDescription, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), stringGPR);
+    callOperation(operationNewSymbolWithDescription, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), inputRegs);
     m_jit.exceptionCheck();
     cellResult(resultGPR, node);
 }

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (285524 => 285525)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-11-09 20:44:59 UTC (rev 285524)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-11-09 20:49:41 UTC (rev 285525)
@@ -7473,8 +7473,11 @@
             setJSValue(vmCall(pointerType(), operationNewSymbol, m_vmValue));
             return;
         }
-        ASSERT(m_node->child1().useKind() == KnownStringUse);
-        setJSValue(vmCall(pointerType(), operationNewSymbolWithDescription, weakPointer(globalObject), lowString(m_node->child1())));
+
+        if (m_node->child1().useKind() == StringUse)
+            setJSValue(vmCall(pointerType(), operationNewSymbolWithStringDescription, weakPointer(globalObject), lowString(m_node->child1())));
+        else
+            setJSValue(vmCall(pointerType(), operationNewSymbolWithDescription, weakPointer(globalObject), lowJSValue(m_node->child1())));
     }
 
     void compileNewArray()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to