Changeset 182433 in webkit


Ignore:
Timestamp:
Apr 6, 2015 12:07:12 PM (9 years ago)
Author:
Yusuke Suzuki
Message:

[ES6] DFG and FTL should be aware of that StringConstructor behavior for symbols becomes different from ToString
https://bugs.webkit.org/show_bug.cgi?id=143424

Reviewed by Geoffrey Garen.

In ES6, StringConstructor behavior becomes different from ToString abstract operations in the spec. (and JSValue::toString).

ToString(symbol) throws a type error.
However, String(symbol) produces SymbolDescriptiveString(symbol).

So, in DFG and FTL phase, they should not inline StringConstructor to ToString.

Now, in the template literals patch, ToString DFG operation is planned to be used.
And current ToString behavior is aligned to the spec (and JSValue::toString) and it's better.
So intead of changing ToString behavior, this patch adds CallStringConstructor operation into DFG and FTL.
In CallStringConstructor, all behavior in DFG analysis is the same.
Only the difference from ToString is, when calling DFG operation functions, it calls
operationCallStringConstructorOnCell and operationCallStringConstructor instead of
operationToStringOnCell and operationToString.

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
(JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
(JSC::DFG::FixupPhase::fixupToString): Deleted.

  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnCell):
(JSC::DFG::SpeculativeJIT::compileToStringOnCell): Deleted.

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStructureRegistrationPhase.cpp:

(JSC::DFG::StructureRegistrationPhase::run):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileToStringOrCallStringConstructor):
(JSC::FTL::LowerDFGToLLVM::compileToString): Deleted.

  • runtime/StringConstructor.cpp:

(JSC::stringConstructor):
(JSC::callStringConstructor):

  • runtime/StringConstructor.h:
  • tests/stress/symbol-and-string-constructor.js: Added.

