Changeset 195938 in webkit


Ignore:
Timestamp:
Jan 31, 2016 3:05:10 PM (8 years ago)
Author:
Yusuke Suzuki
Message:

Should not predict OtherObj for ToThis with primitive types under strict mode
https://bugs.webkit.org/show_bug.cgi?id=153544

Reviewed by Filip Pizlo.

Currently, ToThis predicates OtherObj for primitive values.
But it's not true in strict mode.
In strict mode, ToThis does nothing on primitive values.

In this patch, we

  1. fix prediction. Handles primitive types in strict mode. And we also handles StringObject.
  2. convert it to Identity if the argument should be predicted as primitive types.

This optimization is important to implement Primitive.prototype.methods[1].
Otherwise, we always got BadType OSR exits.

[1]: https://bugs.webkit.org/show_bug.cgi?id=143889

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupToThis):

  • dfg/DFGPredictionPropagationPhase.cpp:

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

  • tests/stress/to-this-boolean.js: Added.

(Boolean.prototype.negate):
(Boolean.prototype.negate2):

  • tests/stress/to-this-double.js: Added.

(Number.prototype.negate):

  • tests/stress/to-this-int32.js: Added.

(Number.prototype.negate):

  • tests/stress/to-this-int52.js: Added.

(Number.prototype.negate):

  • tests/stress/to-this-number.js: Added.

(Number.prototype.negate):

  • tests/stress/to-this-string.js: Added.

(String.prototype.prefix):
(String.prototype.first):
(String.prototype.second):

  • tests/stress/to-this-symbol.js: Added.

(Symbol.prototype.identity):
(Symbol.prototype.identity2):

