Changeset 182498 in webkit
- Timestamp:
- Apr 7, 2015 3:09:15 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r182495 r182498 1 2015-04-07 Filip Pizlo <fpizlo@apple.com> 2 3 Constant folding of typed array properties should be handled by AI rather than strength reduction 4 https://bugs.webkit.org/show_bug.cgi?id=143496 5 6 Reviewed by Geoffrey Garen. 7 8 Handling constant folding in AI is better because it precludes us from having to fixpoint the CFA 9 phase and whatever other phase did the folding in order to find all constants. 10 11 This also removes the TypedArrayWatchpoint node type because we can just set the watchpoint 12 directly. 13 14 This also fixes a bug in FTL lowering of GetTypedArrayByteOffset. The bug was previously not 15 found because all of the tests for it involved the property getting constant folded. I found that 16 the codegen was bad because an earlier version of the patch broke that constant folding. This 17 adds a new test for that node type, which makes constant folding impossible by allocating a new 18 typed array every type. The lesson here is: if you write a test for something, run the test with 19 full IR dumps to make sure it's actually testing the thing you want it to test. 20 21 * dfg/DFGAbstractInterpreterInlines.h: 22 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 23 * dfg/DFGClobberize.h: 24 (JSC::DFG::clobberize): 25 * dfg/DFGConstantFoldingPhase.cpp: 26 (JSC::DFG::ConstantFoldingPhase::foldConstants): 27 * dfg/DFGDoesGC.cpp: 28 (JSC::DFG::doesGC): 29 * dfg/DFGFixupPhase.cpp: 30 (JSC::DFG::FixupPhase::fixupNode): 31 * dfg/DFGGraph.cpp: 32 (JSC::DFG::Graph::dump): 33 (JSC::DFG::Graph::tryGetFoldableView): 34 (JSC::DFG::Graph::tryGetFoldableViewForChild1): Deleted. 35 * dfg/DFGGraph.h: 36 * dfg/DFGNode.h: 37 (JSC::DFG::Node::hasTypedArray): Deleted. 38 (JSC::DFG::Node::typedArray): Deleted. 39 * dfg/DFGNodeType.h: 40 * dfg/DFGPredictionPropagationPhase.cpp: 41 (JSC::DFG::PredictionPropagationPhase::propagate): 42 * dfg/DFGSafeToExecute.h: 43 (JSC::DFG::safeToExecute): 44 * dfg/DFGSpeculativeJIT.cpp: 45 (JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds): 46 * dfg/DFGSpeculativeJIT32_64.cpp: 47 (JSC::DFG::SpeculativeJIT::compile): 48 * dfg/DFGSpeculativeJIT64.cpp: 49 (JSC::DFG::SpeculativeJIT::compile): 50 * dfg/DFGStrengthReductionPhase.cpp: 51 (JSC::DFG::StrengthReductionPhase::handleNode): 52 (JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant): Deleted. 53 (JSC::DFG::StrengthReductionPhase::prepareToFoldTypedArray): Deleted. 54 * dfg/DFGWatchpointCollectionPhase.cpp: 55 (JSC::DFG::WatchpointCollectionPhase::handle): 56 (JSC::DFG::WatchpointCollectionPhase::addLazily): 57 * ftl/FTLCapabilities.cpp: 58 (JSC::FTL::canCompile): 59 * ftl/FTLLowerDFGToLLVM.cpp: 60 (JSC::FTL::LowerDFGToLLVM::compileNode): 61 (JSC::FTL::LowerDFGToLLVM::compileGetTypedArrayByteOffset): 62 (JSC::FTL::LowerDFGToLLVM::typedArrayLength): 63 * tests/stress/fold-typed-array-properties.js: 64 (foo): 65 * tests/stress/typed-array-byte-offset.js: Added. 66 (foo): 67 1 68 2015-04-07 Matthew Mirman <mmirman@apple.com> 2 69 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r182433 r182498 1384 1384 break; 1385 1385 1386 case TypedArrayWatchpoint:1387 break;1388 1389 1386 case CreateDirectArguments: 1390 1387 forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure()); … … 1521 1518 } 1522 1519 1523 case GetArrayLength: 1520 case GetArrayLength: { 1521 JSArrayBufferView* view = m_graph.tryGetFoldableView( 1522 forNode(node->child1()).m_value, node->arrayMode()); 1523 if (view) { 1524 setConstant(node, jsNumber(view->length())); 1525 break; 1526 } 1524 1527 forNode(node).setType(SpecInt32); 1525 1528 break; 1529 } 1526 1530 1527 1531 case CheckStructure: { … … 1706 1710 break; 1707 1711 } 1708 case GetIndexedPropertyStorage: 1712 case GetIndexedPropertyStorage: { 1713 JSArrayBufferView* view = m_graph.tryGetFoldableView( 1714 forNode(node->child1()).m_value, node->arrayMode()); 1715 if (view) 1716 m_state.setFoundConstants(true); 1717 forNode(node).clear(); 1718 break; 1719 } 1709 1720 case ConstantStoragePointer: { 1710 1721 forNode(node).clear(); … … 1713 1724 1714 1725 case GetTypedArrayByteOffset: { 1726 JSArrayBufferView* view = m_graph.tryGetFoldableView(forNode(node->child1()).m_value); 1727 if (view) { 1728 setConstant(node, jsNumber(view->byteOffset())); 1729 break; 1730 } 1715 1731 forNode(node).setType(SpecInt32); 1716 1732 break; -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r182433 r182498 307 307 return; 308 308 309 case TypedArrayWatchpoint:310 read(Watchpoint_fire);311 write(SideState);312 return;313 314 309 case NotifyWrite: 315 310 write(Watchpoint_fire); -
trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
r182004 r182498 116 116 } 117 117 118 case GetIndexedPropertyStorage: { 119 JSArrayBufferView* view = m_graph.tryGetFoldableView( 120 m_state.forNode(node->child1()).m_value, node->arrayMode()); 121 if (!view) 122 break; 123 124 if (view->mode() == FastTypedArray) { 125 // FIXME: It would be awesome to be able to fold the property storage for 126 // these GC-allocated typed arrays. For now it doesn't matter because the 127 // most common use-cases for constant typed arrays involve large arrays with 128 // aliased buffer views. 129 // https://bugs.webkit.org/show_bug.cgi?id=125425 130 break; 131 } 132 133 m_interpreter.execute(indexInBlock); 134 eliminated = true; 135 136 m_insertionSet.insertNode( 137 indexInBlock, SpecNone, Phantom, node->origin, node->children); 138 node->convertToConstantStoragePointer(view->vector()); 139 break; 140 } 141 118 142 case CheckStructureImmediate: { 119 143 AbstractValue& value = m_state.forNode(node->child1()); -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r182433 r182498 165 165 case InvalidationPoint: 166 166 case NotifyWrite: 167 case TypedArrayWatchpoint:168 167 case CheckInBounds: 169 168 case ConstantStoragePointer: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r182433 r182498 1239 1239 case StoreBarrier: 1240 1240 case StoreBarrierWithNullCheck: 1241 case TypedArrayWatchpoint:1242 1241 case MovHint: 1243 1242 case ZombieHint: -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r182167 r182498 314 314 if (node->hasVariableWatchpointSet()) 315 315 out.print(comma, RawPointer(node->variableWatchpointSet())); 316 if (node->hasTypedArray())317 out.print(comma, inContext(JSValue(node->typedArray()), context));318 316 if (node->hasStoragePointer()) 319 317 out.print(comma, RawPointer(node->storagePointer())); … … 1072 1070 } 1073 1071 1074 JSArrayBufferView* Graph::tryGetFoldableView(Node* node) 1075 { 1076 JSArrayBufferView* view = node->dynamicCastConstant<JSArrayBufferView*>(); 1077 if (!view) 1072 JSArrayBufferView* Graph::tryGetFoldableView(JSValue value) 1073 { 1074 if (!value) 1075 return nullptr; 1076 JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(value); 1077 if (!value) 1078 1078 return nullptr; 1079 1079 if (!view->length()) 1080 1080 return nullptr; 1081 1081 WTF::loadLoadFence(); 1082 watchpoints().addLazily(view); 1082 1083 return view; 1083 1084 } 1084 1085 1085 JSArrayBufferView* Graph::tryGetFoldableView( Node* node, ArrayMode arrayMode)1086 JSArrayBufferView* Graph::tryGetFoldableView(JSValue value, ArrayMode arrayMode) 1086 1087 { 1087 1088 if (arrayMode.typedArrayType() == NotTypedArray) 1088 return 0; 1089 return tryGetFoldableView(node); 1090 } 1091 1092 JSArrayBufferView* Graph::tryGetFoldableViewForChild1(Node* node) 1093 { 1094 return tryGetFoldableView(child(node, 0).node(), node->arrayMode()); 1089 return nullptr; 1090 return tryGetFoldableView(value); 1095 1091 } 1096 1092 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r182167 r182498 693 693 JSValue tryGetConstantClosureVar(Node*, ScopeOffset); 694 694 695 JSArrayBufferView* tryGetFoldableView(Node*); 696 JSArrayBufferView* tryGetFoldableView(Node*, ArrayMode); 697 JSArrayBufferView* tryGetFoldableViewForChild1(Node*); 695 JSArrayBufferView* tryGetFoldableView(JSValue); 696 JSArrayBufferView* tryGetFoldableView(JSValue, ArrayMode arrayMode); 698 697 699 698 void registerFrozenValues(); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r181993 r182498 1230 1230 } 1231 1231 1232 bool hasTypedArray()1233 {1234 return op() == TypedArrayWatchpoint;1235 }1236 1237 JSArrayBufferView* typedArray()1238 {1239 return reinterpret_cast<JSArrayBufferView*>(m_opInfo);1240 }1241 1242 1232 bool hasStoragePointer() 1243 1233 { -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r182433 r182498 175 175 macro(GetIndexedPropertyStorage, NodeResultStorage) \ 176 176 macro(ConstantStoragePointer, NodeResultStorage) \ 177 macro(TypedArrayWatchpoint, NodeMustGenerate) \178 177 macro(GetGetter, NodeResultJS) \ 179 178 macro(GetSetter, NodeResultJS) \ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r182433 r182498 646 646 case LoopHint: 647 647 case NotifyWrite: 648 case TypedArrayWatchpoint:649 648 case ConstantStoragePointer: 650 649 case MovHint: -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r182433 r182498 252 252 case InvalidationPoint: 253 253 case NotifyWrite: 254 case TypedArrayWatchpoint:255 254 case CheckInBounds: 256 255 case ConstantStoragePointer: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r182433 r182498 2269 2269 if (node->op() == PutByValAlias) 2270 2270 return JITCompiler::Jump(); 2271 if (JSArrayBufferView* view = m_jit.graph().tryGetFoldableViewForChild1(node)) { 2271 JSArrayBufferView* view = m_jit.graph().tryGetFoldableView( 2272 m_state.forNode(m_jit.graph().child(node, 0)).m_value, node->arrayMode()); 2273 if (view) { 2272 2274 uint32_t length = view->length(); 2273 2275 Node* indexNode = m_jit.graph().child(node, 1).node(); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r182433 r182498 3534 3534 } 3535 3535 3536 case AllocationProfileWatchpoint: 3537 case TypedArrayWatchpoint: { 3536 case AllocationProfileWatchpoint: { 3538 3537 noResult(node); 3539 3538 break; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r182444 r182498 3609 3609 } 3610 3610 3611 case AllocationProfileWatchpoint: 3612 case TypedArrayWatchpoint: { 3611 case AllocationProfileWatchpoint: { 3613 3612 noResult(node); 3614 3613 break; -
trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
r181993 r182498 147 147 break; 148 148 149 case GetArrayLength:150 if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))151 foldTypedArrayPropertyToConstant(view, jsNumber(view->length()));152 break;153 154 case GetTypedArrayByteOffset:155 if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node->child1().node()))156 foldTypedArrayPropertyToConstant(view, jsNumber(view->byteOffset()));157 break;158 159 case GetIndexedPropertyStorage:160 if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {161 if (view->mode() != FastTypedArray) {162 prepareToFoldTypedArray(view);163 m_node->convertToConstantStoragePointer(view->vector());164 m_changed = true;165 break;166 } else {167 // FIXME: It would be awesome to be able to fold the property storage for168 // these GC-allocated typed arrays. For now it doesn't matter because the169 // most common use-cases for constant typed arrays involve large arrays with170 // aliased buffer views.171 // https://bugs.webkit.org/show_bug.cgi?id=125425172 }173 }174 break;175 176 149 case ValueRep: 177 150 case Int52Rep: … … 284 257 } 285 258 286 void foldTypedArrayPropertyToConstant(JSArrayBufferView* view, JSValue constant)287 {288 prepareToFoldTypedArray(view);289 m_graph.convertToConstant(m_node, constant);290 m_changed = true;291 }292 293 void prepareToFoldTypedArray(JSArrayBufferView* view)294 {295 m_insertionSet.insertNode(296 m_nodeIndex, SpecNone, TypedArrayWatchpoint, m_node->origin,297 OpInfo(view));298 m_insertionSet.insertNode(299 m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->children);300 }301 302 259 void handleCommutativity() 303 260 { -
trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp
r180993 r182498 93 93 if (m_node->arrayMode().type() == Array::String) 94 94 handleStringGetByVal(); 95 96 if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))97 addLazily(view);98 break;99 100 case PutByVal:101 if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))102 addLazily(view);103 95 break; 104 96 … … 120 112 case VarInjectionWatchpoint: 121 113 addLazily(globalObject()->varInjectionWatchpoint()); 122 break;123 124 case TypedArrayWatchpoint:125 addLazily(m_node->typedArray());126 114 break; 127 115 … … 155 143 m_graph.watchpoints().addLazily(set); 156 144 } 157 void addLazily(JSArrayBufferView* view)158 {159 m_graph.watchpoints().addLazily(view);160 }161 145 162 146 JSGlobalObject* globalObject() -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r182433 r182498 120 120 case AllocatePropertyStorage: 121 121 case ReallocatePropertyStorage: 122 case TypedArrayWatchpoint:123 122 case GetTypedArrayByteOffset: 124 123 case NotifyWrite: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r182444 r182498 847 847 case PhantomLocal: 848 848 case LoopHint: 849 case TypedArrayWatchpoint:850 849 case AllocationProfileWatchpoint: 851 850 case MovHint: … … 2106 2105 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("continuation branch")); 2107 2106 2108 LValue baseAddress = m_out.addPtr(basePtr, JSArrayBufferView::offsetOfMode());2107 LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode); 2109 2108 m_out.branch( 2110 m_out.notEqual( baseAddress , m_out.constIntPtr(WastefulTypedArray)),2109 m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)), 2111 2110 unsure(simpleCase), unsure(wastefulCase)); 2112 2111 … … 2126 2125 LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data); 2127 2126 2128 ValueFromBlock wastefulOut = m_out.anchor(m_out.sub( dataPtr, vectorPtr));2127 ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr)); 2129 2128 2130 2129 m_out.jump(continuation); … … 5786 5785 LValue typedArrayLength(Edge baseEdge, ArrayMode arrayMode, LValue base) 5787 5786 { 5788 if (JSArrayBufferView* view = m_graph.tryGetFoldableView(baseEdge.node(), arrayMode)) 5787 JSArrayBufferView* view = m_graph.tryGetFoldableView( 5788 m_state.forNode(baseEdge).m_value, arrayMode); 5789 if (view) 5789 5790 return m_out.constInt32(view->length()); 5790 5791 return m_out.load32NonNegative(base, m_heaps.JSArrayBufferView_length); -
trunk/Source/JavaScriptCore/tests/stress/fold-typed-array-properties.js
r160292 r182498 2 2 3 3 if (a.length != 1) 4 throw "Error: bad length : " + a.length;4 throw "Error: bad length (start): " + a.length; 5 5 if (a.byteOffset != 4) 6 throw "Error: bad offset : " + a.byteOffset;6 throw "Error: bad offset (start): " + a.byteOffset; 7 7 if (a.byteLength != 4) 8 throw "Error: bad byte length : " + a.byteLength;8 throw "Error: bad byte length (start): " + a.byteLength; 9 9 10 function foo() { 11 if (a.length != 1) 12 throw "Error: bad length: " + a.length; 13 if (a.byteOffset != 4) 14 throw "Error: bad offset: " + a.byteOffset; 15 if (a.byteLength != 4) 16 throw "Error: bad byte length: " + a.byteLength; 10 function foo(when) { 11 var tmp = a.length; 12 if (tmp != 1) 13 throw "Error: bad length (" + when + "): " + tmp; 14 tmp = a.byteOffset; 15 if (tmp != 4) 16 throw "Error: bad offset (" + when + "): " + tmp; 17 tmp = a.byteLength; 18 if (tmp != 4) 19 throw "Error: bad byte length (" + when + "): " + tmp; 17 20 } 18 21 19 22 for (var i = 0; i < 1000000; ++i) 20 foo( );23 foo("loop"); 21 24 22 25 transferArrayBuffer(a.buffer); … … 24 27 var didThrow = false; 25 28 try { 26 foo( );29 foo("after transfer"); 27 30 } catch (e) { 28 31 didThrow = true; … … 33 36 34 37 if (a.length != 0) 35 throw "Error: bad length : " + a.length;38 throw "Error: bad length (end): " + a.length; 36 39 if (a.byteOffset != 0) 37 throw "Error: bad offset : " + a.byteOffset;40 throw "Error: bad offset (end): " + a.byteOffset; 38 41 if (a.byteLength != 0) 39 throw "Error: bad byte length : " + a.byteLength;42 throw "Error: bad byte length (end): " + a.byteLength;
Note: See TracChangeset
for help on using the changeset viewer.