Changeset 230568 in webkit


Ignore:
Timestamp:
Apr 12, 2018 6:41:06 AM (6 years ago)
Author:
Kocsen Chung
Message:

Cherry-pick r230488. rdar://problem/39337455

DFG AI and clobberize should agree with each other
https://bugs.webkit.org/show_bug.cgi?id=184440

Reviewed by Saam Barati.

JSTests:

Add tests for all of the bugs I fixed.

  • stress/direct-arguments-out-of-bounds-change-structure.js: Added. (foo):
  • stress/new-typed-array-cse-effects.js: Added. (foo):
  • stress/scoped-arguments-out-of-bounds-change-structure.js: Added. (foo.theO): (foo):
  • stress/string-from-char-code-change-structure-not-dead.js: Added. (foo): (i.valueOf): (weirdValue.valueOf):
  • stress/string-from-char-code-change-structure.js: Added. (foo): (i.valueOf): (weirdValue.valueOf):

Source/JavaScriptCore:

One way to fix bugs involving underapproximation in AI or clobberize is to assert that they
agree with each other. That's what this patch does: it adds an assertion that AI's structure
state tracking must be equivalent to JSCell_structureID being clobbered.

One subtlety is that AI sometimes folds away structure clobbering using information that
clobberize doesn't have. So, we track this wuth special kinds of AI states (FoldedClobber and
ObservedTransitions).

This fixes a bunch of cases of AI missing clobberStructures/clobberWorld and one case of
clobberize missing a write(Heap).

This also makes some cases more precise in order to appease the assertion. Making things more
precise might make things faster, but I didn't measure it because that wasn't the goal.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • dfg/DFGAbstractInterpreter.h:
  • dfg/DFGAbstractInterpreterClobberState.cpp: Added. (WTF::printInternal):
  • dfg/DFGAbstractInterpreterClobberState.h: Added. (JSC::DFG::mergeClobberStates):
  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::startExecuting): (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): (JSC::DFG::AbstractInterpreter<AbstractStateType>::didFoldClobberWorld): (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberStructures): (JSC::DFG::AbstractInterpreter<AbstractStateType>::didFoldClobberStructures): (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransition): (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransitions): (JSC::DFG::AbstractInterpreter<AbstractStateType>::setDidClobber): Deleted.
  • dfg/DFGAtTailAbstractState.h: (JSC::DFG::AtTailAbstractState::setClobberState): (JSC::DFG::AtTailAbstractState::mergeClobberState): (JSC::DFG::AtTailAbstractState::setDidClobber): Deleted.
  • dfg/DFGCFAPhase.cpp: (JSC::DFG::CFAPhase::performBlockCFA):
  • dfg/DFGClobberSet.cpp: (JSC::DFG::writeSet):
  • dfg/DFGClobberSet.h:
  • dfg/DFGClobberize.h: (JSC::DFG::clobberize):
  • dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants):
  • dfg/DFGInPlaceAbstractState.h: (JSC::DFG::InPlaceAbstractState::clobberState const): (JSC::DFG::InPlaceAbstractState::didClobberOrFolded const): (JSC::DFG::InPlaceAbstractState::didClobber const): (JSC::DFG::InPlaceAbstractState::setClobberState): (JSC::DFG::InPlaceAbstractState::mergeClobberState): (JSC::DFG::InPlaceAbstractState::setDidClobber): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230488 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-605-branch