Location:
trunk/Source/JavaScriptCore
Files:
7 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r195926 r195938  
     12016-01-31  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Should not predict OtherObj for ToThis with primitive types under strict mode
     4        https://bugs.webkit.org/show_bug.cgi?id=153544
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Currently, ToThis predicates OtherObj for primitive values.
     9        But it's not true in strict mode.
     10        In strict mode, ToThis does nothing on primitive values.
     11
     12        In this patch, we
     13
     14        1. fix prediction. Handles primitive types in strict mode. And we also handles StringObject.
     15        2. convert it to Identity if the argument should be predicted as primitive types.
     16
     17        This optimization is important to implement Primitive.prototype.methods[1].
     18        Otherwise, we always got BadType OSR exits.
     19
     20        [1]: https://bugs.webkit.org/show_bug.cgi?id=143889
     21
     22        * dfg/DFGAbstractInterpreterInlines.h:
     23        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     24        * dfg/DFGConstantFoldingPhase.cpp:
     25        (JSC::DFG::ConstantFoldingPhase::foldConstants):
     26        * dfg/DFGFixupPhase.cpp:
     27        (JSC::DFG::FixupPhase::fixupNode):
     28        (JSC::DFG::FixupPhase::fixupToThis):
     29        * dfg/DFGPredictionPropagationPhase.cpp:
     30        (JSC::DFG::PredictionPropagationPhase::propagate):
     31        * tests/stress/to-this-boolean.js: Added.
     32        (Boolean.prototype.negate):
     33        (Boolean.prototype.negate2):
     34        * tests/stress/to-this-double.js: Added.
     35        (Number.prototype.negate):
     36        * tests/stress/to-this-int32.js: Added.
     37        (Number.prototype.negate):
     38        * tests/stress/to-this-int52.js: Added.
     39        (Number.prototype.negate):
     40        * tests/stress/to-this-number.js: Added.
     41        (Number.prototype.negate):
     42        * tests/stress/to-this-string.js: Added.
     43        (String.prototype.prefix):
     44        (String.prototype.first):
     45        (String.prototype.second):
     46        * tests/stress/to-this-symbol.js: Added.
     47        (Symbol.prototype.identity):
     48        (Symbol.prototype.identity2):
     49
    1502016-01-31  Guillaume Emont  <guijemont@igalia.com>
    251
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r194835 r195938  
    16921692        AbstractValue& source = forNode(node->child1());
    16931693        AbstractValue& destination = forNode(node);
    1694            
    1695         if (m_graph.executableFor(node->origin.semantic)->isStrictMode())
     1694
     1695        if (source.m_type == SpecStringObject) {
     1696            m_state.setFoundConstants(true);
     1697            destination = source;
     1698            break;
     1699        }
     1700
     1701        if (m_graph.executableFor(node->origin.semantic)->isStrictMode()) {
     1702            if (!(source.m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol))) {
     1703                m_state.setFoundConstants(true);
     1704                destination = source;
     1705                break;
     1706            }
    16961707            destination.makeHeapTop();
    1697         else {
     1708        } else {
    16981709            destination = source;
    16991710            destination.merge(SpecObject);
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r190991 r195938  
    553553                break;
    554554            }
    555                
     555
    556556            case Check: {
    557557                alreadyHandled = true;
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r194996 r195938  
    10041004           
    10051005        case ToThis: {
    1006             ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
    1007 
    1008             if (node->child1()->shouldSpeculateOther()) {
    1009                 if (ecmaMode == StrictMode) {
    1010                     fixEdge<OtherUse>(node->child1());
    1011                     node->convertToIdentity();
    1012                     break;
    1013                 }
    1014 
    1015                 m_insertionSet.insertNode(
    1016                     m_indexInBlock, SpecNone, Check, node->origin,
    1017                     Edge(node->child1().node(), OtherUse));
    1018                 observeUseKindOnNode<OtherUse>(node->child1().node());
    1019                 m_graph.convertToConstant(
    1020                     node, m_graph.globalThisObjectFor(node->origin.semantic));
    1021                 break;
    1022             }
    1023            
    1024             if (isFinalObjectSpeculation(node->child1()->prediction())) {
    1025                 fixEdge<FinalObjectUse>(node->child1());
    1026                 node->convertToIdentity();
    1027                 break;
    1028             }
    1029            
     1006            fixupToThis(node);
    10301007            break;
    10311008        }
     
    15931570        }
    15941571    }
     1572
     1573    void fixupToThis(Node* node)
     1574    {
     1575        ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
     1576
     1577        if (ecmaMode == StrictMode) {
     1578            if (node->child1()->shouldSpeculateBoolean()) {
     1579                fixEdge<BooleanUse>(node->child1());
     1580                node->convertToIdentity();
     1581                return;
     1582            }
     1583
     1584            if (node->child1()->shouldSpeculateInt32()) {
     1585                fixEdge<Int32Use>(node->child1());
     1586                node->convertToIdentity();
     1587                return;
     1588            }
     1589
     1590            if (enableInt52() && node->child1()->shouldSpeculateMachineInt()) {
     1591                fixEdge<Int52RepUse>(node->child1());
     1592                node->convertToIdentity();
     1593                node->setResult(NodeResultInt52);
     1594                return;
     1595            }
     1596
     1597            if (node->child1()->shouldSpeculateNumber()) {
     1598                fixEdge<DoubleRepUse>(node->child1());
     1599                node->convertToIdentity();
     1600                node->setResult(NodeResultDouble);
     1601                return;
     1602            }
     1603
     1604            if (node->child1()->shouldSpeculateSymbol()) {
     1605                fixEdge<SymbolUse>(node->child1());
     1606                node->convertToIdentity();
     1607                return;
     1608            }
     1609
     1610            if (node->child1()->shouldSpeculateStringIdent()) {
     1611                fixEdge<StringIdentUse>(node->child1());
     1612                node->convertToIdentity();
     1613                return;
     1614            }
     1615
     1616            if (node->child1()->shouldSpeculateString()) {
     1617                fixEdge<StringUse>(node->child1());
     1618                node->convertToIdentity();
     1619                return;
     1620            }
     1621        }
     1622
     1623        if (node->child1()->shouldSpeculateOther()) {
     1624            if (ecmaMode == StrictMode) {
     1625                fixEdge<OtherUse>(node->child1());
     1626                node->convertToIdentity();
     1627                return;
     1628            }
     1629
     1630            m_insertionSet.insertNode(
     1631                m_indexInBlock, SpecNone, Check, node->origin,
     1632                Edge(node->child1().node(), OtherUse));
     1633            observeUseKindOnNode<OtherUse>(node->child1().node());
     1634            m_graph.convertToConstant(
     1635                node, m_graph.globalThisObjectFor(node->origin.semantic));
     1636            return;
     1637        }
     1638
     1639        if (node->child1()->shouldSpeculateStringObject()) {
     1640            fixEdge<StringObjectUse>(node->child1());
     1641            node->convertToIdentity();
     1642            return;
     1643        }
     1644
     1645        if (isFinalObjectSpeculation(node->child1()->prediction())) {
     1646            fixEdge<FinalObjectUse>(node->child1());
     1647            node->convertToIdentity();
     1648            return;
     1649        }
     1650    }
    15951651   
    15961652    void fixupToPrimitive(Node* node)
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r194983 r195938  
    490490
    491491        case ToThis: {
     492            // ToThis in methods for primitive types should speculate primitive types in strict mode.
     493            ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
     494            if (ecmaMode == StrictMode) {
     495                if (node->child1()->shouldSpeculateBoolean()) {
     496                    changed |= mergePrediction(SpecBoolean);
     497                    break;
     498                }
     499
     500                if (node->child1()->shouldSpeculateInt32()) {
     501                    changed |= mergePrediction(SpecInt32);
     502                    break;
     503                }
     504
     505                if (enableInt52() && node->child1()->shouldSpeculateMachineInt()) {
     506                    changed |= mergePrediction(SpecMachineInt);
     507                    break;
     508                }
     509
     510                if (node->child1()->shouldSpeculateNumber()) {
     511                    changed |= mergePrediction(SpecMachineInt);
     512                    break;
     513                }
     514
     515                if (node->child1()->shouldSpeculateSymbol()) {
     516                    changed |= mergePrediction(SpecSymbol);
     517                    break;
     518                }
     519
     520                if (node->child1()->shouldSpeculateStringIdent()) {
     521                    changed |= mergePrediction(SpecStringIdent);
     522                    break;
     523                }
     524
     525                if (node->child1()->shouldSpeculateString()) {
     526                    changed |= mergePrediction(SpecString);
     527                    break;
     528                }
     529            } else {
     530                if (node->child1()->shouldSpeculateString()) {
     531                    changed |= mergePrediction(SpecStringObject);
     532                    break;
     533                }
     534            }
     535
    492536            SpeculatedType prediction = node->child1()->prediction();
    493537            if (prediction) {
    494538                if (prediction & ~SpecObject) {
    495                     prediction &= SpecObject;
    496                     prediction = mergeSpeculations(prediction, SpecObjectOther);
     539                    // Wrapper objects are created only in sloppy mode.
     540                    if (ecmaMode != StrictMode) {
     541                        prediction &= SpecObject;
     542                        prediction = mergeSpeculations(prediction, SpecObjectOther);
     543                    }
    497544                }
    498545                changed |= mergePrediction(prediction);
Note: See TracChangeset for help on using the changeset viewer.