Changeset 126387 in webkit
- Timestamp:
- Aug 22, 2012 8:38:52 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r126354 r126387 67 67 dfg/DFGAbstractState.cpp 68 68 dfg/DFGArgumentsSimplificationPhase.cpp 69 dfg/DFGArrayMode.cpp 69 70 dfg/DFGAssemblyHelpers.cpp 70 71 dfg/DFGByteCodeParser.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r126379 r126387 1 2012-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 1 87 2012-08-22 Geoffrey Garen <ggaren@apple.com> 2 88 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r126354 r126387 156 156 Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp \ 157 157 Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h \ 158 Source/JavaScriptCore/dfg/DFGArrayMode.cpp \ 159 Source/JavaScriptCore/dfg/DFGArrayMode.h \ 158 160 Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp \ 159 161 Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r126354 r126387 143 143 0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63945115D07051006A597C /* ArrayProfile.cpp */; }; 144 144 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, ); }; }; 145 147 0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; 146 148 0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 900 902 0F63945115D07051006A597C /* ArrayProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayProfile.cpp; sourceTree = "<group>"; }; 901 903 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>"; }; 902 906 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureAbstractValue.h; path = dfg/DFGStructureAbstractValue.h; sourceTree = "<group>"; }; 903 907 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; }; … … 2267 2271 isa = PBXGroup; 2268 2272 children = ( 2273 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */, 2274 0F62016E143FCD2F0068B77C /* DFGAbstractState.h */, 2275 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */, 2276 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */, 2269 2277 0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */, 2270 2278 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */, 2271 2279 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */, 2272 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */, 2273 0F62016E143FCD2F0068B77C /* DFGAbstractState.h */, 2274 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */, 2280 0F63948115E48114006A597C /* DFGArrayMode.cpp */, 2281 0F63948215E48114006A597C /* DFGArrayMode.h */, 2275 2282 0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */, 2276 2283 0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */, … … 2316 2323 0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */, 2317 2324 0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */, 2318 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */,2319 2325 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */, 2320 2326 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */, … … 2896 2902 0F63943F15C75F19006A597C /* DFGStructureCheckHoistingPhase.h in Headers */, 2897 2903 0F63945515D07057006A597C /* ArrayProfile.h in Headers */, 2904 0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */, 2898 2905 0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */, 2899 2906 ); … … 3497 3504 0F63944015C75F1D006A597C /* DFGStructureCheckHoistingPhase.cpp in Sources */, 3498 3505 0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */, 3506 0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */, 3499 3507 C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */, 3500 3508 ); -
trunk/Source/JavaScriptCore/Target.pri
r126354 r126387 97 97 dfg/DFGAbstractState.cpp \ 98 98 dfg/DFGArgumentsSimplificationPhase.cpp \ 99 dfg/DFGArrayMode.cpp \ 99 100 dfg/DFGAssemblyHelpers.cpp \ 100 101 dfg/DFGByteCodeParser.cpp \ -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r125999 r126387 869 869 case GetByVal: { 870 870 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: 872 876 m_isValid = false; 873 877 break; 874 } 875 if (!m_graph[node.child2()].shouldSpeculateInteger() || (!node.child3() && !m_graph[node.child1()].shouldSpeculateArguments())) { 878 case Array::Generic: 876 879 clobberWorld(node.codeOrigin, indexInBlock); 877 880 forNode(nodeIndex).makeTop(); 878 881 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: 881 888 forNode(node.child1()).filter(SpecArguments); 882 889 forNode(node.child2()).filter(SpecInt32); 883 890 forNode(nodeIndex).makeTop(); 884 891 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); 888 897 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: 894 901 forNode(node.child1()).filter(SpecInt8Array); 895 902 forNode(node.child2()).filter(SpecInt32); 896 903 forNode(nodeIndex).set(SpecInt32); 897 904 break; 898 } 899 if (m_graph[node.child1()].shouldSpeculateInt16Array()) { 905 case Array::Int16Array: 900 906 forNode(node.child1()).filter(SpecInt16Array); 901 907 forNode(node.child2()).filter(SpecInt32); 902 908 forNode(nodeIndex).set(SpecInt32); 903 909 break; 904 } 905 if (m_graph[node.child1()].shouldSpeculateInt32Array()) { 910 case Array::Int32Array: 906 911 forNode(node.child1()).filter(SpecInt32Array); 907 912 forNode(node.child2()).filter(SpecInt32); 908 913 forNode(nodeIndex).set(SpecInt32); 909 914 break; 910 } 911 if (m_graph[node.child1()].shouldSpeculateUint8Array()) { 915 case Array::Uint8Array: 912 916 forNode(node.child1()).filter(SpecUint8Array); 913 917 forNode(node.child2()).filter(SpecInt32); 914 918 forNode(nodeIndex).set(SpecInt32); 915 919 break; 916 } 917 if (m_graph[node.child1()].shouldSpeculateUint8ClampedArray()) { 920 case Array::Uint8ClampedArray: 918 921 forNode(node.child1()).filter(SpecUint8ClampedArray); 919 922 forNode(node.child2()).filter(SpecInt32); 920 923 forNode(nodeIndex).set(SpecInt32); 921 924 break; 922 } 923 if (m_graph[node.child1()].shouldSpeculateUint16Array()) { 925 case Array::Uint16Array: 924 926 forNode(node.child1()).filter(SpecUint16Array); 925 927 forNode(node.child2()).filter(SpecInt32); 926 928 forNode(nodeIndex).set(SpecInt32); 927 929 break; 928 } 929 if (m_graph[node.child1()].shouldSpeculateUint32Array()) { 930 case Array::Uint32Array: 930 931 forNode(node.child1()).filter(SpecUint32Array); 931 932 forNode(node.child2()).filter(SpecInt32); … … 935 936 forNode(nodeIndex).set(SpecDouble); 936 937 break; 937 } 938 if (m_graph[node.child1()].shouldSpeculateFloat32Array()) { 938 case Array::Float32Array: 939 939 forNode(node.child1()).filter(SpecFloat32Array); 940 940 forNode(node.child2()).filter(SpecInt32); 941 941 forNode(nodeIndex).set(SpecDouble); 942 942 break; 943 } 944 if (m_graph[node.child1()].shouldSpeculateFloat64Array()) { 943 case Array::Float64Array: 945 944 forNode(node.child1()).filter(SpecFloat64Array); 946 945 forNode(node.child2()).filter(SpecInt32); … … 948 947 break; 949 948 } 950 forNode(node.child1()).filter(SpecCell);951 forNode(node.child2()).filter(SpecInt32);952 forNode(nodeIndex).makeTop();953 949 break; 954 950 } 955 951 956 952 case PutByVal: 957 case PutByValAlias: 958 case PutByValSafe: { 959 node.setCanExit(true); 960 953 case PutByValAlias: { 954 node.setCanExit(true); 961 955 Edge child1 = m_graph.varArgChild(node, 0); 962 956 Edge child2 = m_graph.varArgChild(node, 1); 963 957 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: 966 960 m_isValid = false; 967 961 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: 975 963 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: 981 975 forNode(child1).filter(SpecArguments); 982 976 forNode(child2).filter(SpecInt32); 983 977 break; 984 } 985 if (m_graph[child1].shouldSpeculateInt8Array()) { 978 case Array::Int8Array: 986 979 forNode(child1).filter(SpecInt8Array); 987 980 forNode(child2).filter(SpecInt32); … … 991 984 forNode(child3).filter(SpecNumber); 992 985 break; 993 } 994 if (m_graph[child1].shouldSpeculateInt16Array()) { 986 case Array::Int16Array: 995 987 forNode(child1).filter(SpecInt16Array); 996 988 forNode(child2).filter(SpecInt32); … … 1000 992 forNode(child3).filter(SpecNumber); 1001 993 break; 1002 } 1003 if (m_graph[child1].shouldSpeculateInt32Array()) { 994 case Array::Int32Array: 1004 995 forNode(child1).filter(SpecInt32Array); 1005 996 forNode(child2).filter(SpecInt32); … … 1009 1000 forNode(child3).filter(SpecNumber); 1010 1001 break; 1011 } 1012 if (m_graph[child1].shouldSpeculateUint8Array()) { 1002 case Array::Uint8Array: 1013 1003 forNode(child1).filter(SpecUint8Array); 1014 1004 forNode(child2).filter(SpecInt32); … … 1018 1008 forNode(child3).filter(SpecNumber); 1019 1009 break; 1020 } 1021 if (m_graph[child1].shouldSpeculateUint8ClampedArray()) { 1010 case Array::Uint8ClampedArray: 1022 1011 forNode(child1).filter(SpecUint8ClampedArray); 1023 1012 forNode(child2).filter(SpecInt32); … … 1027 1016 forNode(child3).filter(SpecNumber); 1028 1017 break; 1029 } 1030 if (m_graph[child1].shouldSpeculateUint16Array()) { 1018 case Array::Uint16Array: 1031 1019 forNode(child1).filter(SpecUint16Array); 1032 1020 forNode(child2).filter(SpecInt32); … … 1036 1024 forNode(child3).filter(SpecNumber); 1037 1025 break; 1038 } 1039 if (m_graph[child1].shouldSpeculateUint32Array()) { 1026 case Array::Uint32Array: 1040 1027 forNode(child1).filter(SpecUint32Array); 1041 1028 forNode(child2).filter(SpecInt32); … … 1045 1032 forNode(child3).filter(SpecNumber); 1046 1033 break; 1047 } 1048 if (m_graph[child1].shouldSpeculateFloat32Array()) { 1034 case Array::Float32Array: 1049 1035 forNode(child1).filter(SpecFloat32Array); 1050 1036 forNode(child2).filter(SpecInt32); 1051 1037 forNode(child3).filter(SpecNumber); 1052 1038 break; 1053 } 1054 if (m_graph[child1].shouldSpeculateFloat64Array()) { 1039 case Array::Float64Array: 1055 1040 forNode(child1).filter(SpecFloat64Array); 1056 1041 forNode(child2).filter(SpecInt32); 1057 1042 forNode(child3).filter(SpecNumber); 1058 1043 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 } 1064 1048 break; 1065 1049 } … … 1357 1341 1358 1342 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 1422 1419 case CheckStructure: 1423 1420 case ForwardCheckStructure: { … … 1490 1487 break; 1491 1488 case GetIndexedPropertyStorage: { 1492 ASSERT(m_graph[node.child1()].prediction());1493 ASSERT(m_graph[node.child2()].shouldSpeculateInteger());1494 1489 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: 1496 1528 ASSERT_NOT_REACHED(); 1497 1529 break; 1498 1530 } 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);1551 1531 forNode(nodeIndex).clear(); 1552 1532 break; -
trunk/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
r125999 r126387 146 146 147 147 // Figure out which variables alias the arguments and nothing else, and are 148 // used only for GetByVal and GetAr gumentsLength accesses. At the same time,148 // used only for GetByVal and GetArrayLength accesses. At the same time, 149 149 // identify uses of CreateArguments that are not consistent with the arguments 150 150 // being aliased only to variables that satisfy these constraints. … … 278 278 279 279 case GetByVal: { 280 if (!node.prediction() 281 || !m_graph[node.child1()].prediction() 282 || !m_graph[node.child2()].prediction()) { 280 if (node.arrayMode() != Array::Arguments) { 283 281 observeBadArgumentsUses(node); 284 282 break; 285 283 } 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) { 289 295 observeBadArgumentsUses(node); 290 296 break; 291 297 } 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 308 299 observeProperArgumentsUse(node, node.child1()); 309 300 break; … … 497 488 498 489 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 531 516 if (!isOKToOptimize(m_graph[node.child1()])) 532 517 break; -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r125982 r126387 32 32 #include "CallLinkStatus.h" 33 33 #include "CodeBlock.h" 34 #include "DFGArrayMode.h" 34 35 #include "DFGByteCodeCache.h" 35 36 #include "DFGCapabilities.h" … … 817 818 return getPrediction(m_graph.size(), m_currentProfilingIndex); 818 819 } 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 } 819 850 820 851 NodeIndex makeSafe(NodeIndex nodeIndex) … … 1549 1580 1550 1581 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)); 1553 1583 1554 1584 if (usesResult) … … 1566 1596 1567 1597 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)); 1570 1599 1571 1600 if (usesResult) … … 2149 2178 2150 2179 NodeIndex base = get(currentInstruction[2].u.operand); 2180 Array::Mode arrayMode = getArrayMode(currentInstruction, base); 2151 2181 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); 2158 2183 set(currentInstruction[1].u.operand, getByVal); 2159 2184 … … 2163 2188 case op_put_by_val: { 2164 2189 NodeIndex base = get(currentInstruction[1].u.operand); 2190 2191 Array::Mode arrayMode = getArrayMode(currentInstruction, base); 2192 2165 2193 NodeIndex property = get(currentInstruction[2].u.operand); 2166 2194 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 #endif2176 2177 bool makeSafe =2178 m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)2179 || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds);2180 2195 2181 2196 addVarArgChild(base); 2182 2197 addVarArgChild(property); 2183 2198 addVarArgChild(value); 2184 addToGraph(Node::VarArg, makeSafe ? PutByValSafe : PutByVal, OpInfo(0), OpInfo(0));2199 addToGraph(Node::VarArg, PutByVal, OpInfo(arrayMode), OpInfo(0)); 2185 2200 2186 2201 NEXT_OPCODE(op_put_by_val); -
trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
r125999 r126387 285 285 break; 286 286 case PutByVal: 287 case PutByValAlias: 288 case PutByValSafe: { 287 case PutByValAlias: { 289 288 if (!m_graph.byValIsPure(node)) 290 289 return NoNode; … … 366 365 case PutByVal: 367 366 case PutByValAlias: 368 case PutByValSafe:369 367 if (m_graph.byValIsPure(node)) { 370 368 // If PutByVal speculates that it's accessing an array with an … … 410 408 case PutByVal: 411 409 case PutByValAlias: 412 case PutByValSafe:413 410 if (m_graph.byValIsPure(node)) { 414 411 // If PutByVal speculates that it's accessing an array with an … … 516 513 case PutByVal: 517 514 case PutByValAlias: 518 case PutByValSafe:519 515 if (m_graph.byValIsPure(node)) { 520 516 // If PutByVal speculates that it's accessing an array with an … … 561 557 case PutByValAlias: 562 558 case GetByVal: 563 case PutByValSafe:564 559 if (m_graph.byValIsPure(node)) { 565 560 // If PutByVal speculates that it's accessing an array with an … … 614 609 case PutByVal: 615 610 case PutByValAlias: 616 case PutByValSafe:617 611 if (m_graph.byValIsPure(node)) { 618 612 // If PutByVal speculates that it's accessing an array with an … … 926 920 case ArithMax: 927 921 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:937 922 case GetCallee: 938 case GetStringLength:939 923 case StringCharAt: 940 924 case StringCharCodeAt: … … 1104 1088 break; 1105 1089 1106 case PutByVal: 1107 case PutByValSafe: { 1090 case PutByVal: { 1108 1091 Edge child1 = m_graph.varArgChild(node, 0); 1109 1092 Edge child2 = m_graph.varArgChild(node, 1); -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r125637 r126387 75 75 switch (op) { 76 76 case GetById: { 77 Node* nodePtr = &node; 78 77 79 if (!isInt32Speculation(m_graph[m_compileIndex].prediction())) 78 80 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) { 110 88 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); 148 114 m_graph.deref(m_compileIndex); 115 nodePtr->setArrayMode(arrayMode); 149 116 break; 150 117 } 151 118 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())); 161 128 break; 162 129 } … … 164 131 case StringCharAt: 165 132 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 } 168 160 break; 169 161 } … … 335 327 336 328 case PutByVal: 337 case PutByVal Safe: {329 case PutByValAlias: { 338 330 Edge child1 = m_graph.varArgChild(node, 0); 339 331 Edge child2 = m_graph.varArgChild(node, 1); 340 332 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: 350 350 fixDoubleEdge(2); 351 351 break; 352 } 353 if (isActionableFloatMutableArraySpeculation(m_graph[child1].prediction())) { 354 fixDoubleEdge(2); 352 default: 355 353 break; 356 354 } -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r124555 r126387 212 212 hasPrinted = true; 213 213 } 214 if (node.hasArrayMode()) { 215 dataLog("%s%s", hasPrinted ? ", " : "", modeToString(node.arrayMode())); 216 hasPrinted = true; 217 } 214 218 if (node.hasVarNumber()) { 215 219 dataLog("%svar%u", hasPrinted ? ", " : "", node.varNumber()); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r125982 r126387 489 489 bool byValIsPure(Node& node) 490 490 { 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: 498 504 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;533 505 } 534 506 } … … 550 522 case GetByVal: 551 523 case PutByVal: 552 case PutByValSafe:553 524 case PutByValAlias: 554 525 return !byValIsPure(node); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r125999 r126387 34 34 #include "CodeOrigin.h" 35 35 #include "DFGAdjacencyList.h" 36 #include "DFGArrayMode.h" 36 37 #include "DFGCommon.h" 37 38 #include "DFGNodeFlags.h" … … 733 734 } 734 735 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 735 764 bool hasVirtualRegister() 736 765 { -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r125999 r126387 114 114 macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \ 115 115 macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \ 116 macro(PutByValSafe, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \117 116 macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \ 118 117 macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ … … 144 143 macro(PutByOffset, NodeMustGenerate) \ 145 144 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) \157 145 macro(GetScopeChain, NodeResultJS) \ 158 146 macro(GetScopedVar, NodeResultJS | NodeMustGenerate) \ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r125999 r126387 613 613 case PutByValAlias: 614 614 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:626 615 case Int32ToDouble: 627 616 case DoubleAsInt32: … … 638 627 639 628 case PutByVal: 640 case PutByValSafe:641 629 changed |= m_graph[m_graph.varArgChild(node, 0)].mergeFlags(NodeUsedAsValue); 642 630 changed |= m_graph[m_graph.varArgChild(node, 1)].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r125999 r126387 270 270 } 271 271 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; 272 const 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 298 const 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 } 278 348 279 349 GPRTemporary temp(this); … … 285 355 MacroAssembler::NotEqual, 286 356 MacroAssembler::Address(temp.gpr(), Structure::classInfoOffset()), 287 MacroAssembler::TrustedImmPtr(&JSArray::s_info))); 357 MacroAssembler::TrustedImmPtr(expectedClassInfo))); 358 359 return result; 288 360 } 289 361 … … 1621 1693 GPRReg storageReg = storage.gpr(); 1622 1694 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)); 1628 1696 1629 1697 // unsigned comparison so we can filter out negative indices and indices that are too large … … 2019 2087 } 2020 2088 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) 2089 void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySignedness signedness) 2038 2090 { 2039 2091 SpeculateCellOperand base(this, node.child1()); … … 2048 2100 GPRReg resultReg = result.gpr(); 2049 2101 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())); 2056 2103 2057 2104 speculationCheck( … … 2098 2145 } 2099 2146 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); 2147 void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySignedness signedness, TypedArrayRounding rounding) 2148 { 2103 2149 Edge valueUse = m_jit.graph().varArgChild(node, 2); 2104 2150 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)));2107 2151 GPRTemporary value; 2108 2152 GPRReg valueGPR; … … 2175 2219 m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg); 2176 2220 MacroAssembler::Jump outOfBounds; 2177 if ( speculationRequirements != NoTypedArraySpecCheck)2221 if (node.op() == PutByVal) 2178 2222 outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset)); 2179 2223 … … 2191 2235 ASSERT_NOT_REACHED(); 2192 2236 } 2193 if ( speculationRequirements != NoTypedArraySpecCheck)2237 if (node.op() == PutByVal) 2194 2238 outOfBounds.link(&m_jit); 2195 2239 noResult(m_compileIndex); 2196 2240 } 2197 2241 2198 void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize , TypedArraySpeculationRequirements speculationRequirements)2242 void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize) 2199 2243 { 2200 2244 SpeculateCellOperand base(this, node.child1()); … … 2205 2249 GPRReg propertyReg = property.gpr(); 2206 2250 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())); 2214 2253 2215 2254 FPRTemporary result(this); 2216 2255 FPRReg resultReg = result.fpr(); 2217 ASSERT(speculationRequirements != NoTypedArraySpecCheck);2218 2256 speculationCheck( 2219 2257 Uncountable, JSValueRegs(), NoNode, … … 2239 2277 } 2240 2278 2241 void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize , TypedArraySpeculationRequirements speculationRequirements)2279 void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize) 2242 2280 { 2243 2281 Edge baseUse = m_jit.graph().varArgChild(node, 0); … … 2246 2284 SpeculateDoubleOperand valueOp(this, valueUse); 2247 2285 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())); 2250 2287 2251 2288 GPRTemporary result(this); … … 2256 2293 m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg); 2257 2294 MacroAssembler::Jump outOfBounds; 2258 if ( speculationRequirements != NoTypedArraySpecCheck)2295 if (node.op() == PutByVal) 2259 2296 outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset)); 2260 2297 … … 2273 2310 ASSERT_NOT_REACHED(); 2274 2311 } 2275 if ( speculationRequirements != NoTypedArraySpecCheck)2312 if (node.op() == PutByVal) 2276 2313 outOfBounds.link(&m_jit); 2277 2314 noResult(m_compileIndex); … … 3067 3104 void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node) 3068 3105 { 3069 ASSERT(at(node.child1()).prediction());3070 ASSERT(at(node.child2()).shouldSpeculateInteger());3071 3072 3106 SpeculateCellOperand base(this, node.child1()); 3073 3107 GPRReg baseReg = base.gpr(); … … 3075 3109 GPRTemporary storage(this); 3076 3110 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: 3083 3117 m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg); 3084 3118 … … 3087 3121 3088 3122 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: 3136 3127 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 3138 3136 storageResult(storageReg, m_compileIndex); 3139 3137 } … … 3253 3251 } 3254 3252 3253 void 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 3255 3289 void SpeculativeJIT::compileNewFunctionNoCheck(Node& node) 3256 3290 { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r125999 r126387 2083 2083 void compileGetArgumentsLength(Node&); 2084 2084 2085 void compileGetArrayLength(Node&); 2086 2085 2087 void compileValueToInt32(Node&); 2086 2088 void compileUInt32ToNumber(Node&); … … 2096 2098 void compileArithMod(Node&); 2097 2099 void compileSoftModulo(Node&); 2098 void compileGetTypedArrayLength(const TypedArrayDescriptor&, Node&, bool needsSpeculationCheck);2099 enum TypedArraySpeculationRequirements {2100 NoTypedArraySpecCheck,2101 NoTypedArrayTypeSpecCheck,2102 AllTypedArraySpecChecks2103 };2104 2100 enum TypedArraySignedness { 2105 2101 SignedTypedArray, … … 2111 2107 }; 2112 2108 void compileGetIndexedPropertyStorage(Node&); 2113 void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArrayS peculationRequirements, TypedArraySignedness);2114 void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArrayS peculationRequirements, 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); 2117 2113 void compileNewFunctionNoCheck(Node&); 2118 2114 void compileNewFunctionExpression(Node&); … … 2200 2196 JumpReplacementWatchpoint* speculationWatchpointWithConditionalDirection(ExitKind, bool isForward); 2201 2197 2202 void speculateArray(Edge baseEdge, GPRReg baseReg); 2198 const TypedArrayDescriptor* typedArrayDescriptor(Array::Mode); 2199 2200 const TypedArrayDescriptor* speculateArray(Array::Mode, Edge baseEdge, GPRReg baseReg); 2203 2201 2204 2202 template<bool strict> -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r126082 r126387 2342 2342 2343 2343 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(); 2345 2348 terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); 2346 2349 break; 2347 } 2348 2349 if (!at(node.child2()).shouldSpeculateInteger() || (!node.child3() && !at(node.child1()).shouldSpeculateArguments())) { 2350 case Array::Generic: { 2350 2351 SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right. 2351 2352 JSValueOperand property(this, node.child2()); … … 2362 2363 break; 2363 2364 } 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 2367 2372 if (!m_compileOkay) 2368 2373 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: 2373 2395 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 } 2467 2431 break; 2468 2432 } 2469 2433 2470 2434 case PutByVal: 2471 case PutByVal Safe: {2435 case PutByValAlias: { 2472 2436 Edge child1 = m_jit.graph().varArgChild(node, 0); 2473 2437 Edge child2 = m_jit.graph().varArgChild(node, 1); 2474 2438 Edge child3 = m_jit.graph().varArgChild(node, 2); 2475 2439 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(); 2477 2447 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 2483 2453 SpeculateCellOperand base(this, child1); // Save a register, speculate cell. We'll probably be right. 2484 2454 JSValueOperand property(this, child2); … … 2494 2464 2495 2465 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 2499 2476 SpeculateCellOperand base(this, child1); 2500 2477 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 2503 2492 if (!m_compileOkay) 2504 2493 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 } 2723 2604 break; 2724 2605 } … … 2788 2669 } 2789 2670 2790 speculateArray( node.child1(), baseGPR);2671 speculateArray(Array::JSArray, node.child1(), baseGPR); 2791 2672 2792 2673 GPRTemporary storage(this); … … 2828 2709 GPRReg storageLengthGPR = storageLength.gpr(); 2829 2710 2830 speculateArray( node.child1(), baseGPR);2711 speculateArray(Array::JSArray, node.child1(), baseGPR); 2831 2712 2832 2713 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR); … … 3374 3255 } 3375 3256 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 3452 3261 case CheckFunction: { 3453 3262 SpeculateCellOperand function(this, node.child1()); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r125999 r126387 2375 2375 2376 2376 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(); 2378 2381 terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); 2379 2382 break; 2380 } 2381 2382 if (!at(node.child2()).shouldSpeculateInteger() || (!node.child3() && !at(node.child1()).shouldSpeculateArguments())) { 2383 case Array::Generic: { 2383 2384 JSValueOperand base(this, node.child1()); 2384 2385 JSValueOperand property(this, node.child2()); … … 2393 2394 break; 2394 2395 } 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 2398 2406 if (!m_compileOkay) 2399 2407 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: 2404 2422 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 } 2494 2458 break; 2495 2459 } 2496 2460 2497 2461 case PutByVal: 2498 case PutByVal Safe: {2462 case PutByValAlias: { 2499 2463 Edge child1 = m_jit.graph().varArgChild(node, 0); 2500 2464 Edge child2 = m_jit.graph().varArgChild(node, 1); 2501 2465 Edge child3 = m_jit.graph().varArgChild(node, 2); 2502 2466 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(); 2504 2474 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 2509 2480 JSValueOperand arg1(this, child1); 2510 2481 JSValueOperand arg2(this, child2); … … 2518 2489 2519 2490 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 2523 2501 SpeculateCellOperand base(this, child1); 2524 2502 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: { 2527 2578 JSValueOperand value(this, child3); 2528 2579 GPRTemporary scratch(this); 2529 2580 GPRTemporary scratch2(this); 2530 2581 2531 GPRReg baseReg = base.gpr();2532 GPRReg propertyReg = property.gpr();2533 2582 GPRReg valueReg = value.gpr(); 2534 2583 GPRReg scratchReg = scratch.gpr(); … … 2538 2587 return; 2539 2588 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 2549 2589 m_jit.loadPtr( 2550 2590 MacroAssembler::Address(baseReg, Arguments::offsetOfData()), … … 2580 2620 break; 2581 2621 } 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 2801 2667 case RegExpExec: { 2802 2668 if (compileRegExpExec(node)) … … 2860 2726 writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, storageGPR, storageLengthGPR); 2861 2727 2862 speculateArray( node.child1(), baseGPR);2728 speculateArray(Array::JSArray, node.child1(), baseGPR); 2863 2729 2864 2730 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR); … … 2897 2763 GPRReg storageLengthGPR = storageLength.gpr(); 2898 2764 2899 speculateArray( node.child1(), baseGPR);2765 speculateArray(Array::JSArray, node.child1(), baseGPR); 2900 2766 2901 2767 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR); … … 3387 3253 } 3388 3254 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 3464 3259 case CheckFunction: { 3465 3260 SpeculateCellOperand function(this, node.child1()); -
trunk/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
r125999 r126387 99 99 case PutByVal: 100 100 case PutByValAlias: 101 case PutByValSafe:102 101 case GetArrayLength: 103 102 case Phantom: … … 216 215 217 216 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 224 217 case PutByVal: 225 218 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)) 261 220 break; 262 221 clobber(live); 263 222 break; 264 }265 223 266 224 case GetMyArgumentsLengthSafe:
Note: See TracChangeset
for help on using the changeset viewer.