(performString):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r182406 r182433  
     12015-04-06  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [ES6] DFG and FTL should be aware of that StringConstructor behavior for symbols becomes different from ToString
     4        https://bugs.webkit.org/show_bug.cgi?id=143424
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        In ES6, StringConstructor behavior becomes different from ToString abstract operations in the spec. (and JSValue::toString).
     9
     10        ToString(symbol) throws a type error.
     11        However, String(symbol) produces SymbolDescriptiveString(symbol).
     12
     13        So, in DFG and FTL phase, they should not inline StringConstructor to ToString.
     14
     15        Now, in the template literals patch, ToString DFG operation is planned to be used.
     16        And current ToString behavior is aligned to the spec (and JSValue::toString) and it's better.
     17        So intead of changing ToString behavior, this patch adds CallStringConstructor operation into DFG and FTL.
     18        In CallStringConstructor, all behavior in DFG analysis is the same.
     19        Only the difference from ToString is, when calling DFG operation functions, it calls
     20        operationCallStringConstructorOnCell and operationCallStringConstructor instead of
     21        operationToStringOnCell and operationToString.
     22
     23        * dfg/DFGAbstractInterpreterInlines.h:
     24        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     25        * dfg/DFGBackwardsPropagationPhase.cpp:
     26        (JSC::DFG::BackwardsPropagationPhase::propagate):
     27        * dfg/DFGByteCodeParser.cpp:
     28        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
     29        * dfg/DFGClobberize.h:
     30        (JSC::DFG::clobberize):
     31        * dfg/DFGDoesGC.cpp:
     32        (JSC::DFG::doesGC):
     33        * dfg/DFGFixupPhase.cpp:
     34        (JSC::DFG::FixupPhase::fixupNode):
     35        (JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
     36        (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
     37        (JSC::DFG::FixupPhase::fixupToString): Deleted.
     38        * dfg/DFGNodeType.h:
     39        * dfg/DFGOperations.cpp:
     40        * dfg/DFGOperations.h:
     41        * dfg/DFGPredictionPropagationPhase.cpp:
     42        (JSC::DFG::PredictionPropagationPhase::propagate):
     43        * dfg/DFGSafeToExecute.h:
     44        (JSC::DFG::safeToExecute):
     45        * dfg/DFGSpeculativeJIT.cpp:
     46        (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnCell):
     47        (JSC::DFG::SpeculativeJIT::compileToStringOnCell): Deleted.
     48        * dfg/DFGSpeculativeJIT.h:
     49        * dfg/DFGSpeculativeJIT32_64.cpp:
     50        (JSC::DFG::SpeculativeJIT::compile):
     51        * dfg/DFGSpeculativeJIT64.cpp:
     52        (JSC::DFG::SpeculativeJIT::compile):
     53        * dfg/DFGStructureRegistrationPhase.cpp:
     54        (JSC::DFG::StructureRegistrationPhase::run):
     55        * ftl/FTLCapabilities.cpp:
     56        (JSC::FTL::canCompile):
     57        * ftl/FTLLowerDFGToLLVM.cpp:
     58        (JSC::FTL::LowerDFGToLLVM::compileNode):
     59        (JSC::FTL::LowerDFGToLLVM::compileToStringOrCallStringConstructor):
     60        (JSC::FTL::LowerDFGToLLVM::compileToString): Deleted.
     61        * runtime/StringConstructor.cpp:
     62        (JSC::stringConstructor):
     63        (JSC::callStringConstructor):
     64        * runtime/StringConstructor.h:
     65        * tests/stress/symbol-and-string-constructor.js: Added.
     66        (performString):
     67
    1682015-04-06  Yusuke Suzuki  <utatane.tea@gmail.com>
    269
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r181993 r182433  
    12621262    }
    12631263       
    1264     case ToString: {
     1264    case ToString:
     1265    case CallStringConstructor: {
    12651266        switch (node->child1().useKind()) {
    12661267        case StringObjectUse:
  • trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp

    r181993 r182433  
    346346        }
    347347           
    348         case ToString: {
     348        case ToString:
     349        case CallStringConstructor: {
    349350            node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther);
    350351            break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r182294 r182433  
    21782178            result = jsConstant(m_vm->smallStrings.emptyString());
    21792179        else
    2180             result = addToGraph(ToString, get(virtualRegisterForArgument(1, registerOffset)));
     2180            result = addToGraph(CallStringConstructor, get(virtualRegisterForArgument(1, registerOffset)));
    21812181       
    21822182        if (kind == CodeForConstruct)
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r182213 r182433  
    898898       
    899899    case ToString:
     900    case CallStringConstructor:
    900901        switch (node->child1().useKind()) {
    901902        case StringObjectUse:
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r181993 r182433  
    144144    case ToPrimitive:
    145145    case ToString:
     146    case CallStringConstructor:
    146147    case In:
    147148    case Jump:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r182114 r182433  
    768768        }
    769769           
    770         case ToString: {
    771             fixupToString(node);
     770        case ToString:
     771        case CallStringConstructor: {
     772            fixupToStringOrCallStringConstructor(node);
    772773            break;
    773774        }
     
    13641365    }
    13651366   
    1366     void fixupToString(Node* node)
     1367    void fixupToStringOrCallStringConstructor(Node* node)
    13671368    {
    13681369        if (node->child1()->shouldSpeculateString()) {
     
    14251426           
    14261427            fixupToPrimitive(toPrimitive);
    1427             fixupToString(toString);
     1428            fixupToStringOrCallStringConstructor(toString);
    14281429           
    14291430            right.setNode(toString);
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r181993 r182433  
    262262    macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
    263263    macro(ToString, NodeResultJS | NodeMustGenerate) \
     264    macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
    264265    macro(NewStringObject, NodeResultJS) \
    265266    macro(MakeRope, NodeResultJS) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r182057 r182433  
    10071007}
    10081008
     1009JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
     1010{
     1011    VM& vm = exec->vm();
     1012    NativeCallFrameTracer tracer(&vm, exec);
     1013
     1014    return stringConstructor(exec, cell);
     1015}
     1016
     1017JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
     1018{
     1019    VM& vm = exec->vm();
     1020    NativeCallFrameTracer tracer(&vm, exec);
     1021
     1022    return stringConstructor(exec, JSValue::decode(value));
     1023}
     1024
    10091025JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
    10101026{
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r181993 r182433  
    122122JSCell* JIT_OPERATION operationToStringOnCell(ExecState*, JSCell*);
    123123JSCell* JIT_OPERATION operationToString(ExecState*, EncodedJSValue);
     124JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState*, JSCell*);
     125JSCell* JIT_OPERATION operationCallStringConstructor(ExecState*, EncodedJSValue);
    124126JSCell* JIT_OPERATION operationMakeRope2(ExecState*, JSString*, JSString*);
    125127JSCell* JIT_OPERATION operationMakeRope3(ExecState*, JSString*, JSString*, JSString*);
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r181993 r182433  
    481481        }
    482482        case StringCharAt:
     483        case CallStringConstructor:
    483484        case ToString:
    484485        case MakeRope: {
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r181993 r182433  
    220220    case ToPrimitive:
    221221    case ToString:
     222    case CallStringConstructor:
    222223    case NewStringObject:
    223224    case MakeRope:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r182098 r182433  
    48494849}
    48504850
    4851 void SpeculativeJIT::compileToStringOnCell(Node* node)
     4851void SpeculativeJIT::compileToStringOrCallStringConstructorOnCell(Node* node)
    48524852{
    48534853    SpeculateCellOperand op1(this, node->child1());
     
    49074907            needCall.link(&m_jit);
    49084908        }
    4909         callOperation(operationToStringOnCell, resultGPR, op1GPR);
     4909        if (node->op() == ToString)
     4910            callOperation(operationToStringOnCell, resultGPR, op1GPR);
     4911        else {
     4912            ASSERT(node->op() == CallStringConstructor);
     4913            callOperation(operationCallStringConstructorOnCell, resultGPR, op1GPR);
     4914        }
    49104915        if (done.isSet())
    49114916            done.link(&m_jit);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r181993 r182433  
    21392139    void emitSwitch(Node*);
    21402140   
    2141     void compileToStringOnCell(Node*);
     2141    void compileToStringOrCallStringConstructorOnCell(Node*);
    21422142    void compileNewStringObject(Node*);
    21432143   
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r182001 r182433  
    30993099    }
    31003100       
    3101     case ToString: {
     3101    case ToString:
     3102    case CallStringConstructor: {
    31023103        if (node->child1().useKind() == UntypedUse) {
    31033104            JSValueOperand op1(this, node->child1());
     
    31193120                slowPath2.link(&m_jit);
    31203121            }
    3121             callOperation(operationToString, resultGPR, op1TagGPR, op1PayloadGPR);
     3122            if (op == ToString)
     3123                callOperation(operationToString, resultGPR, op1TagGPR, op1PayloadGPR);
     3124            else {
     3125                ASSERT(op == CallStringConstructor);
     3126                callOperation(operationCallStringConstructor, resultGPR, op1TagGPR, op1PayloadGPR);
     3127            }
    31223128            if (done.isSet())
    31233129                done.link(&m_jit);
     
    31263132        }
    31273133       
    3128         compileToStringOnCell(node);
     3134        compileToStringOrCallStringConstructorOnCell(node);
    31293135        break;
    31303136    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r181993 r182433  
    31863186    }
    31873187       
    3188     case ToString: {
     3188    case ToString:
     3189    case CallStringConstructor: {
    31893190        if (node->child1().useKind() == UntypedUse) {
    31903191            JSValueOperand op1(this, node->child1());
     
    32053206                slowPath2.link(&m_jit);
    32063207            }
    3207             callOperation(operationToString, resultGPR, op1GPR);
     3208            if (op == ToString)
     3209                callOperation(operationToString, resultGPR, op1GPR);
     3210            else {
     3211                ASSERT(op == CallStringConstructor);
     3212                callOperation(operationCallStringConstructor, resultGPR, op1GPR);
     3213            }
    32083214            if (done.isSet())
    32093215                done.link(&m_jit);
     
    32123218        }
    32133219       
    3214         compileToStringOnCell(node);
     3220        compileToStringOrCallStringConstructorOnCell(node);
    32153221        break;
    32163222    }
  • trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp

    r181993 r182433  
    112112                   
    113113                case ToString:
     114                case CallStringConstructor:
    114115                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
    115116                    break;
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r181993 r182433  
    147147    case GetArgumentCount:
    148148    case ToString:
     149    case CallStringConstructor:
    149150    case MakeRope:
    150151    case NewArrayWithSize:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r182009 r182433  
    640640            break;
    641641        case ToString:
    642             compileToString();
     642        case CallStringConstructor:
     643            compileToStringOrCallStringConstructor();
    643644            break;
    644645        case ToPrimitive:
     
    32893290    }
    32903291   
    3291     void compileToString()
     3292    void compileToStringOrCallStringConstructor()
    32923293    {
    32933294        switch (m_node->child1().useKind()) {
     
    33573358            LValue operation;
    33583359            if (m_node->child1().useKind() == CellUse)
    3359                 operation = m_out.operation(operationToStringOnCell);
     3360                operation = m_out.operation(m_node->op() == ToString ? operationToStringOnCell : operationCallStringConstructorOnCell);
    33603361            else
    3361                 operation = m_out.operation(operationToString);
     3362                operation = m_out.operation(m_node->op() == ToString ? operationToString : operationCallStringConstructor);
    33623363            ValueFromBlock convertedResult = m_out.anchor(vmCall(operation, m_callFrame, value));
    33633364            m_out.jump(continuation);
  • trunk/Source/JavaScriptCore/runtime/StringConstructor.cpp

    r179429 r182433  
    107107}
    108108
     109JSCell* stringConstructor(ExecState* exec, JSValue argument)
     110{
     111    if (argument.isSymbol())
     112        return jsNontrivialString(exec, asSymbol(argument)->descriptiveString());
     113    return argument.toString(exec);
     114}
     115
    109116static EncodedJSValue JSC_HOST_CALL callStringConstructor(ExecState* exec)
    110117{
    111118    if (!exec->argumentCount())
    112119        return JSValue::encode(jsEmptyString(exec));
    113     JSValue argument = exec->uncheckedArgument(0);
    114     if (argument.isSymbol())
    115         return JSValue::encode(jsString(exec, asSymbol(argument)->descriptiveString()));
    116     return JSValue::encode(argument.toString(exec));
     120    return JSValue::encode(stringConstructor(exec, exec->uncheckedArgument(0)));
    117121}
    118122
  • trunk/Source/JavaScriptCore/runtime/StringConstructor.h

    r173269 r182433  
    5757    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    5858};
    59    
     59
    6060JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t);
     61JSCell* stringConstructor(ExecState*, JSValue);
    6162
    6263} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.