Ignore:
Timestamp:
Nov 4, 2015, 1:46:10 PM (10 years ago)
Author:
[email protected]
Message:

Fix endless OSR exits when creating a rope that contains an object that ToPrimitive's to a number.
https://bugs.webkit.org/show_bug.cgi?id=150583

Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

Before we assumed that the result of ToPrimitive on any object was a string.
This had a couple of negative effects. First, the result ToPrimitive on an
object can be overridden to be any primitive type. In fact, as of ES6, ToPrimitive,
when part of a addition expression, will type hint a number value. Second, even after
repeatedly exiting with a bad type we would continue to think that the result
of ToPrimitive would be a string so we continue to convert StrCats into MakeRope.

The fix is to make Prediction Propagation match the behavior of Fixup and move
canOptimizeStringObjectAccess to DFGGraph.

  • bytecode/SpeculatedType.h:
  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::attemptToForceStringArrayModeByToStringConversion):
(JSC::DFG::FixupPhase::fixupToPrimitive):
(JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
(JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
(JSC::DFG::FixupPhase::isStringPrototypeMethodSane): Deleted.
(JSC::DFG::FixupPhase::canOptimizeStringObjectAccess): Deleted.

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::isStringPrototypeMethodSane):
(JSC::DFG::Graph::canOptimizeStringObjectAccess):

  • dfg/DFGGraph.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::resultOfToPrimitive):
(JSC::DFG::resultOfToPrimitive): Deleted.

  • bytecode/SpeculatedType.h:
  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::attemptToForceStringArrayModeByToStringConversion):
(JSC::DFG::FixupPhase::fixupToPrimitive):
(JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
(JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
(JSC::DFG::FixupPhase::isStringPrototypeMethodSane): Deleted.
(JSC::DFG::FixupPhase::canOptimizeStringObjectAccess): Deleted.

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::isStringPrototypeMethodSane):
(JSC::DFG::Graph::canOptimizeStringObjectAccess):

  • dfg/DFGGraph.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::resultOfToPrimitive):
(JSC::DFG::resultOfToPrimitive): Deleted.

  • tests/stress/string-rope-with-custom-valueof.js: Added.

(catNumber):
(number.valueOf):
(catBool):
(bool.valueOf):
(catUndefined):
(undef.valueOf):
(catRandom):
(random.valueOf):

LayoutTests:

Created a regression test to look for OSRing in string concatenation when
valueOf returns a non-string primitive.

  • js/regress/script-tests/string-rope-with-object.js: Added.

(body.f):
(body.String.prototype.valueOf):
(body.bar.valueOf):
(body):

  • js/regress/string-rope-with-object-expected.txt: Added.
  • js/regress/string-rope-with-object.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r191621 r192034  
    3434
    3535namespace JSC { namespace DFG {
    36 
    37 SpeculatedType resultOfToPrimitive(SpeculatedType type)
    38 {
    39     if (type & SpecObject) {
    40         // Objects get turned into strings. So if the input has hints of objectness,
    41         // the output will have hinsts of stringiness.
    42         return mergeSpeculations(type & ~SpecObject, SpecString);
    43     }
    44    
    45     return type;
    46 }
    4736
    4837class PredictionPropagationPhase : public Phase {
     
    909898            m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
    910899    }
     900
     901    SpeculatedType resultOfToPrimitive(SpeculatedType type)
     902    {
     903        if (type & SpecObject) {
     904            // We try to be optimistic here about StringObjects since it's unlikely that
     905            // someone overrides the valueOf or toString methods.
     906            if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
     907                return mergeSpeculations(type & ~SpecObject, SpecString);
     908
     909            return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
     910        }
     911
     912        return type;
     913    }
    911914   
    912915    Node* m_currentNode;
Note: See TracChangeset for help on using the changeset viewer.