Files:
7 added
13 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-605-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r230239 r230568  
    343343                0F5CF9841E9D537700C18692 /* AirLowerStackArgs.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5CF9831E9D537500C18692 /* AirLowerStackArgs.h */; };
    344344                0F5CF9891E9ED65200C18692 /* AirStackAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5CF9871E9ED64E00C18692 /* AirStackAllocation.h */; };
     345                0F5E0FD8207C72730097F0DE /* DFGAbstractInterpreterClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5E0FD6207C72710097F0DE /* DFGAbstractInterpreterClobberState.h */; };
    345346                0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5EF91C16878F78003E5C25 /* JITThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
    346347                0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    23452346                0F5CF9871E9ED64E00C18692 /* AirStackAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirStackAllocation.h; path = b3/air/AirStackAllocation.h; sourceTree = "<group>"; };
    23462347                0F5D085C1B8CF99D001143B4 /* DFGNodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNodeOrigin.cpp; path = dfg/DFGNodeOrigin.cpp; sourceTree = "<group>"; };
     2348                0F5E0FD6207C72710097F0DE /* DFGAbstractInterpreterClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractInterpreterClobberState.h; path = dfg/DFGAbstractInterpreterClobberState.h; sourceTree = "<group>"; };
     2349                0F5E0FD7207C72710097F0DE /* DFGAbstractInterpreterClobberState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractInterpreterClobberState.cpp; path = dfg/DFGAbstractInterpreterClobberState.cpp; sourceTree = "<group>"; };
    23472350                0F5EF91B16878F78003E5C25 /* JITThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITThunks.cpp; sourceTree = "<group>"; };
    23482351                0F5EF91C16878F78003E5C25 /* JITThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITThunks.h; sourceTree = "<group>"; };
     
    70667069                                A77A423717A0BBFD00A8DB81 /* DFGAbstractHeap.h */,
    70677070                                A704D8FE17A0BAA8006BA554 /* DFGAbstractInterpreter.h */,
     7071                                0F5E0FD7207C72710097F0DE /* DFGAbstractInterpreterClobberState.cpp */,
     7072                                0F5E0FD6207C72710097F0DE /* DFGAbstractInterpreterClobberState.h */,
    70687073                                A704D8FF17A0BAA8006BA554 /* DFGAbstractInterpreterInlines.h */,
    70697074                                0F55C19317276E4600CEABFD /* DFGAbstractValue.cpp */,
     
    81608165                                8B3BF5E41E3D368B0076A87A /* AsyncGeneratorPrototype.lut.h in Headers */,
    81618166                                8BC064961E1D845C00B2B8CA /* AsyncIteratorPrototype.h in Headers */,
     8167                                0F5E0FD8207C72730097F0DE /* DFGAbstractInterpreterClobberState.h in Headers */,
    81628168                                6A38CFAA1E32B5AB0060206F /* AsyncStackTrace.h in Headers */,
    81638169                                0F7CF9571DC125900098CC12 /* AtomicsObject.h in Headers */,
  • branches/safari-605-branch/Source/JavaScriptCore/Sources.txt

    r230239 r230568  
    272272
    273273dfg/DFGAbstractHeap.cpp
     274dfg/DFGAbstractInterpreterClobberState.cpp
    274275dfg/DFGAbstractValue.cpp
    275276dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h

    r227388 r230568  
    151151private:
    152152    void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
     153    void didFoldClobberWorld();
    153154   
    154155    template<typename Functor>
     
    156157   
    157158    void clobberStructures(unsigned indexInBlock);
     159    void didFoldClobberStructures();
     160   
    158161    void observeTransition(unsigned indexInBlock, RegisteredStructure from, RegisteredStructure to);
    159162    void observeTransitions(unsigned indexInBlock, const TransitionVector&);
    160     void setDidClobber();
    161163   
    162164    enum BooleanResult {
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r230536 r230568  
    3030#include "ArrayConstructor.h"
    3131#include "DFGAbstractInterpreter.h"
     32#include "DFGAbstractInterpreterClobberState.h"
    3233#include "DOMJITGetterSetter.h"
    3334#include "DOMJITSignature.h"
     
    9798    ASSERT(m_state.isValid());
    9899   
    99     m_state.setDidClobber(false);
     100    m_state.setClobberState(AbstractInterpreterClobberState::NotClobbered);
    100101}
    101102
     
    329330        // itself into a straight-line sequence of GetStack/PutStack.
    330331        // https://bugs.webkit.org/show_bug.cgi?id=143071
    331         clobberWorld(node->origin.semantic, clobberLimit);
     332        switch (node->op()) {
     333        case LoadVarargs:
     334            clobberWorld(node->origin.semantic, clobberLimit);
     335            break;
     336        case ForwardVarargs:
     337            break;
     338        default:
     339            DFG_CRASH(m_graph, node, "Bad opcode");
     340            break;
     341        }
    332342        LoadVarargsData* data = node->loadVarargsData();
    333343        m_state.variables().operand(data->count).setType(SpecInt32Only);
     
    609619        JSValue operand = forNode(node->child1()).value();
    610620        if (std::optional<double> number = operand.toNumberFromPrimitive()) {
     621            switch (node->child1().useKind()) {
     622            case Int32Use:
     623            case KnownInt32Use:
     624                break;
     625            default:
     626                didFoldClobberWorld();
     627                break;
     628            }
    611629            uint32_t value = toUInt32(*number);
    612630            setConstant(node, jsNumber(clz32(value)));
     
    10161034        JSValue operand = forNode(node->child1()).value();
    10171035        if (std::optional<double> number = operand.toNumberFromPrimitive()) {
     1036            if (node->child1().useKind() != DoubleRepUse)
     1037                didFoldClobberWorld();
     1038           
    10181039            double roundedValue = 0;
    10191040            if (node->op() == ArithRound)
     
    14911512    case CompareGreaterEq:
    14921513    case CompareEq: {
     1514        bool isClobbering = node->isBinaryUseKind(UntypedUse);
     1515       
     1516        if (isClobbering)
     1517            didFoldClobberWorld();
     1518       
    14931519        JSValue leftConst = forNode(node->child1()).value();
    14941520        JSValue rightConst = forNode(node->child2()).value();
     
    16121638        }
    16131639
    1614         if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse)
     1640        if (isClobbering)
    16151641            clobberWorld(node->origin.semantic, clobberLimit);
    16161642        forNode(node).setType(SpecBoolean);
     
    16991725       
    17001726    case StringFromCharCode:
     1727        switch (node->child1().useKind()) {
     1728        case Int32Use:
     1729            break;
     1730        case UntypedUse:
     1731            clobberWorld(node->origin.semantic, clobberLimit);
     1732            break;
     1733        default:
     1734            DFG_CRASH(m_graph, node, "Bad use kind");
     1735            break;
     1736        }
    17011737        forNode(node).setType(m_graph, SpecString);
    17021738        break;
     
    17591795        case Array::DirectArguments:
    17601796        case Array::ScopedArguments:
     1797            if (node->arrayMode().isOutOfBounds())
     1798                clobberWorld(node->origin.semantic, clobberLimit);
    17611799            forNode(node).makeHeapTop();
    17621800            break;
     
    20302068        JSValue childConst = forNode(node->child1()).value();
    20312069        if (childConst && childConst.isNumber()) {
     2070            didFoldClobberWorld();
    20322071            setConstant(node, childConst);
    20332072            break;
     
    20382077        if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol))) {
    20392078            m_state.setFoundConstants(true);
     2079            didFoldClobberWorld();
    20402080            forNode(node) = forNode(node->child1());
    20412081            break;
     
    20432083       
    20442084        clobberWorld(node->origin.semantic, clobberLimit);
    2045        
    20462085        forNode(node).setType(m_graph, SpecHeapTop & ~SpecObject);
    20472086        break;
     
    20512090        JSValue childConst = forNode(node->child1()).value();
    20522091        if (childConst && childConst.isNumber()) {
     2092            didFoldClobberWorld();
    20532093            setConstant(node, childConst);
    20542094            break;
     
    20592099        if (!(forNode(node->child1()).m_type & ~SpecBytecodeNumber)) {
    20602100            m_state.setFoundConstants(true);
     2101            didFoldClobberWorld();
    20612102            forNode(node) = forNode(node->child1());
    20622103            break;
     
    21022143            if (2 <= radix && radix <= 36) {
    21032144                m_state.setFoundConstants(true);
     2145                didFoldClobberWorld();
    21042146                forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
    21052147                break;
     
    21452187
    21462188    case Spread:
    2147         if (!m_graph.canDoFastSpread(node, forNode(node->child1())))
    2148             clobberWorld(node->origin.semantic, clobberLimit);
     2189        switch (node->child1()->op()) {
     2190        case PhantomNewArrayBuffer:
     2191        case PhantomCreateRest:
     2192            break;
     2193        default:
     2194            if (!m_graph.canDoFastSpread(node, forNode(node->child1())))
     2195                clobberWorld(node->origin.semantic, clobberLimit);
     2196            else
     2197                didFoldClobberWorld();
     2198            break;
     2199        }
    21492200
    21502201        forNode(node).set(
     
    22362287        if (!(source.m_type & ~SpecObject)) {
    22372288            m_state.setFoundConstants(true);
     2289            if (node->op() == ToObject)
     2290                didFoldClobberWorld();
    22382291            destination = source;
    22392292            break;
     
    22592312    case PhantomNewArrayBuffer:
    22602313    case BottomValue:
    2261         m_state.setDidClobber(true); // Prevent constant folding.
    22622314        // This claims to return bottom.
    22632315        break;
     
    24642516    case GetById:
    24652517    case GetByIdFlush: {
    2466         if (!node->prediction()) {
    2467             m_state.setIsValid(false);
    2468             break;
    2469         }
    2470        
    24712518        AbstractValue& value = forNode(node->child1());
    24722519        if (value.m_structure.isFinite()
     
    24882535                }
    24892536                m_state.setFoundConstants(true);
     2537                didFoldClobberWorld();
    24902538                forNode(node) = result;
    24912539                break;
     
    26272675    case PutStructure:
    26282676        if (!forNode(node->child1()).m_structure.isClear()) {
    2629             if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
     2677            if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next) {
     2678                didFoldClobberStructures();
    26302679                m_state.setFoundConstants(true);
    2631             else {
     2680            } else {
    26322681                observeTransition(
    26332682                    clobberLimit, node->transition()->previous, node->transition()->next);
     
    26422691        // FIXME: We don't model the fact that the structureID is nuked, simply because currently
    26432692        // nobody would currently benefit from having that information. But it's a bug nonetheless.
     2693        if (node->op() == NukeStructureAndSetButterfly)
     2694            didFoldClobberStructures();
    26442695        forNode(node).clear(); // The result is not a JS value.
    26452696        break;
     
    27412792    case Arrayify: {
    27422793        if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
     2794            didFoldClobberStructures();
    27432795            m_state.setFoundConstants(true);
    27442796            break;
     
    28322884
    28332885            if (prototype && canFold) {
     2886                switch (node->child1().useKind()) {
     2887                case ArrayUse:
     2888                case FunctionUse:
     2889                case FinalObjectUse:
     2890                    break;
     2891                default:
     2892                    didFoldClobberWorld();
     2893                    break;
     2894                }
    28342895                setConstant(node, *m_graph.freeze(prototype));
    28352896                break;
     
    29633024        AbstractValue resultingValue;
    29643025       
     3026        if (node->multiPutByOffsetData().writesStructures())
     3027            didFoldClobberStructures();
     3028           
    29653029        for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
    29663030            const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
     
    30933157                    m_state.setFoundConstants(true);
    30943158               
     3159                didFoldClobberWorld();
    30953160                observeTransitions(clobberLimit, transitions);
    30963161                if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
     
    33203385                && (radix.asNumber() == 0 || radix.asNumber() == 10)) {
    33213386                m_state.setFoundConstants(true);
     3387                if (node->child1().useKind() == UntypedUse)
     3388                    didFoldClobberWorld();
    33223389                forNode(node).setType(SpecInt32Only);
    33233390                break;
     
    34203487{
    34213488    clobberStructures(clobberLimit);
     3489}
     3490
     3491template<typename AbstractStateType>
     3492void AbstractInterpreter<AbstractStateType>::didFoldClobberWorld()
     3493{
     3494    didFoldClobberStructures();
    34223495}
    34233496
     
    34553528{
    34563529    forAllValues(clobberLimit, AbstractValue::clobberStructuresFor);
    3457     setDidClobber();
     3530    m_state.mergeClobberState(AbstractInterpreterClobberState::ClobberedStructures);
     3531    m_state.setStructureClobberState(StructuresAreClobbered);
     3532}
     3533
     3534template<typename AbstractStateType>
     3535void AbstractInterpreter<AbstractStateType>::didFoldClobberStructures()
     3536{
     3537    m_state.mergeClobberState(AbstractInterpreterClobberState::FoldedClobber);
    34583538}
    34593539
     
    34663546   
    34673547    ASSERT(!from->dfgShouldWatch()); // We don't need to claim to be in a clobbered state because 'from' was never watchable (during the time we were compiling), hence no constants ever introduced into the DFG IR that ever had a watchable structure would ever have the same structure as from.
     3548   
     3549    m_state.mergeClobberState(AbstractInterpreterClobberState::ObservedTransitions);
    34683550}
    34693551
     
    34723554    unsigned clobberLimit, const TransitionVector& vector)
    34733555{
     3556    if (vector.isEmpty())
     3557        return;
     3558   
    34743559    AbstractValue::TransitionsObserver transitionsObserver(vector);
    34753560    forAllValues(clobberLimit, transitionsObserver);
     
    34803565            ASSERT(!vector[i].previous->dfgShouldWatch());
    34813566    }
    3482 }
    3483 
    3484 template<typename AbstractStateType>
    3485 void AbstractInterpreter<AbstractStateType>::setDidClobber()
    3486 {
    3487     m_state.setDidClobber(true);
    3488     m_state.setStructureClobberState(StructuresAreClobbered);
     3567
     3568    m_state.mergeClobberState(AbstractInterpreterClobberState::ObservedTransitions);
    34893569}
    34903570
     
    35863666    JSValue child = forNode(node->child1()).value();
    35873667    if (std::optional<double> number = child.toNumberFromPrimitive()) {
     3668        if (node->child1().useKind() != DoubleRepUse)
     3669            didFoldClobberWorld();
    35883670        setConstant(node, jsDoubleNumber(equivalentFunction(*number)));
    35893671        return;
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h

    r225966 r230568  
    11/*
    2  * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#if ENABLE(DFG_JIT)
    2929
     30#include "DFGAbstractInterpreterClobberState.h"
    3031#include "DFGAbstractValue.h"
    3132#include "DFGBasicBlock.h"
     
    6061    StructureClobberState structureClobberState() const { return m_block->cfaStructureClobberStateAtTail; }
    6162   
    62     void setDidClobber(bool) { }
     63    void setClobberState(AbstractInterpreterClobberState) { }
     64    void mergeClobberState(AbstractInterpreterClobberState) { }
    6365    void setStructureClobberState(StructureClobberState state) { RELEASE_ASSERT(state == m_block->cfaStructureClobberStateAtTail); }
    6466    void setIsValid(bool isValid) { m_block->cfaDidFinish = isValid; }
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp

    r204130 r230568  
    11/*
    2  * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "DFGAbstractInterpreterInlines.h"
     32#include "DFGClobberSet.h"
    3233#include "DFGGraph.h"
    3334#include "DFGInPlaceAbstractState.h"
     
    164165        }
    165166        for (unsigned i = 0; i < block->size(); ++i) {
     167            Node* node = block->at(i);
    166168            if (m_verbose) {
    167                 Node* node = block->at(i);
    168169                dataLogF("      %s @%u: ", Graph::opName(node->op()), node->index());
    169170               
     
    180181                break;
    181182            }
     183           
     184            if (m_state.didClobberOrFolded() != writesOverlap(m_graph, node, JSCell_structureID))
     185                DFG_CRASH(m_graph, node, toCString("AI-clobberize disagreement; AI says ", m_state.clobberState(), " while clobberize says ", writeSet(m_graph, node)).data());
    182186        }
    183187        if (m_verbose) {
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGClobberSet.cpp

    r210023 r230568  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    159159}
    160160
     161ClobberSet writeSet(Graph& graph, Node* node)
     162{
     163    ClobberSet result;
     164    addWrites(graph, node, result);
     165    return result;
     166}
     167
    161168bool readsOverlap(Graph& graph, Node* node, ClobberSet& readSet)
    162169{
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGClobberSet.h

    r207787 r230568  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    114114void addReadsAndWrites(Graph&, Node*, ClobberSet& reads, ClobberSet& writes);
    115115
     116ClobberSet writeSet(Graph&, Node*);
     117
    116118bool readsOverlap(Graph&, Node*, ClobberSet&);
    117119bool writesOverlap(Graph&, Node*, ClobberSet&);
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGClobberize.h

    r230536 r230568  
    954954           
    955955        case Array::ArrayStorage:
     956            if (node->arrayMode().isOutOfBounds()) {
     957                read(World);
     958                write(Heap);
     959                return;
     960            }
     961            read(Butterfly_publicLength);
     962            read(Butterfly_vectorLength);
     963            read(ArrayStorageProperties);
     964            write(ArrayStorageProperties);
     965            if (node->arrayMode().mayStoreToHole())
     966                write(Butterfly_publicLength);
     967            return;
     968
    956969        case Array::SlowPutArrayStorage:
    957             // Give up on life for now.
    958             read(World);
    959             write(Heap);
     970            if (node->arrayMode().mayStoreToHole()) {
     971                read(World);
     972                write(Heap);
     973                return;
     974            }
     975            read(Butterfly_publicLength);
     976            read(Butterfly_vectorLength);
     977            read(ArrayStorageProperties);
     978            write(ArrayStorageProperties);
    960979            return;
    961980
     
    13011320
    13021321    case NewArrayWithSize:
    1303     case NewTypedArray:
    13041322        read(HeapObjectCount);
    13051323        write(HeapObjectCount);
    13061324        return;
     1325
     1326    case NewTypedArray:
     1327        switch (node->child1().useKind()) {
     1328        case Int32Use:
     1329            read(HeapObjectCount);
     1330            write(HeapObjectCount);
     1331            return;
     1332        case UntypedUse:
     1333            read(World);
     1334            write(Heap);
     1335            return;
     1336        default:
     1337            DFG_CRASH(graph, node, "Bad use kind");
     1338        }
     1339        break;
    13071340
    13081341    case NewArrayWithSpread: {
     
    15231556        def(PureValue(node));
    15241557        return;
    1525        
     1558
    15261559    case CompareEq:
    15271560    case CompareLess:
     
    15351568        }
    15361569
    1537         if (node->op() == CompareEq && node->isBinaryUseKind(ObjectUse)) {
    1538             def(PureValue(node));
    1539             return;
    1540         }
    1541         if (node->child1().useKind() == UntypedUse || node->child1().useKind() == ObjectUse
    1542             || node->child2().useKind() == UntypedUse || node->child2().useKind() == ObjectUse) {
     1570        if (node->isBinaryUseKind(UntypedUse)) {
    15431571            read(World);
    15441572            write(Heap);
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r230536 r230568  
    762762            }
    763763               
     764            case PhantomNewObject:
     765            case PhantomNewFunction:
     766            case PhantomNewGeneratorFunction:
     767            case PhantomNewAsyncGeneratorFunction:
     768            case PhantomNewAsyncFunction:
     769            case PhantomCreateActivation:
     770            case PhantomDirectArguments:
     771            case PhantomClonedArguments:
     772            case PhantomCreateRest:
     773            case PhantomSpread:
     774            case PhantomNewArrayWithSpread:
     775            case PhantomNewArrayBuffer:
     776            case BottomValue:
     777                alreadyHandled = true;
     778                break;
     779
    764780            default:
    765781                break;
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r230536 r230568  
    686686           
    687687        case StringFromCharCode:
    688             if (node->child1()->shouldSpeculateInt32())
     688            if (node->child1()->shouldSpeculateInt32()) {
    689689                fixEdge<Int32Use>(node->child1());
    690             else
     690                node->clearFlags(NodeMustGenerate);
     691            } else
    691692                fixEdge<UntypedUse>(node->child1());
    692693            break;
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h

    r225966 r230568  
    11/*
    2  * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#if ENABLE(DFG_JIT)
    2929
     30#include "DFGAbstractInterpreterClobberState.h"
    3031#include "DFGAbstractValue.h"
    3132#include "DFGBranchDirection.h"
     
    9192    void reset();
    9293   
     94    AbstractInterpreterClobberState clobberState() const { return m_clobberState; }
     95   
     96    // Would have the last executed node clobbered things had we not found a way to fold it?
     97    bool didClobberOrFolded() const { return clobberState() != AbstractInterpreterClobberState::NotClobbered; }
     98   
    9399    // Did the last executed node clobber the world?
    94     bool didClobber() const { return m_didClobber; }
     100    bool didClobber() const { return clobberState() == AbstractInterpreterClobberState::ClobberedStructures; }
    95101   
    96102    // Are structures currently clobbered?
     
    115121   
    116122    // Methods intended to be called from AbstractInterpreter.
    117     void setDidClobber(bool didClobber) { m_didClobber = didClobber; }
     123    void setClobberState(AbstractInterpreterClobberState state) { m_clobberState = state; }
     124    void mergeClobberState(AbstractInterpreterClobberState state) { m_clobberState = mergeClobberStates(m_clobberState, state); }
    118125    void setStructureClobberState(StructureClobberState value) { m_structureClobberState = value; }
    119126    void setIsValid(bool isValid) { m_isValid = isValid; }
     
    146153   
    147154    bool m_isValid;
    148     bool m_didClobber;
     155    AbstractInterpreterClobberState m_clobberState;
    149156    StructureClobberState m_structureClobberState;
    150157   
  • branches/safari-605-branch/Source/JavaScriptCore/dfg/DFGNodeType.h

    r230536 r230568  
    281281    macro(StringCharCodeAt, NodeResultInt32) \
    282282    macro(StringCharAt, NodeResultJS) \
    283     macro(StringFromCharCode, NodeResultJS) \
     283    macro(StringFromCharCode, NodeResultJS | NodeMustGenerate) \
    284284    \
    285285    /* Nodes for comparison operations. */\
Note: See TracChangeset for help on using the changeset viewer.