Changeset 126387 in webkit


Ignore:
Timestamp:
Aug 22, 2012 8:38:52 PM (12 years ago)
Author:
fpizlo@apple.com
Message:

Array accesses should remember what kind of array they are predicted to access
https://bugs.webkit.org/show_bug.cgi?id=94448

Reviewed by Gavin Barraclough.

Introduced the notion of DFG::Array::Mode, stored in node.arrayMode(), which allows nodes
to remember how they decided to access arrays. This permits the bytecode parser to "lock in"
the mode of access if it has profiling at its disposal, and it also allows the prediction
propagator to do a fixup of the array mode later in the optimization fixpoint.

This patch adds a healthy amount of new capability (specifically the ability of the parser
to lock in an array mode regardless of type predictions) and it also blows away a lot of
messy code.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGArgumentsSimplificationPhase.cpp:

(JSC::DFG::ArgumentsSimplificationPhase::run):

  • dfg/DFGArrayMode.cpp: Added.

(DFG):
(JSC::DFG::fromObserved):
(JSC::DFG::refineArrayMode):
(JSC::DFG::modeAlreadyChecked):
(JSC::DFG::modeToString):

  • dfg/DFGArrayMode.h: Added.

(DFG):
(JSC::DFG::canCSEStorage):
(JSC::DFG::modeForPut):
(JSC::DFG::modesCompatibleForStorageLoad):
(JSC::DFG::modeSupportsLength):

  • dfg/DFGByteCodeParser.cpp:

(ByteCodeParser):
(JSC::DFG::ByteCodeParser::getArrayModeWithoutOSRExit):
(JSC::DFG::ByteCodeParser::getArrayMode):
(JSC::DFG::ByteCodeParser::handleIntrinsic):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::getByValLoadElimination):
(JSC::DFG::CSEPhase::checkStructureLoadElimination):
(JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
(JSC::DFG::CSEPhase::getByOffsetLoadElimination):
(JSC::DFG::CSEPhase::putByOffsetStoreElimination):
(JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
(JSC::DFG::CSEPhase::performNodeCSE):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dump):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::byValIsPure):
(JSC::DFG::Graph::clobbersWorld):

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasArrayMode):
(Node):
(JSC::DFG::Node::arrayMode):
(JSC::DFG::Node::setArrayMode):

  • dfg/DFGNodeType.h:

