Changeset 103604 in webkit
- Timestamp:
- Dec 22, 2011, 9:47:17 PM (14 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r103599 r103604 1 2011-12-22 Filip Pizlo <[email protected]> 2 3 DFG should not speculate array even when predictions say that the base is not an array 4 https://bugs.webkit.org/show_bug.cgi?id=75160 5 <rdar://problem/10622646> 6 <rdar://problem/10622649> 7 8 Reviewed by Oliver Hunt. 9 10 Added the ability to call slow path when the base is known to not be an array. 11 Also rationalized the logic for deciding when the index is not an int, and 12 cleaned up the logic for deciding when to speculate typed array. 13 14 Neutral for the most part, with odd speed-ups and slow-downs. The slow-downs can 15 likely be mitigated by having the notion of a polymorphic array access, where we 16 try, but don't speculate, to access the array one way before either trying some 17 other ways or calling slow path. 18 19 * bytecode/PredictedType.h: 20 (JSC::isActionableMutableArrayPrediction): 21 (JSC::isActionableArrayPrediction): 22 * dfg/DFGAbstractState.cpp: 23 (JSC::DFG::AbstractState::execute): 24 * dfg/DFGNode.h: 25 (JSC::DFG::Node::shouldSpeculateInt8Array): 26 (JSC::DFG::Node::shouldSpeculateInt16Array): 27 (JSC::DFG::Node::shouldSpeculateInt32Array): 28 (JSC::DFG::Node::shouldSpeculateUint8Array): 29 (JSC::DFG::Node::shouldSpeculateUint16Array): 30 (JSC::DFG::Node::shouldSpeculateUint32Array): 31 (JSC::DFG::Node::shouldSpeculateFloat32Array): 32 (JSC::DFG::Node::shouldSpeculateFloat64Array): 33 * dfg/DFGPropagator.cpp: 34 (JSC::DFG::Propagator::byValIsPure): 35 * dfg/DFGSpeculativeJIT.cpp: 36 (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): 37 * dfg/DFGSpeculativeJIT32_64.cpp: 38 (JSC::DFG::SpeculativeJIT::compile): 39 * dfg/DFGSpeculativeJIT64.cpp: 40 (JSC::DFG::SpeculativeJIT::compile): 41 1 42 2011-12-22 Gavin Barraclough <[email protected]> 2 43 -
trunk/Source/JavaScriptCore/bytecode/PredictedType.h
r103023 r103604 152 152 } 153 153 154 inline bool isActionableMutableArrayPrediction(PredictedType value) 155 { 156 return isArrayPrediction(value) 157 || isByteArrayPrediction(value) 158 || isInt8ArrayPrediction(value) 159 || isInt16ArrayPrediction(value) 160 || isInt32ArrayPrediction(value) 161 || isUint8ArrayPrediction(value) 162 || isUint16ArrayPrediction(value) 163 || isUint32ArrayPrediction(value) 164 #if CPU(X86) || CPU(X86_64) 165 || isFloat32ArrayPrediction(value) 166 #endif 167 || isFloat64ArrayPrediction(value); 168 } 169 170 inline bool isActionableArrayPrediction(PredictedType value) 171 { 172 return isStringPrediction(value) 173 || isActionableMutableArrayPrediction(value); 174 } 175 154 176 inline bool isArrayOrOtherPrediction(PredictedType value) 155 177 { -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r103594 r103604 403 403 404 404 case GetByVal: { 405 PredictedType indexPrediction = m_graph[node.child2()].prediction(); 406 if (!(indexPrediction & PredictInt32) && indexPrediction) { 405 if (!node.prediction() || !m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction()) { 406 m_isValid = false; 407 break; 408 } 409 if (!isActionableArrayPrediction(m_graph[node.child1()].prediction()) || !m_graph[node.child2()].shouldSpeculateInteger()) { 407 410 clobberStructures(nodeIndex); 408 411 forNode(nodeIndex).makeTop(); … … 470 473 break; 471 474 } 475 ASSERT(m_graph[node.child1()].shouldSpeculateArray()); 472 476 forNode(node.child1()).filter(PredictArray); 473 477 forNode(node.child2()).filter(PredictInt32); … … 478 482 case PutByVal: 479 483 case PutByValAlias: { 480 PredictedType indexPrediction = m_graph[node.child2()].prediction(); 481 if (!(indexPrediction & PredictInt32) && indexPrediction) { 484 if (!m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction()) { 485 m_isValid = false; 486 break; 487 } 488 if (!m_graph[node.child2()].shouldSpeculateInteger() || !isActionableMutableArrayPrediction(m_graph[node.child1()].prediction())) { 489 ASSERT(node.op == PutByVal); 482 490 clobberStructures(nodeIndex); 483 491 forNode(nodeIndex).makeTop(); … … 539 547 break; 540 548 } 541 549 ASSERT(m_graph[node.child1()].shouldSpeculateArray()); 542 550 forNode(node.child1()).filter(PredictArray); 543 551 forNode(node.child2()).filter(PredictInt32); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r103255 r103604 932 932 bool shouldSpeculateInt8Array() 933 933 { 934 return prediction() == PredictInt8Array;934 return isInt8ArrayPrediction(prediction()); 935 935 } 936 936 937 937 bool shouldSpeculateInt16Array() 938 938 { 939 return prediction() == PredictInt16Array;939 return isInt16ArrayPrediction(prediction()); 940 940 } 941 941 942 942 bool shouldSpeculateInt32Array() 943 943 { 944 return prediction() == PredictInt32Array;944 return isInt32ArrayPrediction(prediction()); 945 945 } 946 946 947 947 bool shouldSpeculateUint8Array() 948 948 { 949 return prediction() == PredictUint8Array;949 return isUint8ArrayPrediction(prediction()); 950 950 } 951 951 952 952 bool shouldSpeculateUint16Array() 953 953 { 954 return prediction() == PredictUint16Array;954 return isUint16ArrayPrediction(prediction()); 955 955 } 956 956 957 957 bool shouldSpeculateUint32Array() 958 958 { 959 return prediction() == PredictUint32Array;959 return isUint32ArrayPrediction(prediction()); 960 960 } 961 961 … … 963 963 { 964 964 #if CPU(X86) || CPU(X86_64) 965 return !!(prediction() & PredictFloat32Array);965 return isFloat32ArrayPrediction(prediction()); 966 966 #else 967 967 return false; … … 971 971 bool shouldSpeculateFloat64Array() 972 972 { 973 return prediction() == PredictFloat64Array;973 return isFloat64ArrayPrediction(prediction()); 974 974 } 975 975 -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r103255 r103604 1088 1088 bool byValIsPure(Node& node) 1089 1089 { 1090 PredictedType prediction = m_graph[node.child2()].prediction(); 1091 return (prediction & PredictInt32) || !prediction; 1090 return m_graph[node.child2()].shouldSpeculateInteger() 1091 && ((node.op == PutByVal || node.op == PutByValAlias) 1092 ? isActionableMutableArrayPrediction(m_graph[node.child1()].prediction()) 1093 : isActionableArrayPrediction(m_graph[node.child1()].prediction())); 1092 1094 } 1093 1095 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r103306 r103604 2377 2377 void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node) 2378 2378 { 2379 if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) { 2380 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); 2381 return; 2382 } 2383 2379 2384 SpeculateCellOperand base(this, node.child1()); 2380 2385 GPRReg baseReg = base.gpr(); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r103587 r103604 2206 2206 2207 2207 case GetByVal: { 2208 PredictedType basePrediction = at(node.child2()).prediction(); 2209 if (!(basePrediction & PredictInt32) && basePrediction) { 2208 if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) { 2209 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); 2210 break; 2211 } 2212 2213 if (!at(node.child2()).shouldSpeculateInteger() || !isActionableArrayPrediction(at(node.child1()).prediction())) { 2210 2214 SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right. 2211 2215 JSValueOperand property(this, node.child2()); … … 2292 2296 break; 2293 2297 } 2298 2299 ASSERT(at(node.child1()).shouldSpeculateArray()); 2294 2300 2295 2301 SpeculateStrictInt32Operand property(this, node.child2()); … … 2326 2332 2327 2333 case PutByVal: { 2328 PredictedType basePrediction = at(node.child2()).prediction(); 2329 if (!(basePrediction & PredictInt32) && basePrediction) { 2334 if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { 2335 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); 2336 break; 2337 } 2338 2339 if (!at(node.child2()).shouldSpeculateInteger() || !isActionableMutableArrayPrediction(at(node.child1()).prediction())) { 2330 2340 SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right. 2331 2341 JSValueOperand property(this, node.child2()); … … 2410 2420 break; 2411 2421 } 2422 2423 ASSERT(at(node.child1()).shouldSpeculateArray()); 2412 2424 2413 2425 JSValueOperand value(this, node.child3()); … … 2473 2485 2474 2486 case PutByValAlias: { 2487 if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { 2488 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); 2489 break; 2490 } 2491 2492 ASSERT(isActionableMutableArrayPrediction(at(node.child1()).prediction())); 2493 ASSERT(at(node.child2()).shouldSpeculateInteger()); 2494 2475 2495 SpeculateCellOperand base(this, node.child1()); 2476 2496 SpeculateStrictInt32Operand property(this, node.child2()); … … 2536 2556 break; 2537 2557 } 2558 2559 ASSERT(at(node.child1()).shouldSpeculateArray()); 2538 2560 2539 2561 JSValueOperand value(this, node.child3()); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r103587 r103604 2287 2287 2288 2288 case GetByVal: { 2289 PredictedType basePrediction = at(node.child2()).prediction(); 2290 if (!(basePrediction & PredictInt32) && basePrediction) { 2289 if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) { 2290 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); 2291 break; 2292 } 2293 2294 if (!at(node.child2()).shouldSpeculateInteger() || !isActionableArrayPrediction(at(node.child1()).prediction())) { 2291 2295 JSValueOperand base(this, node.child1()); 2292 2296 JSValueOperand property(this, node.child2()); … … 2371 2375 break; 2372 2376 } 2377 2378 ASSERT(at(node.child1()).shouldSpeculateArray()); 2373 2379 2374 2380 SpeculateCellOperand base(this, node.child1()); … … 2399 2405 2400 2406 case PutByVal: { 2401 PredictedType basePrediction = at(node.child2()).prediction(); 2402 if (!(basePrediction & PredictInt32) && basePrediction) { 2407 if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { 2408 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); 2409 break; 2410 } 2411 2412 if (!at(node.child2()).shouldSpeculateInteger() || !isActionableMutableArrayPrediction(at(node.child1()).prediction())) { 2403 2413 JSValueOperand arg1(this, node.child1()); 2404 2414 JSValueOperand arg2(this, node.child2()); … … 2477 2487 break; 2478 2488 } 2489 2490 ASSERT(at(node.child1()).shouldSpeculateArray()); 2479 2491 2480 2492 JSValueOperand value(this, node.child3()); … … 2538 2550 2539 2551 case PutByValAlias: { 2540 PredictedType basePrediction = at(node.child2()).prediction(); 2541 ASSERT_UNUSED(basePrediction, (basePrediction & PredictInt32) || !basePrediction); 2552 if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { 2553 terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode); 2554 break; 2555 } 2556 2557 ASSERT(isActionableMutableArrayPrediction(at(node.child1()).prediction())); 2558 ASSERT(at(node.child2()).shouldSpeculateInteger()); 2542 2559 2543 2560 SpeculateCellOperand base(this, node.child1()); … … 2603 2620 break; 2604 2621 } 2622 2623 ASSERT(at(node.child1()).shouldSpeculateArray()); 2605 2624 2606 2625 JSValueOperand value(this, node.child3());
Note:
See TracChangeset
for help on using the changeset viewer.