Ignore:
Timestamp:
Apr 24, 2016, 10:05:51 AM (9 years ago)
Author:
[email protected]
Message:

[INTL] Implement String.prototype.localeCompare in ECMA-402
https://bugs.webkit.org/show_bug.cgi?id=147607

Patch by Filip Pizlo <[email protected]> and Andy VanWagoner <[email protected]> on 2016-04-24
Reviewed by Darin Adler.
Source/JavaScriptCore:


Part of this change is just rolling 194394 back in.

The other part is making that not a regression on CDjs. Other than the fact that it uses
bound functions, the problem with this new localeCompare implementation is that it uses
the arguments object. It uses it in a way that *seems* like ArgumentsEliminationPhase
ought to handle, but to my surprise it didn't:

  • If we have a ForceExit GetByVal on the arguments object, we would previously assume that it escaped. That's false since we just exit at ForceExit. On the other hand we probably should be pruning unreachable paths before we get here, but that's a separate issue. I don't want to play with phase order right now.


  • If we have a OutOfBounds GetByVal on the arguments object, then the best that would previously happen is that we'd compile it into an in-bounds arguments access. That's quite bad, as Andy's localeCompare illustrates: it uses out-of-bounds access on the arguments object to detect if an argument was passed. This change introduces an OutOfBounds version of GetMyArgumentByVal for this purpose.


This change required registering sane chain watchpoints. In the process, I noticed that the
old way of doing it had a race condition: we might register watchpoints for the structure
that had become insane. This change introduces a double-checking idiom that I believe works
because once the structure becomes insane it can't go back to sane and watchpoints
registration already involves executing the hardest possible fences.

  • builtins/StringPrototype.js:

(repeat):
(localeCompare):
(search):

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGArgumentsEliminationPhase.cpp:
  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::refine):

  • 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):

  • dfg/DFGNodeType.h:
  • dfg/DFGPreciseLocalClobberize.h:

(JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):

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

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileGetByValOnString):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • dfg/DFGValidate.cpp:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetMyArgumentByVal):
(JSC::FTL::DFG::LowerDFGToB3::compilePutByVal):
(JSC::FTL::DFG::LowerDFGToB3::compileStringCharAt):

  • ftl/FTLTypedPointer.h:

(JSC::FTL::TypedPointer::TypedPointer):
(JSC::FTL::TypedPointer::operator bool):
(JSC::FTL::TypedPointer::heap):
(JSC::FTL::TypedPointer::operator!): Deleted.

  • runtime/StringPrototype.cpp:

(JSC::StringPrototype::finishCreation):

LayoutTests:

  • js/dom/script-tests/string-prototype-properties.js:
  • js/dom/string-prototype-properties-expected.txt:
  • js/regress/locale-compare.html: Added.
  • js/regress/locale-compare-expected.txt: Added.
  • js/regress/scripts-tests/locale-compare.js: Added.
  • js/script-tests/string-localeCompare.js:
  • js/string-localeCompare-expected.txt:
  • js/string-localeCompare.html:
File:
1 edited

Legend:

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

    r191215 r199967  
    11/*
    2  * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    199199            graph.watchpoints().addLazily(globalObject->arrayPrototype()->structure()->transitionWatchpointSet());
    200200            graph.watchpoints().addLazily(globalObject->objectPrototype()->structure()->transitionWatchpointSet());
    201             return withSpeculation(Array::SaneChain);
     201            if (globalObject->arrayPrototypeChainIsSane())
     202                return withSpeculation(Array::SaneChain);
    202203        }
    203204        return ArrayMode(Array::Generic);
Note: See TracChangeset for help on using the changeset viewer.