(DFG):

  • dfg/DFGPredictionPropagationPhase.cpp:

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

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::typedArrayDescriptor):
(DFG):
(JSC::DFG::SpeculativeJIT::speculateArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
(JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):

  • dfg/DFGSpeculativeJIT.h:

(SpeculativeJIT):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • dfg/DFGStructureCheckHoistingPhase.cpp:

(JSC::DFG::StructureCheckHoistingPhase::run):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r126354 r126387  
    6767    dfg/DFGAbstractState.cpp
    6868    dfg/DFGArgumentsSimplificationPhase.cpp
     69    dfg/DFGArrayMode.cpp
    6970    dfg/DFGAssemblyHelpers.cpp
    7071    dfg/DFGByteCodeParser.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r126379 r126387  
     12012-08-22  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Array accesses should remember what kind of array they are predicted to access
     4        https://bugs.webkit.org/show_bug.cgi?id=94448
     5
     6        Reviewed by Gavin Barraclough.
     7
     8        Introduced the notion of DFG::Array::Mode, stored in node.arrayMode(), which allows nodes
     9        to remember how they decided to access arrays. This permits the bytecode parser to "lock in"
     10        the mode of access if it has profiling at its disposal, and it also allows the prediction
     11        propagator to do a fixup of the array mode later in the optimization fixpoint.
     12       
     13        This patch adds a healthy amount of new capability (specifically the ability of the parser
     14        to lock in an array mode regardless of type predictions) and it also blows away a lot of
     15        messy code.
     16
     17        * CMakeLists.txt:
     18        * GNUmakefile.list.am:
     19        * JavaScriptCore.xcodeproj/project.pbxproj:
     20        * Target.pri:
     21        * dfg/DFGAbstractState.cpp:
     22        (JSC::DFG::AbstractState::execute):
     23        * dfg/DFGArgumentsSimplificationPhase.cpp:
     24        (JSC::DFG::ArgumentsSimplificationPhase::run):
     25        * dfg/DFGArrayMode.cpp: Added.
     26        (DFG):
     27        (JSC::DFG::fromObserved):
     28        (JSC::DFG::refineArrayMode):
     29        (JSC::DFG::modeAlreadyChecked):
     30        (JSC::DFG::modeToString):
     31        * dfg/DFGArrayMode.h: Added.
     32        (DFG):
     33        (JSC::DFG::canCSEStorage):
     34        (JSC::DFG::modeForPut):
     35        (JSC::DFG::modesCompatibleForStorageLoad):
     36        (JSC::DFG::modeSupportsLength):
     37        * dfg/DFGByteCodeParser.cpp:
     38        (ByteCodeParser):
     39        (JSC::DFG::ByteCodeParser::getArrayModeWithoutOSRExit):
     40        (JSC::DFG::ByteCodeParser::getArrayMode):
     41        (JSC::DFG::ByteCodeParser::handleIntrinsic):
     42        (JSC::DFG::ByteCodeParser::parseBlock):
     43        * dfg/DFGCSEPhase.cpp:
     44        (JSC::DFG::CSEPhase::getByValLoadElimination):
     45        (JSC::DFG::CSEPhase::checkStructureLoadElimination):
     46        (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
     47        (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
     48        (JSC::DFG::CSEPhase::putByOffsetStoreElimination):
     49        (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
     50        (JSC::DFG::CSEPhase::performNodeCSE):
     51        * dfg/DFGFixupPhase.cpp:
     52        (JSC::DFG::FixupPhase::fixupNode):
     53        * dfg/DFGGraph.cpp:
     54        (JSC::DFG::Graph::dump):
     55        * dfg/DFGGraph.h:
     56        (JSC::DFG::Graph::byValIsPure):
     57        (JSC::DFG::Graph::clobbersWorld):
     58        * dfg/DFGNode.h:
     59        (JSC::DFG::Node::hasArrayMode):
     60        (Node):
     61        (JSC::DFG::Node::arrayMode):
     62        (JSC::DFG::Node::setArrayMode):
     63        * dfg/DFGNodeType.h:
     64        (DFG):
     65        * dfg/DFGPredictionPropagationPhase.cpp:
     66        (JSC::DFG::PredictionPropagationPhase::propagate):
     67        * dfg/DFGSpeculativeJIT.cpp:
     68        (JSC::DFG::SpeculativeJIT::typedArrayDescriptor):
     69        (DFG):
     70        (JSC::DFG::SpeculativeJIT::speculateArray):
     71        (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
     72        (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
     73        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
     74        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
     75        (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
     76        (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
     77        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
     78        * dfg/DFGSpeculativeJIT.h:
     79        (SpeculativeJIT):
     80        * dfg/DFGSpeculativeJIT32_64.cpp:
     81        (JSC::DFG::SpeculativeJIT::compile):
     82        * dfg/DFGSpeculativeJIT64.cpp:
     83        (JSC::DFG::SpeculativeJIT::compile):
     84        * dfg/DFGStructureCheckHoistingPhase.cpp:
     85        (JSC::DFG::StructureCheckHoistingPhase::run):
     86
    1872012-08-22  Geoffrey Garen  <ggaren@apple.com>
    288
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r126354 r126387  
    156156        Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp \
    157157        Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h \
     158        Source/JavaScriptCore/dfg/DFGArrayMode.cpp \
     159        Source/JavaScriptCore/dfg/DFGArrayMode.h \
    158160        Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp \
    159161        Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r126354 r126387  
    143143                0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63945115D07051006A597C /* ArrayProfile.cpp */; };
    144144                0F63945515D07057006A597C /* ArrayProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63945215D07051006A597C /* ArrayProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
     145                0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63948115E48114006A597C /* DFGArrayMode.cpp */; };
     146                0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63948215E48114006A597C /* DFGArrayMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    145147                0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
    146148                0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    900902                0F63945115D07051006A597C /* ArrayProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayProfile.cpp; sourceTree = "<group>"; };
    901903                0F63945215D07051006A597C /* ArrayProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayProfile.h; sourceTree = "<group>"; };
     904                0F63948115E48114006A597C /* DFGArrayMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArrayMode.cpp; path = dfg/DFGArrayMode.cpp; sourceTree = "<group>"; };
     905                0F63948215E48114006A597C /* DFGArrayMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayMode.h; path = dfg/DFGArrayMode.h; sourceTree = "<group>"; };
    902906                0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureAbstractValue.h; path = dfg/DFGStructureAbstractValue.h; sourceTree = "<group>"; };
    903907                0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
     
    22672271                        isa = PBXGroup;
    22682272                        children = (
     2273                                0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */,
     2274                                0F62016E143FCD2F0068B77C /* DFGAbstractState.h */,
     2275                                0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */,
     2276                                0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */,
    22692277                                0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
    22702278                                0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */,
    22712279                                0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */,
    2272                                 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */,
    2273                                 0F62016E143FCD2F0068B77C /* DFGAbstractState.h */,
    2274                                 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */,
     2280                                0F63948115E48114006A597C /* DFGArrayMode.cpp */,
     2281                                0F63948215E48114006A597C /* DFGArrayMode.h */,
    22752282                                0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */,
    22762283                                0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */,
     
    23162323                                0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */,
    23172324                                0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */,
    2318                                 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */,
    23192325                                0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */,
    23202326                                0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */,
     
    28962902                                0F63943F15C75F19006A597C /* DFGStructureCheckHoistingPhase.h in Headers */,
    28972903                                0F63945515D07057006A597C /* ArrayProfile.h in Headers */,
     2904                                0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */,
    28982905                                0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */,
    28992906                        );
     
    34973504                                0F63944015C75F1D006A597C /* DFGStructureCheckHoistingPhase.cpp in Sources */,
    34983505                                0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
     3506                                0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */,
    34993507                                C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */,
    35003508                        );
  • trunk/Source/JavaScriptCore/Target.pri

    r126354 r126387  
    9797    dfg/DFGAbstractState.cpp \
    9898    dfg/DFGArgumentsSimplificationPhase.cpp \
     99    dfg/DFGArrayMode.cpp \
    99100    dfg/DFGAssemblyHelpers.cpp \
    100101    dfg/DFGByteCodeParser.cpp \
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r125999 r126387  
    869869    case GetByVal: {
    870870        node.setCanExit(true);
    871         if (!node.prediction() || !m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction()) {
     871        switch (node.arrayMode()) {
     872        case Array::Undecided:
     873            ASSERT_NOT_REACHED();
     874            break;
     875        case Array::ForceExit:
    872876            m_isValid = false;
    873877            break;
    874         }
    875         if (!m_graph[node.child2()].shouldSpeculateInteger() || (!node.child3() && !m_graph[node.child1()].shouldSpeculateArguments())) {
     878        case Array::Generic:
    876879            clobberWorld(node.codeOrigin, indexInBlock);
    877880            forNode(nodeIndex).makeTop();
    878881            break;
    879         }
    880         if (m_graph[node.child1()].shouldSpeculateArguments()) {
     882        case Array::String:
     883            forNode(node.child1()).filter(SpecString);
     884            forNode(node.child2()).filter(SpecInt32);
     885            forNode(nodeIndex).set(SpecString);
     886            break;
     887        case Array::Arguments:
    881888            forNode(node.child1()).filter(SpecArguments);
    882889            forNode(node.child2()).filter(SpecInt32);
    883890            forNode(nodeIndex).makeTop();
    884891            break;
    885         }
    886         if (m_graph[node.child1()].prediction() == SpecString) {
    887             forNode(node.child1()).filter(SpecString);
     892        case Array::JSArray:
     893        case Array::JSArrayOutOfBounds:
     894            // FIXME: We should have more conservative handling of the out-of-bounds
     895            // case.
     896            forNode(node.child1()).filter(SpecCell);
    888897            forNode(node.child2()).filter(SpecInt32);
    889             forNode(nodeIndex).set(SpecString);
    890             break;
    891         }
    892        
    893         if (m_graph[node.child1()].shouldSpeculateInt8Array()) {
     898            forNode(nodeIndex).makeTop();
     899            break;
     900        case Array::Int8Array:
    894901            forNode(node.child1()).filter(SpecInt8Array);
    895902            forNode(node.child2()).filter(SpecInt32);
    896903            forNode(nodeIndex).set(SpecInt32);
    897904            break;
    898         }
    899         if (m_graph[node.child1()].shouldSpeculateInt16Array()) {
     905        case Array::Int16Array:
    900906            forNode(node.child1()).filter(SpecInt16Array);
    901907            forNode(node.child2()).filter(SpecInt32);
    902908            forNode(nodeIndex).set(SpecInt32);
    903909            break;
    904         }
    905         if (m_graph[node.child1()].shouldSpeculateInt32Array()) {
     910        case Array::Int32Array:
    906911            forNode(node.child1()).filter(SpecInt32Array);
    907912            forNode(node.child2()).filter(SpecInt32);
    908913            forNode(nodeIndex).set(SpecInt32);
    909914            break;
    910         }
    911         if (m_graph[node.child1()].shouldSpeculateUint8Array()) {
     915        case Array::Uint8Array:
    912916            forNode(node.child1()).filter(SpecUint8Array);
    913917            forNode(node.child2()).filter(SpecInt32);
    914918            forNode(nodeIndex).set(SpecInt32);
    915919            break;
    916         }
    917         if (m_graph[node.child1()].shouldSpeculateUint8ClampedArray()) {
     920        case Array::Uint8ClampedArray:
    918921            forNode(node.child1()).filter(SpecUint8ClampedArray);
    919922            forNode(node.child2()).filter(SpecInt32);
    920923            forNode(nodeIndex).set(SpecInt32);
    921924            break;
    922         }
    923         if (m_graph[node.child1()].shouldSpeculateUint16Array()) {
     925        case Array::Uint16Array:
    924926            forNode(node.child1()).filter(SpecUint16Array);
    925927            forNode(node.child2()).filter(SpecInt32);
    926928            forNode(nodeIndex).set(SpecInt32);
    927929            break;
    928         }
    929         if (m_graph[node.child1()].shouldSpeculateUint32Array()) {
     930        case Array::Uint32Array:
    930931            forNode(node.child1()).filter(SpecUint32Array);
    931932            forNode(node.child2()).filter(SpecInt32);
     
    935936                forNode(nodeIndex).set(SpecDouble);
    936937            break;
    937         }
    938         if (m_graph[node.child1()].shouldSpeculateFloat32Array()) {
     938        case Array::Float32Array:
    939939            forNode(node.child1()).filter(SpecFloat32Array);
    940940            forNode(node.child2()).filter(SpecInt32);
    941941            forNode(nodeIndex).set(SpecDouble);
    942942            break;
    943         }
    944         if (m_graph[node.child1()].shouldSpeculateFloat64Array()) {
     943        case Array::Float64Array:
    945944            forNode(node.child1()).filter(SpecFloat64Array);
    946945            forNode(node.child2()).filter(SpecInt32);
     
    948947            break;
    949948        }
    950         forNode(node.child1()).filter(SpecCell);
    951         forNode(node.child2()).filter(SpecInt32);
    952         forNode(nodeIndex).makeTop();
    953949        break;
    954950    }
    955951           
    956952    case PutByVal:
    957     case PutByValAlias:
    958     case PutByValSafe: {
    959         node.setCanExit(true);
    960 
     953    case PutByValAlias: {
     954        node.setCanExit(true);
    961955        Edge child1 = m_graph.varArgChild(node, 0);
    962956        Edge child2 = m_graph.varArgChild(node, 1);
    963957        Edge child3 = m_graph.varArgChild(node, 2);
    964            
    965         if (!m_graph[child1].prediction() || !m_graph[child2].prediction()) {
     958        switch (modeForPut(node.arrayMode())) {
     959        case Array::ForceExit:
    966960            m_isValid = false;
    967961            break;
    968         }
    969         if (!m_graph[child2].shouldSpeculateInteger()
    970 #if USE(JSVALUE32_64)
    971             || m_graph[child1].shouldSpeculateArguments()
    972 #endif
    973             ) {
    974             ASSERT(node.op() == PutByVal || node.op() == PutByValSafe);
     962        case Array::Generic:
    975963            clobberWorld(node.codeOrigin, indexInBlock);
    976             forNode(nodeIndex).makeTop();
    977             break;
    978         }
    979        
    980         if (m_graph[child1].shouldSpeculateArguments()) {
     964            break;
     965        case Array::JSArray:
     966            forNode(child1).filter(SpecCell);
     967            forNode(child2).filter(SpecInt32);
     968            break;
     969        case Array::JSArrayOutOfBounds:
     970            forNode(child1).filter(SpecCell);
     971            forNode(child2).filter(SpecInt32);
     972            clobberWorld(node.codeOrigin, indexInBlock);
     973            break;
     974        case Array::Arguments:
    981975            forNode(child1).filter(SpecArguments);
    982976            forNode(child2).filter(SpecInt32);
    983977            break;
    984         }
    985         if (m_graph[child1].shouldSpeculateInt8Array()) {
     978        case Array::Int8Array:
    986979            forNode(child1).filter(SpecInt8Array);
    987980            forNode(child2).filter(SpecInt32);
     
    991984                forNode(child3).filter(SpecNumber);
    992985            break;
    993         }
    994         if (m_graph[child1].shouldSpeculateInt16Array()) {
     986        case Array::Int16Array:
    995987            forNode(child1).filter(SpecInt16Array);
    996988            forNode(child2).filter(SpecInt32);
     
    1000992                forNode(child3).filter(SpecNumber);
    1001993            break;
    1002         }
    1003         if (m_graph[child1].shouldSpeculateInt32Array()) {
     994        case Array::Int32Array:
    1004995            forNode(child1).filter(SpecInt32Array);
    1005996            forNode(child2).filter(SpecInt32);
     
    10091000                forNode(child3).filter(SpecNumber);
    10101001            break;
    1011         }
    1012         if (m_graph[child1].shouldSpeculateUint8Array()) {
     1002        case Array::Uint8Array:
    10131003            forNode(child1).filter(SpecUint8Array);
    10141004            forNode(child2).filter(SpecInt32);
     
    10181008                forNode(child3).filter(SpecNumber);
    10191009            break;
    1020         }
    1021         if (m_graph[child1].shouldSpeculateUint8ClampedArray()) {
     1010        case Array::Uint8ClampedArray:
    10221011            forNode(child1).filter(SpecUint8ClampedArray);
    10231012            forNode(child2).filter(SpecInt32);
     
    10271016                forNode(child3).filter(SpecNumber);
    10281017            break;
    1029         }
    1030         if (m_graph[child1].shouldSpeculateUint16Array()) {
     1018        case Array::Uint16Array:
    10311019            forNode(child1).filter(SpecUint16Array);
    10321020            forNode(child2).filter(SpecInt32);
     
    10361024                forNode(child3).filter(SpecNumber);
    10371025            break;
    1038         }
    1039         if (m_graph[child1].shouldSpeculateUint32Array()) {
     1026        case Array::Uint32Array:
    10401027            forNode(child1).filter(SpecUint32Array);
    10411028            forNode(child2).filter(SpecInt32);
     
    10451032                forNode(child3).filter(SpecNumber);
    10461033            break;
    1047         }
    1048         if (m_graph[child1].shouldSpeculateFloat32Array()) {
     1034        case Array::Float32Array:
    10491035            forNode(child1).filter(SpecFloat32Array);
    10501036            forNode(child2).filter(SpecInt32);
    10511037            forNode(child3).filter(SpecNumber);
    10521038            break;
    1053         }
    1054         if (m_graph[child1].shouldSpeculateFloat64Array()) {
     1039        case Array::Float64Array:
    10551040            forNode(child1).filter(SpecFloat64Array);
    10561041            forNode(child2).filter(SpecInt32);
    10571042            forNode(child3).filter(SpecNumber);
    10581043            break;
    1059         }
    1060         forNode(child1).filter(SpecCell);
    1061         forNode(child2).filter(SpecInt32);
    1062         if (node.op() == PutByValSafe)
    1063             clobberWorld(node.codeOrigin, indexInBlock);
     1044        default:
     1045            ASSERT_NOT_REACHED();
     1046            break;
     1047        }
    10641048        break;
    10651049    }
     
    13571341           
    13581342    case GetArrayLength:
    1359         node.setCanExit(true);
    1360         forNode(node.child1()).filter(SpecCell);
    1361         forNode(nodeIndex).set(SpecInt32);
    1362         break;
    1363 
    1364     case GetArgumentsLength:
    1365         node.setCanExit(true);
    1366         forNode(node.child1()).filter(SpecArguments);
    1367         forNode(nodeIndex).set(SpecInt32);
    1368         break;
    1369 
    1370     case GetStringLength:
    1371         node.setCanExit(!isStringSpeculation(forNode(node.child1()).m_type));
    1372         forNode(node.child1()).filter(SpecString);
    1373         forNode(nodeIndex).set(SpecInt32);
    1374         break;
    1375        
    1376     case GetInt8ArrayLength:
    1377         node.setCanExit(!isInt8ArraySpeculation(forNode(node.child1()).m_type));
    1378         forNode(node.child1()).filter(SpecInt8Array);
    1379         forNode(nodeIndex).set(SpecInt32);
    1380         break;
    1381     case GetInt16ArrayLength:
    1382         node.setCanExit(!isInt16ArraySpeculation(forNode(node.child1()).m_type));
    1383         forNode(node.child1()).filter(SpecInt16Array);
    1384         forNode(nodeIndex).set(SpecInt32);
    1385         break;
    1386     case GetInt32ArrayLength:
    1387         node.setCanExit(!isInt32ArraySpeculation(forNode(node.child1()).m_type));
    1388         forNode(node.child1()).filter(SpecInt32Array);
    1389         forNode(nodeIndex).set(SpecInt32);
    1390         break;
    1391     case GetUint8ArrayLength:
    1392         node.setCanExit(!isUint8ArraySpeculation(forNode(node.child1()).m_type));
    1393         forNode(node.child1()).filter(SpecUint8Array);
    1394         forNode(nodeIndex).set(SpecInt32);
    1395         break;
    1396     case GetUint8ClampedArrayLength:
    1397         node.setCanExit(!isUint8ClampedArraySpeculation(forNode(node.child1()).m_type));
    1398         forNode(node.child1()).filter(SpecUint8ClampedArray);
    1399         forNode(nodeIndex).set(SpecInt32);
    1400         break;
    1401     case GetUint16ArrayLength:
    1402         node.setCanExit(!isUint16ArraySpeculation(forNode(node.child1()).m_type));
    1403         forNode(node.child1()).filter(SpecUint16Array);
    1404         forNode(nodeIndex).set(SpecInt32);
    1405         break;
    1406     case GetUint32ArrayLength:
    1407         node.setCanExit(!isUint32ArraySpeculation(forNode(node.child1()).m_type));
    1408         forNode(node.child1()).filter(SpecUint32Array);
    1409         forNode(nodeIndex).set(SpecInt32);
    1410         break;
    1411     case GetFloat32ArrayLength:
    1412         node.setCanExit(!isFloat32ArraySpeculation(forNode(node.child1()).m_type));
    1413         forNode(node.child1()).filter(SpecFloat32Array);
    1414         forNode(nodeIndex).set(SpecInt32);
    1415         break;
    1416     case GetFloat64ArrayLength:
    1417         node.setCanExit(!isFloat64ArraySpeculation(forNode(node.child1()).m_type));
    1418         forNode(node.child1()).filter(SpecFloat64Array);
    1419         forNode(nodeIndex).set(SpecInt32);
    1420         break;
    1421            
     1343        switch (node.arrayMode()) {
     1344        case Array::Undecided:
     1345            ASSERT_NOT_REACHED();
     1346            break;
     1347        case Array::ForceExit:
     1348            m_isValid = false;
     1349            break;
     1350        case Array::Generic:
     1351            ASSERT_NOT_REACHED();
     1352            break;
     1353        case Array::String:
     1354            node.setCanExit(!isStringSpeculation(forNode(node.child1()).m_type));
     1355            forNode(node.child1()).filter(SpecString);
     1356            forNode(nodeIndex).set(SpecInt32);
     1357            break;
     1358        case Array::JSArray:
     1359            node.setCanExit(true);
     1360            forNode(node.child1()).filter(SpecCell);
     1361            forNode(nodeIndex).set(SpecInt32);
     1362            break;
     1363        case Array::JSArrayOutOfBounds:
     1364            ASSERT_NOT_REACHED();
     1365            break;
     1366        case Array::Arguments:
     1367            node.setCanExit(true);
     1368            forNode(node.child1()).filter(SpecArguments);
     1369            forNode(nodeIndex).set(SpecInt32);
     1370            break;
     1371        case Array::Int8Array:
     1372            node.setCanExit(!isInt8ArraySpeculation(forNode(node.child1()).m_type));
     1373            forNode(node.child1()).filter(SpecInt8Array);
     1374            forNode(nodeIndex).set(SpecInt32);
     1375            break;
     1376        case Array::Int16Array:
     1377            node.setCanExit(!isInt16ArraySpeculation(forNode(node.child1()).m_type));
     1378            forNode(node.child1()).filter(SpecInt16Array);
     1379            forNode(nodeIndex).set(SpecInt32);
     1380            break;
     1381        case Array::Int32Array:
     1382            node.setCanExit(!isInt32ArraySpeculation(forNode(node.child1()).m_type));
     1383            forNode(node.child1()).filter(SpecInt32Array);
     1384            forNode(nodeIndex).set(SpecInt32);
     1385            break;
     1386        case Array::Uint8Array:
     1387            node.setCanExit(!isUint8ArraySpeculation(forNode(node.child1()).m_type));
     1388            forNode(node.child1()).filter(SpecUint8Array);
     1389            forNode(nodeIndex).set(SpecInt32);
     1390            break;
     1391        case Array::Uint8ClampedArray:
     1392            node.setCanExit(!isUint8ClampedArraySpeculation(forNode(node.child1()).m_type));
     1393            forNode(node.child1()).filter(SpecUint8ClampedArray);
     1394            forNode(nodeIndex).set(SpecInt32);
     1395            break;
     1396        case Array::Uint16Array:
     1397            node.setCanExit(!isUint16ArraySpeculation(forNode(node.child1()).m_type));
     1398            forNode(node.child1()).filter(SpecUint16Array);
     1399            forNode(nodeIndex).set(SpecInt32);
     1400            break;
     1401        case Array::Uint32Array:
     1402            node.setCanExit(!isUint32ArraySpeculation(forNode(node.child1()).m_type));
     1403            forNode(node.child1()).filter(SpecUint32Array);
     1404            forNode(nodeIndex).set(SpecInt32);
     1405            break;
     1406        case Array::Float32Array:
     1407            node.setCanExit(!isFloat32ArraySpeculation(forNode(node.child1()).m_type));
     1408            forNode(node.child1()).filter(SpecFloat32Array);
     1409            forNode(nodeIndex).set(SpecInt32);
     1410            break;
     1411        case Array::Float64Array:
     1412            node.setCanExit(!isFloat64ArraySpeculation(forNode(node.child1()).m_type));
     1413            forNode(node.child1()).filter(SpecFloat64Array);
     1414            forNode(nodeIndex).set(SpecInt32);
     1415            break;
     1416        }
     1417        break;
     1418
    14221419    case CheckStructure:
    14231420    case ForwardCheckStructure: {
     
    14901487        break;
    14911488    case GetIndexedPropertyStorage: {
    1492         ASSERT(m_graph[node.child1()].prediction());
    1493         ASSERT(m_graph[node.child2()].shouldSpeculateInteger());
    14941489        node.setCanExit(true); // Lies, but this is (almost) always followed by GetByVal, which does exit. So no point in trying to be more precise.
    1495         if (m_graph[node.child1()].shouldSpeculateArguments()) {
     1490        switch (node.arrayMode()) {
     1491        case Array::String:
     1492            forNode(node.child1()).filter(SpecString);
     1493            break;
     1494        case Array::JSArray:
     1495        case Array::JSArrayOutOfBounds:
     1496            // This doesn't filter anything meaningful right now. We may want to add
     1497            // CFA tracking of array mode speculations, but we don't have that, yet.
     1498            forNode(node.child1()).filter(SpecCell);
     1499            break;
     1500        case Array::Int8Array:
     1501            forNode(node.child1()).filter(SpecInt8Array);
     1502            break;
     1503        case Array::Int16Array:
     1504            forNode(node.child1()).filter(SpecInt16Array);
     1505            break;
     1506        case Array::Int32Array:
     1507            forNode(node.child1()).filter(SpecInt32Array);
     1508            break;
     1509        case Array::Uint8Array:
     1510            forNode(node.child1()).filter(SpecUint8Array);
     1511            break;
     1512        case Array::Uint8ClampedArray:
     1513            forNode(node.child1()).filter(SpecUint8ClampedArray);
     1514            break;
     1515        case Array::Uint16Array:
     1516            forNode(node.child1()).filter(SpecUint16Array);
     1517            break;
     1518        case Array::Uint32Array:
     1519            forNode(node.child1()).filter(SpecUint32Array);
     1520            break;
     1521        case Array::Float32Array:
     1522            forNode(node.child1()).filter(SpecFloat32Array);
     1523            break;
     1524        case Array::Float64Array:
     1525            forNode(node.child1()).filter(SpecFloat64Array);
     1526            break;
     1527        default:
    14961528            ASSERT_NOT_REACHED();
    14971529            break;
    14981530        }
    1499         if (m_graph[node.child1()].prediction() == SpecString) {
    1500             forNode(node.child1()).filter(SpecString);
    1501             forNode(nodeIndex).clear();
    1502             break;
    1503         }
    1504        
    1505         if (m_graph[node.child1()].shouldSpeculateInt8Array()) {
    1506             forNode(node.child1()).filter(SpecInt8Array);
    1507             forNode(nodeIndex).clear();
    1508             break;
    1509         }
    1510         if (m_graph[node.child1()].shouldSpeculateInt16Array()) {
    1511             forNode(node.child1()).filter(SpecInt16Array);
    1512             forNode(nodeIndex).clear();
    1513             break;
    1514         }
    1515         if (m_graph[node.child1()].shouldSpeculateInt32Array()) {
    1516             forNode(node.child1()).filter(SpecInt32Array);
    1517             forNode(nodeIndex).clear();
    1518             break;
    1519         }
    1520         if (m_graph[node.child1()].shouldSpeculateUint8Array()) {
    1521             forNode(node.child1()).filter(SpecUint8Array);
    1522             forNode(nodeIndex).clear();
    1523             break;
    1524         }
    1525         if (m_graph[node.child1()].shouldSpeculateUint8ClampedArray()) {
    1526             forNode(node.child1()).filter(SpecUint8ClampedArray);
    1527             forNode(nodeIndex).clear();
    1528             break;
    1529         }
    1530         if (m_graph[node.child1()].shouldSpeculateUint16Array()) {
    1531             forNode(node.child1()).filter(SpecUint16Array);
    1532             forNode(nodeIndex).set(SpecOther);
    1533             break;
    1534         }
    1535         if (m_graph[node.child1()].shouldSpeculateUint32Array()) {
    1536             forNode(node.child1()).filter(SpecUint32Array);
    1537             forNode(nodeIndex).clear();
    1538             break;
    1539         }
    1540         if (m_graph[node.child1()].shouldSpeculateFloat32Array()) {
    1541             forNode(node.child1()).filter(SpecFloat32Array);
    1542             forNode(nodeIndex).clear();
    1543             break;
    1544         }
    1545         if (m_graph[node.child1()].shouldSpeculateFloat64Array()) {
    1546             forNode(node.child1()).filter(SpecFloat64Array);
    1547             forNode(nodeIndex).clear();
    1548             break;
    1549         }
    1550         forNode(node.child1()).filter(SpecCell);
    15511531        forNode(nodeIndex).clear();
    15521532        break;
  • trunk/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp

    r125999 r126387  
    146146       
    147147        // Figure out which variables alias the arguments and nothing else, and are
    148         // used only for GetByVal and GetArgumentsLength accesses. At the same time,
     148        // used only for GetByVal and GetArrayLength accesses. At the same time,
    149149        // identify uses of CreateArguments that are not consistent with the arguments
    150150        // being aliased only to variables that satisfy these constraints.
     
    278278                   
    279279                case GetByVal: {
    280                     if (!node.prediction()
    281                         || !m_graph[node.child1()].prediction()
    282                         || !m_graph[node.child2()].prediction()) {
     280                    if (node.arrayMode() != Array::Arguments) {
    283281                        observeBadArgumentsUses(node);
    284282                        break;
    285283                    }
    286                    
    287                     if (!isActionableArraySpeculation(m_graph[node.child1()].prediction())
    288                         || !m_graph[node.child2()].shouldSpeculateInteger()) {
     284
     285                    // That's so awful and pretty much impossible since it would
     286                    // imply that the arguments were predicted integer, but it's
     287                    // good to be defensive and thorough.
     288                    observeBadArgumentsUse(node.child2());
     289                    observeProperArgumentsUse(node, node.child1());
     290                    break;
     291                }
     292                   
     293                case GetArrayLength: {
     294                    if (node.arrayMode() != Array::Arguments) {
    289295                        observeBadArgumentsUses(node);
    290296                        break;
    291297                    }
    292                    
    293                     if (m_graph[node.child1()].shouldSpeculateArguments()) {
    294                         // If arguments is used as an index, then it's an escaping use.
    295                         // That's so awful and pretty much impossible since it would
    296                         // imply that the arguments were predicted integer, but it's
    297                         // good to be defensive and thorough.
    298                         observeBadArgumentsUse(node.child2());
    299                         observeProperArgumentsUse(node, node.child1());
    300                         break;
    301                     }
    302                    
    303                     observeBadArgumentsUses(node);
    304                     break;
    305                 }
    306                    
    307                 case GetArgumentsLength: {
     298                       
    308299                    observeProperArgumentsUse(node, node.child1());
    309300                    break;
     
    497488                   
    498489                case GetByVal: {
    499                     if (!node.prediction()
    500                         || !m_graph[node.child1()].prediction()
    501                         || !m_graph[node.child2()].prediction())
    502                         break;
    503                    
    504                     if (!isActionableArraySpeculation(m_graph[node.child1()].prediction())
    505                         || !m_graph[node.child2()].shouldSpeculateInteger())
    506                         break;
    507                    
    508                     if (m_graph[node.child1()].shouldSpeculateArguments()) {
    509                         // This can be simplified to GetMyArgumentByVal if we know that
    510                         // it satisfies either condition (1) or (2):
    511                         // 1) Its first child is a valid ArgumentsAliasingData and the
    512                         //    InlineCallFrame* is not marked as creating arguments.
    513                         // 2) Its first child is CreateArguments and its InlineCallFrame*
    514                         //    is not marked as creating arguments.
    515                        
    516                         if (!isOKToOptimize(m_graph[node.child1()]))
    517                             break;
    518                        
    519                         m_graph.deref(node.child1());
    520                         node.children.child1() = node.children.child2();
    521                         node.children.child2() = Edge();
    522                         node.setOpAndDefaultFlags(GetMyArgumentByVal);
    523                         changed = true;
    524                         --indexInBlock; // Force reconsideration of this op now that it's a GetMyArgumentByVal.
    525                         break;
    526                     }
    527                     break;
    528                 }
    529                    
    530                 case GetArgumentsLength: {
     490                    if (node.arrayMode() != Array::Arguments)
     491                        break;
     492
     493                    // This can be simplified to GetMyArgumentByVal if we know that
     494                    // it satisfies either condition (1) or (2):
     495                    // 1) Its first child is a valid ArgumentsAliasingData and the
     496                    //    InlineCallFrame* is not marked as creating arguments.
     497                    // 2) Its first child is CreateArguments and its InlineCallFrame*
     498                    //    is not marked as creating arguments.
     499                   
     500                    if (!isOKToOptimize(m_graph[node.child1()]))
     501                        break;
     502                   
     503                    m_graph.deref(node.child1());
     504                    node.children.child1() = node.children.child2();
     505                    node.children.child2() = Edge();
     506                    node.setOpAndDefaultFlags(GetMyArgumentByVal);
     507                    changed = true;
     508                    --indexInBlock; // Force reconsideration of this op now that it's a GetMyArgumentByVal.
     509                    break;
     510                }
     511                   
     512                case GetArrayLength: {
     513                    if (node.arrayMode() != Array::Arguments)
     514                        break;
     515                   
    531516                    if (!isOKToOptimize(m_graph[node.child1()]))
    532517                        break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r125982 r126387  
    3232#include "CallLinkStatus.h"
    3333#include "CodeBlock.h"
     34#include "DFGArrayMode.h"
    3435#include "DFGByteCodeCache.h"
    3536#include "DFGCapabilities.h"
     
    817818        return getPrediction(m_graph.size(), m_currentProfilingIndex);
    818819    }
     820   
     821    Array::Mode getArrayModeWithoutOSRExit(Instruction* currentInstruction, NodeIndex base)
     822    {
     823        ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
     824        profile->computeUpdatedPrediction();
     825        if (profile->hasDefiniteStructure())
     826            addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(profile->expectedStructure())), base);
     827       
     828#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
     829        if (m_inlineStackTop->m_profiledBlock->numberOfRareCaseProfiles())
     830            dataLog("Slow case profile for bc#%u: %u\n", m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter);
     831        dataLog("Array profile for bc#%u: %p%s, %u\n", m_currentIndex, profile->expectedStructure(), profile->structureIsPolymorphic() ? " (polymorphic)" : "", profile->observedArrayModes());
     832#endif
     833       
     834        bool makeSafe =
     835            m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
     836            || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds);
     837       
     838        return fromObserved(profile->observedArrayModes(), makeSafe);
     839    }
     840   
     841    Array::Mode getArrayMode(Instruction* currentInstruction, NodeIndex base)
     842    {
     843        Array::Mode result = getArrayModeWithoutOSRExit(currentInstruction, base);
     844       
     845        if (result == Array::ForceExit)
     846            addToGraph(ForceOSRExit);
     847       
     848        return result;
     849    }
    819850
    820851    NodeIndex makeSafe(NodeIndex nodeIndex)
     
    15491580       
    15501581        int indexOperand = registerOffset + argumentToOperand(1);
    1551         NodeIndex storage = addToGraph(GetIndexedPropertyStorage, get(thisOperand), getToInt32(indexOperand));
    1552         NodeIndex charCode = addToGraph(StringCharCodeAt, get(thisOperand), getToInt32(indexOperand), storage);
     1582        NodeIndex charCode = addToGraph(StringCharCodeAt, OpInfo(Array::String), get(thisOperand), getToInt32(indexOperand));
    15531583
    15541584        if (usesResult)
     
    15661596
    15671597        int indexOperand = registerOffset + argumentToOperand(1);
    1568         NodeIndex storage = addToGraph(GetIndexedPropertyStorage, get(thisOperand), getToInt32(indexOperand));
    1569         NodeIndex charCode = addToGraph(StringCharAt, get(thisOperand), getToInt32(indexOperand), storage);
     1598        NodeIndex charCode = addToGraph(StringCharAt, OpInfo(Array::String), get(thisOperand), getToInt32(indexOperand));
    15701599
    15711600        if (usesResult)
     
    21492178           
    21502179            NodeIndex base = get(currentInstruction[2].u.operand);
     2180            Array::Mode arrayMode = getArrayMode(currentInstruction, base);
    21512181            NodeIndex property = get(currentInstruction[3].u.operand);
    2152             ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
    2153             profile->computeUpdatedPrediction();
    2154             if (profile->hasDefiniteStructure())
    2155                 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(profile->expectedStructure())), base);
    2156             NodeIndex propertyStorage = addToGraph(GetIndexedPropertyStorage, base, property);
    2157             NodeIndex getByVal = addToGraph(GetByVal, OpInfo(0), OpInfo(prediction), base, property, propertyStorage);
     2182            NodeIndex getByVal = addToGraph(GetByVal, OpInfo(arrayMode), OpInfo(prediction), base, property);
    21582183            set(currentInstruction[1].u.operand, getByVal);
    21592184
     
    21632188        case op_put_by_val: {
    21642189            NodeIndex base = get(currentInstruction[1].u.operand);
     2190
     2191            Array::Mode arrayMode = getArrayMode(currentInstruction, base);
     2192           
    21652193            NodeIndex property = get(currentInstruction[2].u.operand);
    21662194            NodeIndex value = get(currentInstruction[3].u.operand);
    2167            
    2168             ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
    2169             profile->computeUpdatedPrediction();
    2170             if (profile->hasDefiniteStructure())
    2171                 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(profile->expectedStructure())), base);
    2172 
    2173 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
    2174             dataLog("Slow case profile for bc#%u: %u\n", m_currentIndex, m_inlineStackTop->m_profiledBlock->rareCaseProfileForBytecodeOffset(m_currentIndex)->m_counter);
    2175 #endif
    2176 
    2177             bool makeSafe =
    2178                 m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
    2179                 || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds);
    21802195           
    21812196            addVarArgChild(base);
    21822197            addVarArgChild(property);
    21832198            addVarArgChild(value);
    2184             addToGraph(Node::VarArg, makeSafe ? PutByValSafe : PutByVal, OpInfo(0), OpInfo(0));
     2199            addToGraph(Node::VarArg, PutByVal, OpInfo(arrayMode), OpInfo(0));
    21852200
    21862201            NEXT_OPCODE(op_put_by_val);
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r125999 r126387  
    285285                break;
    286286            case PutByVal:
    287             case PutByValAlias:
    288             case PutByValSafe: {
     287            case PutByValAlias: {
    289288                if (!m_graph.byValIsPure(node))
    290289                    return NoNode;
     
    366365            case PutByVal:
    367366            case PutByValAlias:
    368             case PutByValSafe:
    369367                if (m_graph.byValIsPure(node)) {
    370368                    // If PutByVal speculates that it's accessing an array with an
     
    410408            case PutByVal:
    411409            case PutByValAlias:
    412             case PutByValSafe:
    413410                if (m_graph.byValIsPure(node)) {
    414411                    // If PutByVal speculates that it's accessing an array with an
     
    516513            case PutByVal:
    517514            case PutByValAlias:
    518             case PutByValSafe:
    519515                if (m_graph.byValIsPure(node)) {
    520516                    // If PutByVal speculates that it's accessing an array with an
     
    561557            case PutByValAlias:
    562558            case GetByVal:
    563             case PutByValSafe:
    564559                if (m_graph.byValIsPure(node)) {
    565560                    // If PutByVal speculates that it's accessing an array with an
     
    614609            case PutByVal:
    615610            case PutByValAlias:
    616             case PutByValSafe:
    617611                if (m_graph.byValIsPure(node)) {
    618612                    // If PutByVal speculates that it's accessing an array with an
     
    926920        case ArithMax:
    927921        case ArithSqrt:
    928         case GetInt8ArrayLength:
    929         case GetInt16ArrayLength:
    930         case GetInt32ArrayLength:
    931         case GetUint8ArrayLength:
    932         case GetUint8ClampedArrayLength:
    933         case GetUint16ArrayLength:
    934         case GetUint32ArrayLength:
    935         case GetFloat32ArrayLength:
    936         case GetFloat64ArrayLength:
    937922        case GetCallee:
    938         case GetStringLength:
    939923        case StringCharAt:
    940924        case StringCharCodeAt:
     
    11041088            break;
    11051089           
    1106         case PutByVal:
    1107         case PutByValSafe: {
     1090        case PutByVal: {
    11081091            Edge child1 = m_graph.varArgChild(node, 0);
    11091092            Edge child2 = m_graph.varArgChild(node, 1);
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r125637 r126387  
    7575        switch (op) {
    7676        case GetById: {
     77            Node* nodePtr = &node;
     78           
    7779            if (!isInt32Speculation(m_graph[m_compileIndex].prediction()))
    7880                break;
    79             if (codeBlock()->identifier(node.identifierNumber()) != globalData().propertyNames->length)
    80                 break;
    81             bool isArray = isArraySpeculation(m_graph[node.child1()].prediction());
    82             bool isArguments = isArgumentsSpeculation(m_graph[node.child1()].prediction());
    83             bool isString = isStringSpeculation(m_graph[node.child1()].prediction());
    84             bool isInt8Array = m_graph[node.child1()].shouldSpeculateInt8Array();
    85             bool isInt16Array = m_graph[node.child1()].shouldSpeculateInt16Array();
    86             bool isInt32Array = m_graph[node.child1()].shouldSpeculateInt32Array();
    87             bool isUint8Array = m_graph[node.child1()].shouldSpeculateUint8Array();
    88             bool isUint8ClampedArray = m_graph[node.child1()].shouldSpeculateUint8ClampedArray();
    89             bool isUint16Array = m_graph[node.child1()].shouldSpeculateUint16Array();
    90             bool isUint32Array = m_graph[node.child1()].shouldSpeculateUint32Array();
    91             bool isFloat32Array = m_graph[node.child1()].shouldSpeculateFloat32Array();
    92             bool isFloat64Array = m_graph[node.child1()].shouldSpeculateFloat64Array();
    93             if (!isArray && !isArguments && !isString && !isInt8Array && !isInt16Array && !isInt32Array && !isUint8Array && !isUint8ClampedArray && !isUint16Array && !isUint32Array && !isFloat32Array && !isFloat64Array)
    94                 break;
    95            
    96 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
    97             dataLog("  @%u -> %s", m_compileIndex, isArray ? "GetArrayLength" : "GetStringLength");
    98 #endif
    99             if (isArray) {
    100                 node.setOp(GetArrayLength);
    101                 ASSERT(node.flags() & NodeMustGenerate);
    102                 node.clearFlags(NodeMustGenerate);
    103                 m_graph.deref(m_compileIndex);
    104                
    105                 ArrayProfile* arrayProfile =
    106                     m_graph.baselineCodeBlockFor(node.codeOrigin)->getArrayProfile(
    107                         node.codeOrigin.bytecodeIndex);
    108                 if (!arrayProfile)
    109                     break;
     81            if (codeBlock()->identifier(nodePtr->identifierNumber()) != globalData().propertyNames->length)
     82                break;
     83            ArrayProfile* arrayProfile =
     84                m_graph.baselineCodeBlockFor(nodePtr->codeOrigin)->getArrayProfile(
     85                    nodePtr->codeOrigin.bytecodeIndex);
     86            Array::Mode arrayMode = Array::Undecided;
     87            if (arrayProfile) {
    11088                arrayProfile->computeUpdatedPrediction();
    111                 if (!arrayProfile->hasDefiniteStructure())
    112                     break;
    113                 m_graph.ref(node.child1());
    114                 Node checkStructure(CheckStructure, node.codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())), node.child1().index());
    115                 checkStructure.ref();
    116                 NodeIndex checkStructureIndex = m_graph.size();
    117                 m_graph.append(checkStructure);
    118                 m_insertionSet.append(m_indexInBlock, checkStructureIndex);
    119                 break;
    120             }
    121             if (isArguments)
    122                 node.setOp(GetArgumentsLength);
    123             else if (isString)
    124                 node.setOp(GetStringLength);
    125             else if (isInt8Array)
    126                 node.setOp(GetInt8ArrayLength);
    127             else if (isInt16Array)
    128                 node.setOp(GetInt16ArrayLength);
    129             else if (isInt32Array)
    130                 node.setOp(GetInt32ArrayLength);
    131             else if (isUint8Array)
    132                 node.setOp(GetUint8ArrayLength);
    133             else if (isUint8ClampedArray)
    134                 node.setOp(GetUint8ClampedArrayLength);
    135             else if (isUint16Array)
    136                 node.setOp(GetUint16ArrayLength);
    137             else if (isUint32Array)
    138                 node.setOp(GetUint32ArrayLength);
    139             else if (isFloat32Array)
    140                 node.setOp(GetFloat32ArrayLength);
    141             else if (isFloat64Array)
    142                 node.setOp(GetFloat64ArrayLength);
    143             else
    144                 ASSERT_NOT_REACHED();
    145             // No longer MustGenerate
    146             ASSERT(node.flags() & NodeMustGenerate);
    147             node.clearFlags(NodeMustGenerate);
     89                arrayMode = refineArrayMode(
     90                    fromObserved(arrayProfile->observedArrayModes(), false),
     91                    m_graph[node.child1()].prediction(),
     92                    m_graph[m_compileIndex].prediction());                   
     93                if (modeSupportsLength(arrayMode)
     94                    && arrayProfile->hasDefiniteStructure()) {
     95                    m_graph.ref(nodePtr->child1());
     96                    Node checkStructure(CheckStructure, nodePtr->codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())), nodePtr->child1().index());
     97                    checkStructure.ref();
     98                    NodeIndex checkStructureIndex = m_graph.size();
     99                    m_graph.append(checkStructure);
     100                    m_insertionSet.append(m_indexInBlock, checkStructureIndex);
     101                    nodePtr = &m_graph[m_compileIndex];
     102                }
     103            } else {
     104                arrayMode = refineArrayMode(
     105                    arrayMode,
     106                    m_graph[node.child1()].prediction(),
     107                    m_graph[m_compileIndex].prediction());
     108            }
     109            if (!modeSupportsLength(arrayMode))
     110                break;
     111            nodePtr->setOp(GetArrayLength);
     112            ASSERT(nodePtr->flags() & NodeMustGenerate);
     113            nodePtr->clearFlags(NodeMustGenerate);
    148114            m_graph.deref(m_compileIndex);
     115            nodePtr->setArrayMode(arrayMode);
    149116            break;
    150117        }
    151118        case GetIndexedPropertyStorage: {
    152             if (!m_graph[node.child1()].prediction()
    153                 || !m_graph[node.child2()].shouldSpeculateInteger()
    154                 || m_graph[node.child1()].shouldSpeculateArguments()) {
    155                 node.setOpAndDefaultFlags(Nop);
    156                 m_graph.clearAndDerefChild1(node);
    157                 m_graph.clearAndDerefChild2(node);
    158                 m_graph.clearAndDerefChild3(node);
    159                 node.setRefCount(0);
    160             }
     119            node.setArrayMode(
     120                refineArrayMode(
     121                    node.arrayMode(),
     122                    m_graph[node.child1()].prediction(),
     123                    m_graph[node.child2()].prediction()));
     124            // Predictions should only become more, rather than less, refined. Hence
     125            // if we were ever able to CSE the storage pointer for this operation,
     126            // then we should always continue to be able to do so.
     127            ASSERT(canCSEStorage(node.arrayMode()));
    161128            break;
    162129        }
     
    164131        case StringCharAt:
    165132        case StringCharCodeAt: {
    166             if (!!node.child3() && m_graph[node.child3()].op() == Nop)
    167                 node.children.child3() = Edge();
     133            node.setArrayMode(
     134                refineArrayMode(
     135                    node.arrayMode(),
     136                    m_graph[node.child1()].prediction(),
     137                    m_graph[node.child2()].prediction()));
     138           
     139            if (canCSEStorage(node.arrayMode())) {
     140                if (node.child3()) {
     141                    ASSERT(m_graph[node.child3()].op() == GetIndexedPropertyStorage);
     142                    ASSERT(modesCompatibleForStorageLoad(m_graph[node.child3()].arrayMode(), node.arrayMode()));
     143                } else {
     144                    // Make sure we don't use the node reference after we do the append.
     145                    Node getIndexedPropertyStorage(
     146                        GetIndexedPropertyStorage, node.codeOrigin, OpInfo(node.arrayMode()),
     147                        node.child1().index(), node.child2().index());
     148                    NodeIndex getIndexedPropertyStorageIndex = m_graph.size();
     149                    node.children.child3() = Edge(getIndexedPropertyStorageIndex);
     150                    m_graph.append(getIndexedPropertyStorage);
     151                    m_graph.ref(getIndexedPropertyStorageIndex); // Once because it's MustGenerate.
     152                    m_graph.ref(getIndexedPropertyStorageIndex); // And again because it's referenced from the GetByVal.
     153                    m_insertionSet.append(m_indexInBlock, getIndexedPropertyStorageIndex);
     154                }
     155            } else {
     156                // See above. Continued fixup of the graph should not regress our ability
     157                // to speculate.
     158                ASSERT(!node.child3());
     159            }
    168160            break;
    169161        }
     
    335327           
    336328        case PutByVal:
    337         case PutByValSafe: {
     329        case PutByValAlias: {
    338330            Edge child1 = m_graph.varArgChild(node, 0);
    339331            Edge child2 = m_graph.varArgChild(node, 1);
    340332            Edge child3 = m_graph.varArgChild(node, 2);
    341             if (!m_graph[child1].prediction() || !m_graph[child2].prediction())
    342                 break;
    343             if (!m_graph[child2].shouldSpeculateInteger())
    344                 break;
    345             if (isActionableIntMutableArraySpeculation(m_graph[child1].prediction())) {
    346                 if (m_graph[child3].isConstant())
    347                     break;
    348                 if (m_graph[child3].shouldSpeculateInteger())
    349                     break;
     333            node.setArrayMode(
     334                refineArrayMode(
     335                    node.arrayMode(), m_graph[child1].prediction(), m_graph[child2].prediction()));
     336           
     337            switch (modeForPut(node.arrayMode())) {
     338            case Array::Int8Array:
     339            case Array::Int16Array:
     340            case Array::Int32Array:
     341            case Array::Uint8Array:
     342            case Array::Uint8ClampedArray:
     343            case Array::Uint16Array:
     344            case Array::Uint32Array:
     345                if (!m_graph[child3].shouldSpeculateInteger())
     346                    fixDoubleEdge(2);
     347                break;
     348            case Array::Float32Array:
     349            case Array::Float64Array:
    350350                fixDoubleEdge(2);
    351351                break;
    352             }
    353             if (isActionableFloatMutableArraySpeculation(m_graph[child1].prediction())) {
    354                 fixDoubleEdge(2);
     352            default:
    355353                break;
    356354            }
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r124555 r126387  
    212212        hasPrinted = true;
    213213    }
     214    if (node.hasArrayMode()) {
     215        dataLog("%s%s", hasPrinted ? ", " : "", modeToString(node.arrayMode()));
     216        hasPrinted = true;
     217    }
    214218    if (node.hasVarNumber()) {
    215219        dataLog("%svar%u", hasPrinted ? ", " : "", node.varNumber());
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r125982 r126387  
    489489    bool byValIsPure(Node& node)
    490490    {
    491         switch (node.op()) {
    492         case PutByVal: {
    493             if (!at(varArgChild(node, 1)).shouldSpeculateInteger())
    494                 return false;
    495             SpeculatedType prediction = at(varArgChild(node, 0)).prediction();
    496             if (!isActionableMutableArraySpeculation(prediction))
    497                 return false;
     491        switch (node.arrayMode()) {
     492        case Array::Generic:
     493        case Array::JSArrayOutOfBounds:
     494            return false;
     495        case Array::String:
     496            return node.op() == GetByVal;
     497#if USE(JSVALUE32_64)
     498        case Array::Arguments:
     499            if (node.op() == GetByVal)
     500                return true;
     501            return false;
     502#endif // USE(JSVALUE32_64)
     503        default:
    498504            return true;
    499         }
    500            
    501         case PutByValSafe: {
    502             if (!at(varArgChild(node, 1)).shouldSpeculateInteger())
    503                 return false;
    504             SpeculatedType prediction = at(varArgChild(node, 0)).prediction();
    505             if (!isActionableMutableArraySpeculation(prediction))
    506                 return false;
    507             if (isArraySpeculation(prediction))
    508                 return false;
    509             return true;
    510         }
    511            
    512         case PutByValAlias: {
    513             if (!at(varArgChild(node, 1)).shouldSpeculateInteger())
    514                 return false;
    515             SpeculatedType prediction = at(varArgChild(node, 0)).prediction();
    516             if (!isActionableMutableArraySpeculation(prediction))
    517                 return false;
    518             return true;
    519         }
    520            
    521         case GetByVal: {
    522             if (!at(node.child2()).shouldSpeculateInteger())
    523                 return false;
    524             SpeculatedType prediction = at(node.child1()).prediction();
    525             if (!isActionableArraySpeculation(prediction))
    526                 return false;
    527             return true;
    528         }
    529            
    530         default:
    531             ASSERT_NOT_REACHED();
    532             return false;
    533505        }
    534506    }
     
    550522        case GetByVal:
    551523        case PutByVal:
    552         case PutByValSafe:
    553524        case PutByValAlias:
    554525            return !byValIsPure(node);
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r125999 r126387  
    3434#include "CodeOrigin.h"
    3535#include "DFGAdjacencyList.h"
     36#include "DFGArrayMode.h"
    3637#include "DFGCommon.h"
    3738#include "DFGNodeFlags.h"
     
    733734    }
    734735   
     736    bool hasArrayMode()
     737    {
     738        switch (op()) {
     739        case GetIndexedPropertyStorage:
     740        case GetArrayLength:
     741        case PutByVal:
     742        case PutByValAlias:
     743        case GetByVal:
     744        case StringCharAt:
     745        case StringCharCodeAt:
     746            return true;
     747        default:
     748            return false;
     749        }
     750    }
     751   
     752    Array::Mode arrayMode()
     753    {
     754        ASSERT(hasArrayMode());
     755        return static_cast<Array::Mode>(m_opInfo);
     756    }
     757   
     758    void setArrayMode(Array::Mode arrayMode)
     759    {
     760        ASSERT(hasArrayMode());
     761        m_opInfo = arrayMode;
     762    }
     763   
    735764    bool hasVirtualRegister()
    736765    {
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r125999 r126387  
    114114    macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
    115115    macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
    116     macro(PutByValSafe, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
    117116    macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
    118117    macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
     
    144143    macro(PutByOffset, NodeMustGenerate) \
    145144    macro(GetArrayLength, NodeResultInt32) \
    146     macro(GetArgumentsLength, NodeResultInt32) \
    147     macro(GetStringLength, NodeResultInt32) \
    148     macro(GetInt8ArrayLength, NodeResultInt32) \
    149     macro(GetInt16ArrayLength, NodeResultInt32) \
    150     macro(GetInt32ArrayLength, NodeResultInt32) \
    151     macro(GetUint8ArrayLength, NodeResultInt32) \
    152     macro(GetUint8ClampedArrayLength, NodeResultInt32) \
    153     macro(GetUint16ArrayLength, NodeResultInt32) \
    154     macro(GetUint32ArrayLength, NodeResultInt32) \
    155     macro(GetFloat32ArrayLength, NodeResultInt32) \
    156     macro(GetFloat64ArrayLength, NodeResultInt32) \
    157145    macro(GetScopeChain, NodeResultJS) \
    158146    macro(GetScopedVar, NodeResultJS | NodeMustGenerate) \
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r125999 r126387  
    613613        case PutByValAlias:
    614614        case GetArrayLength:
    615         case GetArgumentsLength:
    616         case GetInt8ArrayLength:
    617         case GetInt16ArrayLength:
    618         case GetInt32ArrayLength:
    619         case GetUint8ArrayLength:
    620         case GetUint8ClampedArrayLength:
    621         case GetUint16ArrayLength:
    622         case GetUint32ArrayLength:
    623         case GetFloat32ArrayLength:
    624         case GetFloat64ArrayLength:
    625         case GetStringLength:
    626615        case Int32ToDouble:
    627616        case DoubleAsInt32:
     
    638627       
    639628        case PutByVal:
    640         case PutByValSafe:
    641629            changed |= m_graph[m_graph.varArgChild(node, 0)].mergeFlags(NodeUsedAsValue);
    642630            changed |= m_graph[m_graph.varArgChild(node, 1)].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r125999 r126387  
    270270}
    271271
    272 void SpeculativeJIT::speculateArray(Edge edge, GPRReg baseReg)
    273 {
    274     AbstractValue& arrayValue = m_state.forNode(edge);
    275     if (arrayValue.m_currentKnownStructure.hasSingleton()
    276         && arrayValue.m_currentKnownStructure.singleton()->classInfo() == &JSArray::s_info)
    277         return;
     272const TypedArrayDescriptor* SpeculativeJIT::typedArrayDescriptor(Array::Mode arrayMode)
     273{
     274    switch (arrayMode) {
     275    case Array::Int8Array:
     276        return &m_jit.globalData()->int8ArrayDescriptor();
     277    case Array::Int16Array:
     278        return &m_jit.globalData()->int16ArrayDescriptor();
     279    case Array::Int32Array:
     280        return &m_jit.globalData()->int32ArrayDescriptor();
     281    case Array::Uint8Array:
     282        return &m_jit.globalData()->uint8ArrayDescriptor();
     283    case Array::Uint8ClampedArray:
     284        return &m_jit.globalData()->uint8ClampedArrayDescriptor();
     285    case Array::Uint16Array:
     286        return &m_jit.globalData()->uint16ArrayDescriptor();
     287    case Array::Uint32Array:
     288        return &m_jit.globalData()->uint32ArrayDescriptor();
     289    case Array::Float32Array:
     290        return &m_jit.globalData()->float32ArrayDescriptor();
     291    case Array::Float64Array:
     292        return &m_jit.globalData()->float32ArrayDescriptor();
     293    default:
     294        return 0;
     295    }
     296}
     297
     298const TypedArrayDescriptor* SpeculativeJIT::speculateArray(Array::Mode arrayMode, Edge edge, GPRReg baseReg)
     299{
     300    const TypedArrayDescriptor* result = typedArrayDescriptor(arrayMode);
     301   
     302    if (modeAlreadyChecked(m_state.forNode(edge), arrayMode))
     303        return result;
     304   
     305    const ClassInfo* expectedClassInfo = 0;
     306   
     307    switch (arrayMode) {
     308    case Array::ForceExit:
     309        ASSERT_NOT_REACHED();
     310        terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
     311        return result;
     312    case Array::String:
     313        expectedClassInfo = &JSString::s_info;
     314        break;
     315    case Array::JSArray:
     316    case Array::JSArrayOutOfBounds: {
     317        // This code duplicates the code below in anticipation of this code being
     318        // substantially changed in the future.
     319        GPRTemporary temp(this);
     320        m_jit.loadPtr(
     321            MacroAssembler::Address(baseReg, JSCell::structureOffset()), temp.gpr());
     322        speculationCheck(
     323            Uncountable, JSValueRegs(), NoNode,
     324            m_jit.branchPtr(
     325                MacroAssembler::NotEqual,
     326                MacroAssembler::Address(temp.gpr(), Structure::classInfoOffset()),
     327                MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
     328        return result;
     329    }
     330    case Array::Arguments:
     331        expectedClassInfo = &Arguments::s_info;
     332        break;
     333    case Array::Int8Array:
     334    case Array::Int16Array:
     335    case Array::Int32Array:
     336    case Array::Uint8Array:
     337    case Array::Uint8ClampedArray:
     338    case Array::Uint16Array:
     339    case Array::Uint32Array:
     340    case Array::Float32Array:
     341    case Array::Float64Array:
     342        expectedClassInfo = result->m_classInfo;
     343        break;
     344    default:
     345        ASSERT_NOT_REACHED();
     346        break;
     347    }
    278348   
    279349    GPRTemporary temp(this);
     
    285355            MacroAssembler::NotEqual,
    286356            MacroAssembler::Address(temp.gpr(), Structure::classInfoOffset()),
    287             MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
     357            MacroAssembler::TrustedImmPtr(expectedClassInfo)));
     358   
     359    return result;
    288360}
    289361
     
    16211693    GPRReg storageReg = storage.gpr();
    16221694
    1623     if (!isStringSpeculation(m_state.forNode(node.child1()).m_type)) {
    1624         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
    1625         noResult(m_compileIndex);
    1626         return;
    1627     }
     1695    ASSERT(modeAlreadyChecked(m_state.forNode(node.child1()), Array::String));
    16281696
    16291697    // unsigned comparison so we can filter out negative indices and indices that are too large
     
    20192087}
    20202088
    2021 void SpeculativeJIT::compileGetTypedArrayLength(const TypedArrayDescriptor& descriptor, Node& node, bool needsSpeculationCheck)
    2022 {
    2023     SpeculateCellOperand base(this, node.child1());
    2024     GPRTemporary result(this);
    2025    
    2026     GPRReg baseGPR = base.gpr();
    2027     GPRReg resultGPR = result.gpr();
    2028    
    2029     if (needsSpeculationCheck)
    2030         speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    2031    
    2032     m_jit.load32(MacroAssembler::Address(baseGPR, descriptor.m_lengthOffset), resultGPR);
    2033    
    2034     integerResult(resultGPR, m_compileIndex);
    2035 }
    2036 
    2037 void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness)
     2089void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySignedness signedness)
    20382090{
    20392091    SpeculateCellOperand base(this, node.child1());
     
    20482100    GPRReg resultReg = result.gpr();
    20492101
    2050     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
    2051         ASSERT_NOT_REACHED();
    2052         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
    2053         noResult(m_compileIndex);
    2054         return;
    2055     }
     2102    ASSERT(modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode()));
    20562103
    20572104    speculationCheck(
     
    20982145}
    20992146
    2100 void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness, TypedArrayRounding rounding)
    2101 {
    2102     Edge baseUse = m_jit.graph().varArgChild(node, 0);
     2147void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySignedness signedness, TypedArrayRounding rounding)
     2148{
    21032149    Edge valueUse = m_jit.graph().varArgChild(node, 2);
    21042150   
    2105     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
    2106         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    21072151    GPRTemporary value;
    21082152    GPRReg valueGPR;
     
    21752219    m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
    21762220    MacroAssembler::Jump outOfBounds;
    2177     if (speculationRequirements != NoTypedArraySpecCheck)
     2221    if (node.op() == PutByVal)
    21782222        outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
    21792223
     
    21912235        ASSERT_NOT_REACHED();
    21922236    }
    2193     if (speculationRequirements != NoTypedArraySpecCheck)
     2237    if (node.op() == PutByVal)
    21942238        outOfBounds.link(&m_jit);
    21952239    noResult(m_compileIndex);
    21962240}
    21972241
    2198 void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
     2242void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize)
    21992243{
    22002244    SpeculateCellOperand base(this, node.child1());
     
    22052249    GPRReg propertyReg = property.gpr();
    22062250    GPRReg storageReg = storage.gpr();
    2207    
    2208     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
    2209         ASSERT_NOT_REACHED();
    2210         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
    2211         noResult(m_compileIndex);
    2212         return;
    2213     }
     2251
     2252    ASSERT(modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode()));
    22142253
    22152254    FPRTemporary result(this);
    22162255    FPRReg resultReg = result.fpr();
    2217     ASSERT(speculationRequirements != NoTypedArraySpecCheck);
    22182256    speculationCheck(
    22192257        Uncountable, JSValueRegs(), NoNode,
     
    22392277}
    22402278
    2241 void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
     2279void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize)
    22422280{
    22432281    Edge baseUse = m_jit.graph().varArgChild(node, 0);
     
    22462284    SpeculateDoubleOperand valueOp(this, valueUse);
    22472285   
    2248     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
    2249         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse.index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
     2286    ASSERT_UNUSED(baseUse, modeAlreadyChecked(m_state.forNode(baseUse), node.arrayMode()));
    22502287   
    22512288    GPRTemporary result(this);
     
    22562293    m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
    22572294    MacroAssembler::Jump outOfBounds;
    2258     if (speculationRequirements != NoTypedArraySpecCheck)
     2295    if (node.op() == PutByVal)
    22592296        outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
    22602297   
     
    22732310        ASSERT_NOT_REACHED();
    22742311    }
    2275     if (speculationRequirements != NoTypedArraySpecCheck)
     2312    if (node.op() == PutByVal)
    22762313        outOfBounds.link(&m_jit);
    22772314    noResult(m_compileIndex);
     
    30673104void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
    30683105{
    3069     ASSERT(at(node.child1()).prediction());
    3070     ASSERT(at(node.child2()).shouldSpeculateInteger());
    3071        
    30723106    SpeculateCellOperand base(this, node.child1());
    30733107    GPRReg baseReg = base.gpr();
     
    30753109    GPRTemporary storage(this);
    30763110    GPRReg storageReg = storage.gpr();
    3077     if (at(node.child1()).shouldSpeculateArguments()) {
    3078         ASSERT_NOT_REACHED();
    3079     } else if (at(node.child1()).prediction() == SpecString) {
    3080         if (!isStringSpeculation(m_state.forNode(node.child1()).m_type))
    3081             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
    3082 
     3111   
     3112    const TypedArrayDescriptor* descriptor =
     3113        speculateArray(node.arrayMode(), node.child1(), baseReg);
     3114   
     3115    switch (node.arrayMode()) {
     3116    case Array::String:
    30833117        m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
    30843118       
     
    30873121
    30883122        m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg);
    3089     } else if (at(node.child1()).shouldSpeculateInt8Array()) {
    3090         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int8ArrayDescriptor();
    3091         if (!isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3092             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3093         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3094     } else if (at(node.child1()).shouldSpeculateInt16Array()) {
    3095         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int16ArrayDescriptor();
    3096         if (!isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3097             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3098         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3099     } else if (at(node.child1()).shouldSpeculateInt32Array()) {
    3100         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int32ArrayDescriptor();
    3101         if (!isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3102             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3103         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3104     } else if (at(node.child1()).shouldSpeculateUint8Array()) {
    3105         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ArrayDescriptor();
    3106         if (!isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3107             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3108         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3109     } else if (at(node.child1()).shouldSpeculateUint8ClampedArray()) {
    3110         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ClampedArrayDescriptor();
    3111         if (!isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type))
    3112             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3113         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3114     } else if (at(node.child1()).shouldSpeculateUint16Array()) {
    3115         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint16ArrayDescriptor();
    3116         if (!isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3117             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3118         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3119     } else if (at(node.child1()).shouldSpeculateUint32Array()) {
    3120         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint32ArrayDescriptor();
    3121         if (!isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3122             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3123         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3124     } else if (at(node.child1()).shouldSpeculateFloat32Array()) {
    3125         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float32ArrayDescriptor();
    3126         if (!isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3127             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3128         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3129     } else if (at(node.child1()).shouldSpeculateFloat64Array()) {
    3130         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float64ArrayDescriptor();
    3131         if (!isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type))
    3132             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
    3133         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
    3134     } else {
    3135         speculateArray(node.child1(), baseReg);
     3123        break;
     3124       
     3125    case Array::JSArray:
     3126    case Array::JSArrayOutOfBounds:
    31363127        m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
    3137     }
     3128        break;
     3129       
     3130    default:
     3131        ASSERT(descriptor);
     3132        m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor->m_storageOffset), storageReg);
     3133        break;
     3134    }
     3135   
    31383136    storageResult(storageReg, m_compileIndex);
    31393137}
     
    32533251}
    32543252
     3253void SpeculativeJIT::compileGetArrayLength(Node& node)
     3254{
     3255    SpeculateCellOperand base(this, node.child1());
     3256    GPRTemporary result(this);
     3257       
     3258    GPRReg baseGPR = base.gpr();
     3259    GPRReg resultGPR = result.gpr();
     3260       
     3261    const TypedArrayDescriptor* descriptor =
     3262        speculateArray(node.arrayMode(), node.child1(), baseGPR);
     3263
     3264    switch (node.arrayMode()) {
     3265    case Array::JSArray:
     3266    case Array::JSArrayOutOfBounds:
     3267        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
     3268        m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
     3269           
     3270        speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));
     3271           
     3272        integerResult(resultGPR, m_compileIndex);
     3273        break;
     3274    case Array::String:
     3275        m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
     3276        integerResult(resultGPR, m_compileIndex);
     3277        break;
     3278    case Array::Arguments:
     3279        compileGetArgumentsLength(node);
     3280        break;
     3281    default:
     3282        ASSERT(descriptor);
     3283        m_jit.load32(MacroAssembler::Address(baseGPR, descriptor->m_lengthOffset), resultGPR);
     3284        integerResult(resultGPR, m_compileIndex);
     3285        break;
     3286    }
     3287}
     3288
    32553289void SpeculativeJIT::compileNewFunctionNoCheck(Node& node)
    32563290{
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r125999 r126387  
    20832083    void compileGetArgumentsLength(Node&);
    20842084   
     2085    void compileGetArrayLength(Node&);
     2086   
    20852087    void compileValueToInt32(Node&);
    20862088    void compileUInt32ToNumber(Node&);
     
    20962098    void compileArithMod(Node&);
    20972099    void compileSoftModulo(Node&);
    2098     void compileGetTypedArrayLength(const TypedArrayDescriptor&, Node&, bool needsSpeculationCheck);
    2099     enum TypedArraySpeculationRequirements {
    2100         NoTypedArraySpecCheck,
    2101         NoTypedArrayTypeSpecCheck,
    2102         AllTypedArraySpecChecks
    2103     };
    21042100    enum TypedArraySignedness {
    21052101        SignedTypedArray,
     
    21112107    };
    21122108    void compileGetIndexedPropertyStorage(Node&);
    2113     void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySpeculationRequirements, TypedArraySignedness);
    2114     void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
    2115     void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySpeculationRequirements);
    2116     void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySpeculationRequirements);
     2109    void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySignedness);
     2110    void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
     2111    void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize);
     2112    void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize);
    21172113    void compileNewFunctionNoCheck(Node&);
    21182114    void compileNewFunctionExpression(Node&);
     
    22002196    JumpReplacementWatchpoint* speculationWatchpointWithConditionalDirection(ExitKind, bool isForward);
    22012197   
    2202     void speculateArray(Edge baseEdge, GPRReg baseReg);
     2198    const TypedArrayDescriptor* typedArrayDescriptor(Array::Mode);
     2199   
     2200    const TypedArrayDescriptor* speculateArray(Array::Mode, Edge baseEdge, GPRReg baseReg);
    22032201   
    22042202    template<bool strict>
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r126082 r126387  
    23422342
    23432343    case GetByVal: {
    2344         if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2344        switch (node.arrayMode()) {
     2345        case Array::Undecided:
     2346        case Array::ForceExit:
     2347            ASSERT_NOT_REACHED();
    23452348            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
    23462349            break;
    2347         }
    2348        
    2349         if (!at(node.child2()).shouldSpeculateInteger() || (!node.child3() && !at(node.child1()).shouldSpeculateArguments())) {
     2350        case Array::Generic: {
    23502351            SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right.
    23512352            JSValueOperand property(this, node.child2());
     
    23622363            break;
    23632364        }
    2364        
    2365         if (at(node.child1()).shouldSpeculateArguments()) {
    2366             compileGetByValOnArguments(node);
     2365        case Array::JSArray:
     2366        case Array::JSArrayOutOfBounds: {
     2367            SpeculateStrictInt32Operand property(this, node.child2());
     2368            StorageOperand storage(this, node.child3());
     2369            GPRReg propertyReg = property.gpr();
     2370            GPRReg storageReg = storage.gpr();
     2371       
    23672372            if (!m_compileOkay)
    23682373                return;
    2369             break;
    2370         }
    2371 
    2372         if (at(node.child1()).prediction() == SpecString) {
     2374
     2375            // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
     2376            // If we have predicted the base to be type array, we can skip the check.
     2377            {
     2378                SpeculateCellOperand base(this, node.child1());
     2379                GPRReg baseReg = base.gpr();
     2380                // We've already speculated that it's some kind of array, at this point.
     2381                speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
     2382            }
     2383
     2384            GPRTemporary resultTag(this);
     2385            GPRTemporary resultPayload(this);
     2386
     2387            m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
     2388            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
     2389            m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
     2390
     2391            jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
     2392            break;
     2393        }
     2394        case Array::String:
    23732395            compileGetByValOnString(node);
    2374             if (!m_compileOkay)
    2375                 return;
    2376             break;
    2377         }
    2378        
    2379         if (at(node.child1()).shouldSpeculateInt8Array()) {
    2380             compileGetByValOnIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2381             if (!m_compileOkay)
    2382                 return;
    2383             break;           
    2384         }
    2385        
    2386         if (at(node.child1()).shouldSpeculateInt16Array()) {
    2387             compileGetByValOnIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2388             if (!m_compileOkay)
    2389                 return;
    2390             break;           
    2391         }
    2392        
    2393         if (at(node.child1()).shouldSpeculateInt32Array()) {
    2394             compileGetByValOnIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2395             if (!m_compileOkay)
    2396                 return;
    2397             break;           
    2398         }
    2399        
    2400         if (at(node.child1()).shouldSpeculateUint8Array()) {
    2401             compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2402             if (!m_compileOkay)
    2403                 return;
    2404             break;           
    2405         }
    2406 
    2407         if (at(node.child1()).shouldSpeculateUint8ClampedArray()) {
    2408             compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2409             if (!m_compileOkay)
    2410                 return;
    2411             break;
    2412         }
    2413 
    2414         if (at(node.child1()).shouldSpeculateUint16Array()) {
    2415             compileGetByValOnIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2416             if (!m_compileOkay)
    2417                 return;
    2418             break;           
    2419         }
    2420        
    2421         if (at(node.child1()).shouldSpeculateUint32Array()) {
    2422             compileGetByValOnIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2423             if (!m_compileOkay)
    2424                 return;
    2425             break;           
    2426         }
    2427        
    2428         if (at(node.child1()).shouldSpeculateFloat32Array()) {
    2429             compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2430             if (!m_compileOkay)
    2431                 return;
    2432             break;           
    2433         }
    2434        
    2435         if (at(node.child1()).shouldSpeculateFloat64Array()) {
    2436             compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2437             if (!m_compileOkay)
    2438                 return;
    2439             break;           
    2440         }
    2441        
    2442         SpeculateStrictInt32Operand property(this, node.child2());
    2443         StorageOperand storage(this, node.child3());
    2444         GPRReg propertyReg = property.gpr();
    2445         GPRReg storageReg = storage.gpr();
    2446        
    2447         if (!m_compileOkay)
    2448             return;
    2449 
    2450         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
    2451         // If we have predicted the base to be type array, we can skip the check.
    2452         {
    2453             SpeculateCellOperand base(this, node.child1());
    2454             GPRReg baseReg = base.gpr();
    2455             // We've already speculated that it's some kind of array, at this point.
    2456             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
    2457         }
    2458 
    2459         GPRTemporary resultTag(this);
    2460         GPRTemporary resultPayload(this);
    2461 
    2462         m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
    2463         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
    2464         m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
    2465 
    2466         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
     2396            break;
     2397        case Array::Arguments:
     2398            compileGetByValOnArguments(node);
     2399            break;
     2400        case Array::Int8Array:
     2401            compileGetByValOnIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), node, sizeof(int8_t), SignedTypedArray);
     2402            break;
     2403        case Array::Int16Array:
     2404            compileGetByValOnIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), node, sizeof(int16_t), SignedTypedArray);
     2405            break;
     2406        case Array::Int32Array:
     2407            compileGetByValOnIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), node, sizeof(int32_t), SignedTypedArray);
     2408            break;
     2409        case Array::Uint8Array:
     2410            compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
     2411            break;
     2412        case Array::Uint8ClampedArray:
     2413            compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
     2414            break;
     2415        case Array::Uint16Array:
     2416            compileGetByValOnIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), node, sizeof(uint16_t), UnsignedTypedArray);
     2417            break;
     2418        case Array::Uint32Array:
     2419            compileGetByValOnIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), node, sizeof(uint32_t), UnsignedTypedArray);
     2420            break;
     2421        case Array::Float32Array:
     2422            compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float));
     2423            break;
     2424        case Array::Float64Array:
     2425            compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double));
     2426            break;
     2427        default:
     2428            ASSERT_NOT_REACHED();
     2429            break;
     2430        }
    24672431        break;
    24682432    }
    24692433
    24702434    case PutByVal:
    2471     case PutByValSafe: {
     2435    case PutByValAlias: {
    24722436        Edge child1 = m_jit.graph().varArgChild(node, 0);
    24732437        Edge child2 = m_jit.graph().varArgChild(node, 1);
    24742438        Edge child3 = m_jit.graph().varArgChild(node, 2);
    24752439       
    2476         if (!at(child1).prediction() || !at(child2).prediction()) {
     2440        Array::Mode arrayMode = modeForPut(node.arrayMode());
     2441        bool alreadyHandled = false;
     2442       
     2443        switch (arrayMode) {
     2444        case Array::Undecided:
     2445        case Array::ForceExit:
     2446            ASSERT_NOT_REACHED();
    24772447            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
    2478             break;
    2479         }
    2480        
    2481         if (!at(child2).shouldSpeculateInteger()
    2482             || at(child1).shouldSpeculateArguments()) {
     2448            alreadyHandled = true;
     2449            break;
     2450        case Array::Generic: {
     2451            ASSERT(node.op() == PutByVal);
     2452           
    24832453            SpeculateCellOperand base(this, child1); // Save a register, speculate cell. We'll probably be right.
    24842454            JSValueOperand property(this, child2);
     
    24942464           
    24952465            noResult(m_compileIndex);
    2496             break;
    2497         }
    2498 
     2466            alreadyHandled = true;
     2467            break;
     2468        }
     2469        default:
     2470            break;
     2471        }
     2472       
     2473        if (alreadyHandled)
     2474            break;
     2475       
    24992476        SpeculateCellOperand base(this, child1);
    25002477        SpeculateStrictInt32Operand property(this, child2);
    2501         if (at(child1).shouldSpeculateInt8Array()) {
    2502             compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
     2478       
     2479        GPRReg baseReg = base.gpr();
     2480        GPRReg propertyReg = property.gpr();
     2481
     2482        speculateArray(arrayMode, child1, baseReg);
     2483
     2484        switch (arrayMode) {
     2485        case Array::JSArray:
     2486        case Array::JSArrayOutOfBounds: {
     2487            JSValueOperand value(this, child3);
     2488
     2489            GPRReg valueTagReg = value.tagGPR();
     2490            GPRReg valuePayloadReg = value.payloadGPR();
     2491           
    25032492            if (!m_compileOkay)
    25042493                return;
    2505             break;           
    2506         }
    2507        
    2508         if (at(child1).shouldSpeculateInt16Array()) {
    2509             compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2510             if (!m_compileOkay)
    2511                 return;
    2512             break;           
    2513         }
    2514        
    2515         if (at(child1).shouldSpeculateInt32Array()) {
    2516             compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2517             if (!m_compileOkay)
    2518                 return;
    2519             break;           
    2520         }
    2521        
    2522         if (at(child1).shouldSpeculateUint8Array()) {
    2523             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2524             if (!m_compileOkay)
    2525                 return;
    2526             break;           
    2527         }
    2528        
    2529         if (at(child1).shouldSpeculateUint8ClampedArray()) {
    2530             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding);
    2531             if (!m_compileOkay)
    2532                 return;
    2533             break;
    2534         }
    2535 
    2536         if (at(child1).shouldSpeculateUint16Array()) {
    2537             compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2538             if (!m_compileOkay)
    2539                 return;
    2540             break;           
    2541         }
    2542        
    2543         if (at(child1).shouldSpeculateUint32Array()) {
    2544             compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2545             if (!m_compileOkay)
    2546                 return;
    2547             break;           
    2548         }
    2549        
    2550         if (at(child1).shouldSpeculateFloat32Array()) {
    2551             compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2552             if (!m_compileOkay)
    2553                 return;
    2554             break;           
    2555         }
    2556        
    2557         if (at(child1).shouldSpeculateFloat64Array()) {
    2558             compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2559             if (!m_compileOkay)
    2560                 return;
    2561             break;           
    2562         }
    2563        
    2564         JSValueOperand value(this, child3);
    2565         // Map base, property & value into registers, allocate a scratch register.
    2566         GPRReg baseReg = base.gpr();
    2567         GPRReg propertyReg = property.gpr();
    2568         GPRReg valueTagReg = value.tagGPR();
    2569         GPRReg valuePayloadReg = value.payloadGPR();
    2570        
    2571         if (!m_compileOkay)
    2572             return;
    2573 
    2574         {
    2575             GPRTemporary scratch(this);
    2576             GPRReg scratchReg = scratch.gpr();
    2577             writeBarrier(baseReg, valueTagReg, child3, WriteBarrierForPropertyAccess, scratchReg);
    2578         }
    2579 
    2580         speculateArray(child1, baseReg);
    2581 
    2582         MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
    2583         if (node.op() == PutByVal)
    2584             speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
    2585 
    2586         base.use();
    2587         property.use();
    2588         value.use();
    2589        
    2590         // Get the array storage.
    2591         GPRTemporary storage(this);
    2592         GPRReg storageReg = storage.gpr();
    2593         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
    2594 
    2595         // Check if we're writing to a hole; if so increment m_numValuesInVector.
    2596         MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
    2597         m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
    2598 
    2599         // If we're writing to a hole we might be growing the array;
    2600         MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
    2601         m_jit.add32(TrustedImm32(1), propertyReg);
    2602         m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
    2603         m_jit.sub32(TrustedImm32(1), propertyReg);
    2604 
    2605         lengthDoesNotNeedUpdate.link(&m_jit);
    2606         notHoleValue.link(&m_jit);
    2607 
    2608         // Store the value to the array.
    2609         m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
    2610         m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
    2611        
    2612         if (node.op() == PutByValSafe) {
    2613             addSlowPathGenerator(
    2614                 slowPathCall(
    2615                     beyondArrayBounds, this,
    2616                     m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
    2617                     NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg));
    2618         }
    2619            
    2620         noResult(m_compileIndex, UseChildrenCalledExplicitly);
    2621         break;
    2622     }
    2623 
    2624     case PutByValAlias: {
    2625         Edge child1 = m_jit.graph().varArgChild(node, 0);
    2626         Edge child2 = m_jit.graph().varArgChild(node, 1);
    2627         Edge child3 = m_jit.graph().varArgChild(node, 2);
    2628        
    2629         if (!at(child1).prediction() || !at(child2).prediction()) {
    2630             terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
    2631             break;
    2632         }
    2633        
    2634         ASSERT(isActionableMutableArraySpeculation(at(child1).prediction()));
    2635         ASSERT(at(child2).shouldSpeculateInteger());
    2636 
    2637         SpeculateCellOperand base(this, child1);
    2638         SpeculateStrictInt32Operand property(this, child2);
    2639 
    2640         if (at(child1).shouldSpeculateInt8Array()) {
    2641             compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), NoTypedArraySpecCheck, SignedTypedArray);
    2642             if (!m_compileOkay)
    2643                 return;
    2644             break;           
    2645         }
    2646        
    2647         if (at(child1).shouldSpeculateInt16Array()) {
    2648             compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), NoTypedArraySpecCheck, SignedTypedArray);
    2649             if (!m_compileOkay)
    2650                 return;
    2651             break;           
    2652         }
    2653        
    2654         if (at(child1).shouldSpeculateInt32Array()) {
    2655             compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), NoTypedArraySpecCheck, SignedTypedArray);
    2656             if (!m_compileOkay)
    2657                 return;
    2658             break;           
    2659         }
    2660        
    2661         if (at(child1).shouldSpeculateUint8Array()) {
    2662             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray);
    2663             if (!m_compileOkay)
    2664                 return;
    2665             break;           
    2666         }
    2667 
    2668         if (at(child1).shouldSpeculateUint8ClampedArray()) {
    2669             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray, ClampRounding);
    2670             if (!m_compileOkay)
    2671                 return;
    2672             break;
    2673         }
    2674 
    2675         if (at(child1).shouldSpeculateUint16Array()) {
    2676             compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), NoTypedArraySpecCheck, UnsignedTypedArray);
    2677             if (!m_compileOkay)
    2678                 return;
    2679             break;           
    2680         }
    2681        
    2682         if (at(child1).shouldSpeculateUint32Array()) {
    2683             compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), NoTypedArraySpecCheck, UnsignedTypedArray);
    2684             if (!m_compileOkay)
    2685                 return;
    2686             break;           
    2687         }
    2688        
    2689         if (at(child1).shouldSpeculateFloat32Array()) {
    2690             compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), NoTypedArraySpecCheck);
    2691             if (!m_compileOkay)
    2692                 return;
    2693             break;           
    2694         }
    2695        
    2696         if (at(child1).shouldSpeculateFloat64Array()) {
    2697             compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), NoTypedArraySpecCheck);
    2698             if (!m_compileOkay)
    2699                 return;
    2700             break;           
    2701         }
    2702 
    2703         ASSERT(at(child1).shouldSpeculateArray());
    2704 
    2705         JSValueOperand value(this, child3);
    2706         GPRTemporary scratch(this, base);
    2707        
    2708         GPRReg baseReg = base.gpr();
    2709         GPRReg scratchReg = scratch.gpr();
    2710 
    2711         writeBarrier(baseReg, value.tagGPR(), child3, WriteBarrierForPropertyAccess, scratchReg);
    2712 
    2713         // Get the array storage.
    2714         GPRReg storageReg = scratchReg;
    2715         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
    2716 
    2717         // Store the value to the array.
    2718         GPRReg propertyReg = property.gpr();
    2719         m_jit.store32(value.tagGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
    2720         m_jit.store32(value.payloadGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
    2721 
    2722         noResult(m_compileIndex);
     2494           
     2495            {
     2496                GPRTemporary scratch(this);
     2497                GPRReg scratchReg = scratch.gpr();
     2498                writeBarrier(baseReg, valueTagReg, child3, WriteBarrierForPropertyAccess, scratchReg);
     2499            }
     2500
     2501            if (node.op() == PutByValAlias) {
     2502                // Get the array storage.
     2503                GPRTemporary storage(this);
     2504                GPRReg storageReg = storage.gpr();
     2505                m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
     2506               
     2507                // Store the value to the array.
     2508                GPRReg propertyReg = property.gpr();
     2509                m_jit.store32(value.tagGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
     2510                m_jit.store32(value.payloadGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
     2511               
     2512                noResult(m_compileIndex);
     2513                break;
     2514            }
     2515
     2516            MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
     2517            if (arrayMode == Array::JSArray)
     2518                speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
     2519           
     2520            base.use();
     2521            property.use();
     2522            value.use();
     2523           
     2524            // Get the array storage.
     2525            GPRTemporary storage(this);
     2526            GPRReg storageReg = storage.gpr();
     2527            m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
     2528
     2529            // Check if we're writing to a hole; if so increment m_numValuesInVector.
     2530            MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
     2531            m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
     2532
     2533            // If we're writing to a hole we might be growing the array;
     2534            MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
     2535            m_jit.add32(TrustedImm32(1), propertyReg);
     2536            m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
     2537            m_jit.sub32(TrustedImm32(1), propertyReg);
     2538
     2539            lengthDoesNotNeedUpdate.link(&m_jit);
     2540            notHoleValue.link(&m_jit);
     2541
     2542            // Store the value to the array.
     2543            m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
     2544            m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
     2545       
     2546            if (arrayMode == Array::JSArrayOutOfBounds) {
     2547                addSlowPathGenerator(
     2548                    slowPathCall(
     2549                        beyondArrayBounds, this,
     2550                        m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
     2551                        NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg));
     2552            }
     2553           
     2554            noResult(m_compileIndex, UseChildrenCalledExplicitly);
     2555            break;
     2556        }
     2557           
     2558        case Array::Arguments:
     2559            // FIXME: we could at some point make this work. Right now we're assuming that the register
     2560            // pressure would be too great.
     2561            ASSERT_NOT_REACHED();
     2562            break;
     2563           
     2564        case Array::Int8Array:
     2565            compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), SignedTypedArray);
     2566            break;
     2567           
     2568        case Array::Int16Array:
     2569            compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), SignedTypedArray);
     2570            break;
     2571           
     2572        case Array::Int32Array:
     2573            compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), SignedTypedArray);
     2574            break;
     2575           
     2576        case Array::Uint8Array:
     2577            compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray);
     2578            break;
     2579           
     2580        case Array::Uint8ClampedArray:
     2581            compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray, ClampRounding);
     2582            break;
     2583           
     2584        case Array::Uint16Array:
     2585            compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), UnsignedTypedArray);
     2586            break;
     2587           
     2588        case Array::Uint32Array:
     2589            compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), UnsignedTypedArray);
     2590            break;
     2591           
     2592        case Array::Float32Array:
     2593            compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float));
     2594            break;
     2595           
     2596        case Array::Float64Array:
     2597            compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double));
     2598            break;
     2599           
     2600        default:
     2601            ASSERT_NOT_REACHED();
     2602            break;
     2603        }
    27232604        break;
    27242605    }
     
    27882669        }
    27892670
    2790         speculateArray(node.child1(), baseGPR);
     2671        speculateArray(Array::JSArray, node.child1(), baseGPR);
    27912672       
    27922673        GPRTemporary storage(this);
     
    28282709        GPRReg storageLengthGPR = storageLength.gpr();
    28292710       
    2830         speculateArray(node.child1(), baseGPR);
     2711        speculateArray(Array::JSArray, node.child1(), baseGPR);
    28312712       
    28322713        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
     
    33743255    }
    33753256
    3376     case GetArrayLength: {
    3377         SpeculateCellOperand base(this, node.child1());
    3378         GPRReg baseGPR = base.gpr();
    3379        
    3380         speculateArray(node.child1(), baseGPR);
    3381        
    3382         GPRTemporary result(this);
    3383         GPRReg resultGPR = result.gpr();
    3384 
    3385         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
    3386         m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
    3387        
    3388         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));
    3389        
    3390         integerResult(resultGPR, m_compileIndex);
    3391         break;
    3392     }
    3393        
    3394     case GetArgumentsLength: {
    3395         compileGetArgumentsLength(node);
    3396         break;
    3397     }
    3398 
    3399     case GetStringLength: {
    3400         SpeculateCellOperand base(this, node.child1());
    3401         GPRTemporary result(this);
    3402        
    3403         GPRReg baseGPR = base.gpr();
    3404         GPRReg resultGPR = result.gpr();
    3405        
    3406         if (!isStringSpeculation(m_state.forNode(node.child1()).m_type))
    3407             speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
    3408        
    3409         m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
    3410 
    3411         integerResult(resultGPR, m_compileIndex);
    3412         break;
    3413     }
    3414 
    3415     case GetInt8ArrayLength: {
    3416         compileGetTypedArrayLength(m_jit.globalData()->int8ArrayDescriptor(), node, !isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3417         break;
    3418     }
    3419     case GetInt16ArrayLength: {
    3420         compileGetTypedArrayLength(m_jit.globalData()->int16ArrayDescriptor(), node, !isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3421         break;
    3422     }
    3423     case GetInt32ArrayLength: {
    3424         compileGetTypedArrayLength(m_jit.globalData()->int32ArrayDescriptor(), node, !isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3425         break;
    3426     }
    3427     case GetUint8ArrayLength: {
    3428         compileGetTypedArrayLength(m_jit.globalData()->uint8ArrayDescriptor(), node, !isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3429         break;
    3430     }
    3431     case GetUint8ClampedArrayLength: {
    3432         compileGetTypedArrayLength(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, !isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type));
    3433         break;
    3434     }
    3435     case GetUint16ArrayLength: {
    3436         compileGetTypedArrayLength(m_jit.globalData()->uint16ArrayDescriptor(), node, !isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3437         break;
    3438     }
    3439     case GetUint32ArrayLength: {
    3440         compileGetTypedArrayLength(m_jit.globalData()->uint32ArrayDescriptor(), node, !isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3441         break;
    3442     }
    3443     case GetFloat32ArrayLength: {
    3444         compileGetTypedArrayLength(m_jit.globalData()->float32ArrayDescriptor(), node, !isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3445         break;
    3446     }
    3447     case GetFloat64ArrayLength: {
    3448         compileGetTypedArrayLength(m_jit.globalData()->float64ArrayDescriptor(), node, !isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3449         break;
    3450     }
    3451 
     3257    case GetArrayLength:
     3258        compileGetArrayLength(node);
     3259        break;
     3260       
    34523261    case CheckFunction: {
    34533262        SpeculateCellOperand function(this, node.child1());
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r125999 r126387  
    23752375
    23762376    case GetByVal: {
    2377         if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2377        switch (node.arrayMode()) {
     2378        case Array::Undecided:
     2379        case Array::ForceExit:
     2380            ASSERT_NOT_REACHED();
    23782381            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
    23792382            break;
    2380         }
    2381        
    2382         if (!at(node.child2()).shouldSpeculateInteger() || (!node.child3() && !at(node.child1()).shouldSpeculateArguments())) {
     2383        case Array::Generic: {
    23832384            JSValueOperand base(this, node.child1());
    23842385            JSValueOperand property(this, node.child2());
     
    23932394            break;
    23942395        }
    2395        
    2396         if (at(node.child1()).shouldSpeculateArguments()) {
    2397             compileGetByValOnArguments(node);
     2396        case Array::JSArray:
     2397        case Array::JSArrayOutOfBounds: {
     2398            SpeculateCellOperand base(this, node.child1());
     2399            SpeculateStrictInt32Operand property(this, node.child2());
     2400            StorageOperand storage(this, node.child3());
     2401           
     2402            GPRReg baseReg = base.gpr();
     2403            GPRReg propertyReg = property.gpr();
     2404            GPRReg storageReg = storage.gpr();
     2405           
    23982406            if (!m_compileOkay)
    23992407                return;
    2400             break;
    2401         }
    2402        
    2403         if (at(node.child1()).prediction() == SpecString) {
     2408           
     2409            // We will have already speculated that the base is some kind of array,
     2410            // at this point.
     2411           
     2412            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
     2413           
     2414            GPRTemporary result(this);
     2415            m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
     2416            speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()));
     2417           
     2418            jsValueResult(result.gpr(), m_compileIndex);
     2419            break;
     2420        }
     2421        case Array::String:
    24042422            compileGetByValOnString(node);
    2405             if (!m_compileOkay)
    2406                 return;
    2407             break;
    2408         }
    2409 
    2410         if (at(node.child1()).shouldSpeculateInt8Array()) {
    2411             compileGetByValOnIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2412             if (!m_compileOkay)
    2413                 return;
    2414             break;           
    2415         }
    2416        
    2417         if (at(node.child1()).shouldSpeculateInt16Array()) {
    2418             compileGetByValOnIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2419             if (!m_compileOkay)
    2420                 return;
    2421             break;           
    2422         }
    2423        
    2424         if (at(node.child1()).shouldSpeculateInt32Array()) {
    2425             compileGetByValOnIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2426             if (!m_compileOkay)
    2427                 return;
    2428             break;           
    2429         }
    2430 
    2431         if (at(node.child1()).shouldSpeculateUint8Array()) {
    2432             compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2433             if (!m_compileOkay)
    2434                 return;
    2435             break;           
    2436         }
    2437 
    2438         if (at(node.child1()).shouldSpeculateUint8ClampedArray()) {
    2439             compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2440             if (!m_compileOkay)
    2441                 return;
    2442             break;
    2443         }
    2444 
    2445         if (at(node.child1()).shouldSpeculateUint16Array()) {
    2446             compileGetByValOnIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2447             if (!m_compileOkay)
    2448                 return;
    2449             break;           
    2450         }
    2451        
    2452         if (at(node.child1()).shouldSpeculateUint32Array()) {
    2453             compileGetByValOnIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2454             if (!m_compileOkay)
    2455                 return;
    2456             break;           
    2457         }
    2458        
    2459         if (at(node.child1()).shouldSpeculateFloat32Array()) {
    2460             compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2461             if (!m_compileOkay)
    2462                 return;
    2463             break;           
    2464         }
    2465        
    2466         if (at(node.child1()).shouldSpeculateFloat64Array()) {
    2467             compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2468             if (!m_compileOkay)
    2469                 return;
    2470             break;           
    2471         }
    2472        
    2473         SpeculateCellOperand base(this, node.child1());
    2474         SpeculateStrictInt32Operand property(this, node.child2());
    2475         StorageOperand storage(this, node.child3());
    2476 
    2477         GPRReg baseReg = base.gpr();
    2478         GPRReg propertyReg = property.gpr();
    2479         GPRReg storageReg = storage.gpr();
    2480        
    2481         if (!m_compileOkay)
    2482             return;
    2483 
    2484         // We will have already speculated that the base is some kind of array,
    2485         // at this point.
    2486        
    2487         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
    2488 
    2489         GPRTemporary result(this);
    2490         m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
    2491         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()));
    2492 
    2493         jsValueResult(result.gpr(), m_compileIndex);
     2423            break;
     2424        case Array::Arguments:
     2425            compileGetByValOnArguments(node);
     2426            break;
     2427        case Array::Int8Array:
     2428            compileGetByValOnIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), node, sizeof(int8_t), SignedTypedArray);
     2429            break;
     2430        case Array::Int16Array:
     2431            compileGetByValOnIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), node, sizeof(int16_t), SignedTypedArray);
     2432            break;
     2433        case Array::Int32Array:
     2434            compileGetByValOnIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), node, sizeof(int32_t), SignedTypedArray);
     2435            break;
     2436        case Array::Uint8Array:
     2437            compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
     2438            break;
     2439        case Array::Uint8ClampedArray:
     2440            compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
     2441            break;
     2442        case Array::Uint16Array:
     2443            compileGetByValOnIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), node, sizeof(uint16_t), UnsignedTypedArray);
     2444            break;
     2445        case Array::Uint32Array:
     2446            compileGetByValOnIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), node, sizeof(uint32_t), UnsignedTypedArray);
     2447            break;
     2448        case Array::Float32Array:
     2449            compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float));
     2450            break;
     2451        case Array::Float64Array:
     2452            compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double));
     2453            break;
     2454        default:
     2455            ASSERT_NOT_REACHED();
     2456            break;
     2457        }
    24942458        break;
    24952459    }
    24962460
    24972461    case PutByVal:
    2498     case PutByValSafe: {
     2462    case PutByValAlias: {
    24992463        Edge child1 = m_jit.graph().varArgChild(node, 0);
    25002464        Edge child2 = m_jit.graph().varArgChild(node, 1);
    25012465        Edge child3 = m_jit.graph().varArgChild(node, 2);
    25022466       
    2503         if (!at(child1).prediction() || !at(child2).prediction()) {
     2467        Array::Mode arrayMode = modeForPut(node.arrayMode());
     2468        bool alreadyHandled = false;
     2469       
     2470        switch (arrayMode) {
     2471        case Array::Undecided:
     2472        case Array::ForceExit:
     2473            ASSERT_NOT_REACHED();
    25042474            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
    2505             break;
    2506         }
    2507        
    2508         if (!at(child2).shouldSpeculateInteger()) {
     2475            alreadyHandled = true;
     2476            break;
     2477        case Array::Generic: {
     2478            ASSERT(node.op() == PutByVal);
     2479           
    25092480            JSValueOperand arg1(this, child1);
    25102481            JSValueOperand arg2(this, child2);
     
    25182489           
    25192490            noResult(m_compileIndex);
    2520             break;
    2521         }
    2522 
     2491            alreadyHandled = true;
     2492            break;
     2493        }
     2494        default:
     2495            break;
     2496        }
     2497       
     2498        if (alreadyHandled)
     2499            break;
     2500       
    25232501        SpeculateCellOperand base(this, child1);
    25242502        SpeculateStrictInt32Operand property(this, child2);
    2525         if (at(child1).shouldSpeculateArguments()) {
    2526             dataLog(" in here ");
     2503       
     2504        GPRReg baseReg = base.gpr();
     2505        GPRReg propertyReg = property.gpr();
     2506
     2507        speculateArray(arrayMode, child1, baseReg);
     2508
     2509        switch (arrayMode) {
     2510        case Array::JSArray:
     2511        case Array::JSArrayOutOfBounds: {
     2512            JSValueOperand value(this, child3);
     2513            GPRTemporary scratch(this);
     2514
     2515            // Map base, property & value into registers, allocate a scratch register.
     2516            GPRReg valueReg = value.gpr();
     2517            GPRReg scratchReg = scratch.gpr();
     2518       
     2519            if (!m_compileOkay)
     2520                return;
     2521       
     2522            writeBarrier(baseReg, value.gpr(), child3, WriteBarrierForPropertyAccess, scratchReg);
     2523
     2524            if (node.op() == PutByValAlias) {
     2525                GPRReg storageReg = scratchReg;
     2526                m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
     2527               
     2528                // Store the value to the array.
     2529                GPRReg propertyReg = property.gpr();
     2530                GPRReg valueReg = value.gpr();
     2531                m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
     2532               
     2533                noResult(m_compileIndex);
     2534                break;
     2535            }
     2536           
     2537            MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
     2538            if (arrayMode == Array::JSArray)
     2539                speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
     2540
     2541            base.use();
     2542            property.use();
     2543            value.use();
     2544       
     2545            // Get the array storage.
     2546            GPRReg storageReg = scratchReg;
     2547            m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
     2548
     2549            // Check if we're writing to a hole; if so increment m_numValuesInVector.
     2550            MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
     2551            m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
     2552
     2553            // If we're writing to a hole we might be growing the array;
     2554            MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
     2555            m_jit.add32(TrustedImm32(1), propertyReg);
     2556            m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
     2557            m_jit.sub32(TrustedImm32(1), propertyReg);
     2558
     2559            lengthDoesNotNeedUpdate.link(&m_jit);
     2560            notHoleValue.link(&m_jit);
     2561
     2562            // Store the value to the array.
     2563            m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
     2564
     2565            if (arrayMode == Array::JSArrayOutOfBounds) {
     2566                addSlowPathGenerator(
     2567                    slowPathCall(
     2568                        beyondArrayBounds, this,
     2569                        m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
     2570                        NoResult, baseReg, propertyReg, valueReg));
     2571            }
     2572
     2573            noResult(m_compileIndex, UseChildrenCalledExplicitly);
     2574            break;
     2575        }
     2576           
     2577        case Array::Arguments: {
    25272578            JSValueOperand value(this, child3);
    25282579            GPRTemporary scratch(this);
    25292580            GPRTemporary scratch2(this);
    25302581           
    2531             GPRReg baseReg = base.gpr();
    2532             GPRReg propertyReg = property.gpr();
    25332582            GPRReg valueReg = value.gpr();
    25342583            GPRReg scratchReg = scratch.gpr();
     
    25382587                return;
    25392588
    2540             if (!isArgumentsSpeculation(m_state.forNode(child1).m_type)) {
    2541                 speculationCheck(
    2542                     BadType, JSValueSource::unboxedCell(baseReg), child1,
    2543                     m_jit.branchPtr(
    2544                         MacroAssembler::NotEqual,
    2545                         MacroAssembler::Address(baseReg, JSCell::classInfoOffset()),
    2546                         MacroAssembler::TrustedImmPtr(&Arguments::s_info)));
    2547             }
    2548    
    25492589            m_jit.loadPtr(
    25502590                MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
     
    25802620            break;
    25812621        }
    2582        
    2583         if (at(child1).shouldSpeculateInt8Array()) {
    2584             compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2585             if (!m_compileOkay)
    2586                 return;
    2587             break;           
    2588         }
    2589        
    2590         if (at(child1).shouldSpeculateInt16Array()) {
    2591             compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2592             if (!m_compileOkay)
    2593                 return;
    2594             break;           
    2595         }
    2596 
    2597         if (at(child1).shouldSpeculateInt32Array()) {
    2598             compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray);
    2599             if (!m_compileOkay)
    2600                 return;
    2601             break;           
    2602         }
    2603        
    2604         if (at(child1).shouldSpeculateUint8Array()) {
    2605             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2606             if (!m_compileOkay)
    2607                 return;
    2608             break;           
    2609         }
    2610 
    2611         if (at(child1).shouldSpeculateUint8ClampedArray()) {
    2612             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding);
    2613             break;
    2614         }
    2615 
    2616         if (at(child1).shouldSpeculateUint16Array()) {
    2617             compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2618             if (!m_compileOkay)
    2619                 return;
    2620             break;           
    2621         }
    2622        
    2623         if (at(child1).shouldSpeculateUint32Array()) {
    2624             compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray);
    2625             if (!m_compileOkay)
    2626                 return;
    2627             break;           
    2628         }
    2629        
    2630         if (at(child1).shouldSpeculateFloat32Array()) {
    2631             compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2632             if (!m_compileOkay)
    2633                 return;
    2634             break;           
    2635         }
    2636        
    2637         if (at(child1).shouldSpeculateFloat64Array()) {
    2638             compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks);
    2639             if (!m_compileOkay)
    2640                 return;
    2641             break;           
    2642         }
    2643            
    2644         JSValueOperand value(this, child3);
    2645         GPRTemporary scratch(this);
    2646 
    2647         // Map base, property & value into registers, allocate a scratch register.
    2648         GPRReg baseReg = base.gpr();
    2649         GPRReg propertyReg = property.gpr();
    2650         GPRReg valueReg = value.gpr();
    2651         GPRReg scratchReg = scratch.gpr();
    2652        
    2653         if (!m_compileOkay)
    2654             return;
    2655        
    2656         writeBarrier(baseReg, value.gpr(), child3, WriteBarrierForPropertyAccess, scratchReg);
    2657 
    2658         speculateArray(child1, baseReg);
    2659 
    2660         MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
    2661         if (node.op() == PutByVal)
    2662             speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
    2663 
    2664         base.use();
    2665         property.use();
    2666         value.use();
    2667        
    2668         // Get the array storage.
    2669         GPRReg storageReg = scratchReg;
    2670         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
    2671 
    2672         // Check if we're writing to a hole; if so increment m_numValuesInVector.
    2673         MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
    2674         m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
    2675 
    2676         // If we're writing to a hole we might be growing the array;
    2677         MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
    2678         m_jit.add32(TrustedImm32(1), propertyReg);
    2679         m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
    2680         m_jit.sub32(TrustedImm32(1), propertyReg);
    2681 
    2682         lengthDoesNotNeedUpdate.link(&m_jit);
    2683         notHoleValue.link(&m_jit);
    2684 
    2685         // Store the value to the array.
    2686         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
    2687 
    2688         if (node.op() == PutByValSafe) {
    2689             addSlowPathGenerator(
    2690                 slowPathCall(
    2691                     beyondArrayBounds, this,
    2692                     m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
    2693                     NoResult, baseReg, propertyReg, valueReg));
    2694         }
    2695 
    2696         noResult(m_compileIndex, UseChildrenCalledExplicitly);
    2697         break;
    2698     }
    2699 
    2700     case PutByValAlias: {
    2701         Edge child1 = m_jit.graph().varArgChild(node, 0);
    2702         Edge child2 = m_jit.graph().varArgChild(node, 1);
    2703         Edge child3 = m_jit.graph().varArgChild(node, 2);
    2704        
    2705         if (!at(child1).prediction() || !at(child2).prediction()) {
    2706             terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
    2707             break;
    2708         }
    2709        
    2710         ASSERT(isActionableMutableArraySpeculation(at(child1).prediction()));
    2711         ASSERT(at(child2).shouldSpeculateInteger());
    2712 
    2713         SpeculateCellOperand base(this, child1);
    2714         SpeculateStrictInt32Operand property(this, child2);
    2715         if (at(child1).shouldSpeculateInt8Array()) {
    2716             compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), NoTypedArraySpecCheck, SignedTypedArray);
    2717             if (!m_compileOkay)
    2718                 return;
    2719             break;           
    2720         }
    2721        
    2722         if (at(child1).shouldSpeculateInt16Array()) {
    2723             compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), NoTypedArraySpecCheck, SignedTypedArray);
    2724             if (!m_compileOkay)
    2725                 return;
    2726             break;           
    2727         }
    2728        
    2729         if (at(child1).shouldSpeculateInt32Array()) {
    2730             compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), NoTypedArraySpecCheck, SignedTypedArray);
    2731             if (!m_compileOkay)
    2732                 return;
    2733             break;           
    2734         }
    2735        
    2736         if (at(child1).shouldSpeculateUint8Array()) {
    2737             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray);
    2738             if (!m_compileOkay)
    2739                 return;
    2740             break;           
    2741         }
    2742 
    2743         if (at(child1).shouldSpeculateUint8ClampedArray()) {
    2744             compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray, ClampRounding);
    2745             if (!m_compileOkay)
    2746                 return;
    2747             break;
    2748         }
    2749 
    2750         if (at(child1).shouldSpeculateUint16Array()) {
    2751             compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), NoTypedArraySpecCheck, UnsignedTypedArray);
    2752             if (!m_compileOkay)
    2753                 return;
    2754             break;           
    2755         }
    2756        
    2757         if (at(child1).shouldSpeculateUint32Array()) {
    2758             compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), NoTypedArraySpecCheck, UnsignedTypedArray);
    2759             if (!m_compileOkay)
    2760                 return;
    2761             break;           
    2762         }
    2763        
    2764         if (at(child1).shouldSpeculateFloat32Array()) {
    2765             compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), NoTypedArraySpecCheck);
    2766             if (!m_compileOkay)
    2767                 return;
    2768             break;           
    2769         }
    2770        
    2771         if (at(child1).shouldSpeculateFloat64Array()) {
    2772             compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), NoTypedArraySpecCheck);
    2773             if (!m_compileOkay)
    2774                 return;
    2775             break;           
    2776         }
    2777        
    2778         ASSERT(at(child1).shouldSpeculateArray());
    2779 
    2780         JSValueOperand value(this, child3);
    2781         GPRTemporary scratch(this);
    2782        
    2783         GPRReg baseReg = base.gpr();
    2784         GPRReg scratchReg = scratch.gpr();
    2785 
    2786         writeBarrier(base.gpr(), value.gpr(), child3, WriteBarrierForPropertyAccess, scratchReg);
    2787 
    2788         // Get the array storage.
    2789         GPRReg storageReg = scratchReg;
    2790         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
    2791 
    2792         // Store the value to the array.
    2793         GPRReg propertyReg = property.gpr();
    2794         GPRReg valueReg = value.gpr();
    2795         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
    2796 
    2797         noResult(m_compileIndex);
    2798         break;
    2799     }
    2800        
     2622           
     2623        case Array::Int8Array:
     2624            compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), SignedTypedArray);
     2625            break;
     2626           
     2627        case Array::Int16Array:
     2628            compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), SignedTypedArray);
     2629            break;
     2630           
     2631        case Array::Int32Array:
     2632            compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), SignedTypedArray);
     2633            break;
     2634           
     2635        case Array::Uint8Array:
     2636            compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray);
     2637            break;
     2638           
     2639        case Array::Uint8ClampedArray:
     2640            compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray, ClampRounding);
     2641            break;
     2642           
     2643        case Array::Uint16Array:
     2644            compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), UnsignedTypedArray);
     2645            break;
     2646           
     2647        case Array::Uint32Array:
     2648            compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), UnsignedTypedArray);
     2649            break;
     2650           
     2651        case Array::Float32Array:
     2652            compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float));
     2653            break;
     2654           
     2655        case Array::Float64Array:
     2656            compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double));
     2657            break;
     2658           
     2659        default:
     2660            ASSERT_NOT_REACHED();
     2661            break;
     2662        }
     2663
     2664        break;
     2665    }
     2666
    28012667    case RegExpExec: {
    28022668        if (compileRegExpExec(node))
     
    28602726        writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, storageGPR, storageLengthGPR);
    28612727
    2862         speculateArray(node.child1(), baseGPR);
     2728        speculateArray(Array::JSArray, node.child1(), baseGPR);
    28632729
    28642730        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
     
    28972763        GPRReg storageLengthGPR = storageLength.gpr();
    28982764       
    2899         speculateArray(node.child1(), baseGPR);
     2765        speculateArray(Array::JSArray, node.child1(), baseGPR);
    29002766
    29012767        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
     
    33873253    }
    33883254
    3389     case GetArrayLength: {
    3390         SpeculateCellOperand base(this, node.child1());
    3391         GPRTemporary result(this);
    3392        
    3393         GPRReg baseGPR = base.gpr();
    3394         GPRReg resultGPR = result.gpr();
    3395        
    3396         speculateArray(node.child1(), baseGPR);
    3397 
    3398         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
    3399         m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
    3400        
    3401         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));
    3402        
    3403         integerResult(resultGPR, m_compileIndex);
    3404         break;
    3405     }
    3406        
    3407     case GetArgumentsLength: {
    3408         compileGetArgumentsLength(node);
    3409         break;
    3410     }
    3411 
    3412     case GetStringLength: {
    3413         SpeculateCellOperand base(this, node.child1());
    3414         GPRTemporary result(this);
    3415        
    3416         GPRReg baseGPR = base.gpr();
    3417         GPRReg resultGPR = result.gpr();
    3418        
    3419         if (!isStringSpeculation(m_state.forNode(node.child1()).m_type))
    3420             speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
    3421        
    3422         m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
    3423 
    3424         integerResult(resultGPR, m_compileIndex);
    3425         break;
    3426     }
    3427 
    3428     case GetInt8ArrayLength: {
    3429         compileGetTypedArrayLength(m_jit.globalData()->int8ArrayDescriptor(), node, !isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3430         break;
    3431     }
    3432     case GetInt16ArrayLength: {
    3433         compileGetTypedArrayLength(m_jit.globalData()->int16ArrayDescriptor(), node, !isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3434         break;
    3435     }
    3436     case GetInt32ArrayLength: {
    3437         compileGetTypedArrayLength(m_jit.globalData()->int32ArrayDescriptor(), node, !isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3438         break;
    3439     }
    3440     case GetUint8ArrayLength: {
    3441         compileGetTypedArrayLength(m_jit.globalData()->uint8ArrayDescriptor(), node, !isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3442         break;
    3443     }
    3444     case GetUint8ClampedArrayLength: {
    3445         compileGetTypedArrayLength(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, !isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type));
    3446         break;
    3447     }
    3448     case GetUint16ArrayLength: {
    3449         compileGetTypedArrayLength(m_jit.globalData()->uint16ArrayDescriptor(), node, !isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3450         break;
    3451     }
    3452     case GetUint32ArrayLength: {
    3453         compileGetTypedArrayLength(m_jit.globalData()->uint32ArrayDescriptor(), node, !isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3454         break;
    3455     }
    3456     case GetFloat32ArrayLength: {
    3457         compileGetTypedArrayLength(m_jit.globalData()->float32ArrayDescriptor(), node, !isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3458         break;
    3459     }
    3460     case GetFloat64ArrayLength: {
    3461         compileGetTypedArrayLength(m_jit.globalData()->float64ArrayDescriptor(), node, !isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type));
    3462         break;
    3463     }
     3255    case GetArrayLength:
     3256        compileGetArrayLength(node);
     3257        break;
     3258       
    34643259    case CheckFunction: {
    34653260        SpeculateCellOperand function(this, node.child1());
  • trunk/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp

    r125999 r126387  
    9999                case PutByVal:
    100100                case PutByValAlias:
    101                 case PutByValSafe:
    102101                case GetArrayLength:
    103102                case Phantom:
     
    216215                   
    217216                case GetByVal:
    218                     if (!node.prediction() || !m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction())
    219                         break;
    220                     if (!isActionableArraySpeculation(m_graph[node.child1()].prediction()) || !m_graph[node.child2()].shouldSpeculateInteger())
    221                         clobber(live);
    222                     break;
    223                    
    224217                case PutByVal:
    225218                case PutByValAlias:
    226                 case PutByValSafe: {
    227                     Edge child1 = m_graph.varArgChild(node, 0);
    228                     Edge child2 = m_graph.varArgChild(node, 1);
    229                    
    230                     if (!m_graph[child1].prediction() || !m_graph[child2].prediction())
    231                         break;
    232                     if (!m_graph[child2].shouldSpeculateInteger()
    233 #if USE(JSVALUE32_64)
    234                         || m_graph[child1].shouldSpeculateArguments()
    235 #endif
    236                         ) {
    237                         clobber(live);
    238                         break;
    239                     }
    240                     if (node.op() != PutByValSafe)
    241                         break;
    242                     if (m_graph[child1].shouldSpeculateArguments())
    243                         break;
    244                     if (m_graph[child1].shouldSpeculateInt8Array())
    245                         break;
    246                     if (m_graph[child1].shouldSpeculateInt16Array())
    247                         break;
    248                     if (m_graph[child1].shouldSpeculateInt32Array())
    249                         break;
    250                     if (m_graph[child1].shouldSpeculateUint8Array())
    251                         break;
    252                     if (m_graph[child1].shouldSpeculateUint8ClampedArray())
    253                         break;
    254                     if (m_graph[child1].shouldSpeculateUint16Array())
    255                         break;
    256                     if (m_graph[child1].shouldSpeculateUint32Array())
    257                         break;
    258                     if (m_graph[child1].shouldSpeculateFloat32Array())
    259                         break;
    260                     if (m_graph[child1].shouldSpeculateFloat64Array())
     219                    if (m_graph.byValIsPure(node))
    261220                        break;
    262221                    clobber(live);
    263222                    break;
    264                 }
    265223                   
    266224                case GetMyArgumentsLengthSafe:
Note: See TracChangeset for help on using the changeset viewer.