Changeset 172176 in webkit for trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
- Timestamp:
- Aug 6, 2014, 2:32:55 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r172149 r172176 401 401 case Phantom: 402 402 case HardPhantom: 403 case Check: 403 404 compilePhantom(); 404 405 break; … … 699 700 compileStoreBarrierWithNullCheck(); 700 701 break; 702 case HasIndexedProperty: 703 compileHasIndexedProperty(); 704 break; 705 case HasGenericProperty: 706 compileHasGenericProperty(); 707 break; 708 case HasStructureProperty: 709 compileHasStructureProperty(); 710 break; 711 case GetDirectPname: 712 compileGetDirectPname(); 713 break; 714 case GetEnumerableLength: 715 compileGetEnumerableLength(); 716 break; 717 case GetStructurePropertyEnumerator: 718 compileGetStructurePropertyEnumerator(); 719 break; 720 case GetGenericPropertyEnumerator: 721 compileGetGenericPropertyEnumerator(); 722 break; 723 case GetEnumeratorPname: 724 compileGetEnumeratorPname(); 725 break; 726 case ToIndexString: 727 compileToIndexString(); 728 break; 729 701 730 case PhantomLocal: 702 731 case SetArgument: … … 1727 1756 { 1728 1757 LValue cell = lowCell(m_node->child1()); 1758 1759 speculateFunction(m_node->child1(), cell); 1729 1760 1730 1761 speculate( … … 4103 4134 } 4104 4135 4136 void compileHasIndexedProperty() 4137 { 4138 switch (m_node->arrayMode().type()) { 4139 case Array::Int32: 4140 case Array::Contiguous: { 4141 LValue base = lowCell(m_node->child1()); 4142 LValue index = lowInt32(m_node->child2()); 4143 LValue storage = lowStorage(m_node->child3()); 4144 4145 IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ? 4146 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties; 4147 4148 LBasicBlock checkHole = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty int/contiguous check hole")); 4149 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty int/contiguous slow case")); 4150 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty int/contiguous continuation")); 4151 4152 if (!m_node->arrayMode().isInBounds()) { 4153 m_out.branch( 4154 m_out.aboveOrEqual( 4155 index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)), 4156 rarely(slowCase), usually(checkHole)); 4157 } else 4158 m_out.jump(checkHole); 4159 4160 LBasicBlock lastNext = m_out.appendTo(checkHole, slowCase); 4161 ValueFromBlock checkHoleResult = m_out.anchor( 4162 m_out.notZero64(m_out.load64(baseIndex(heap, storage, index, m_node->child2())))); 4163 m_out.branch(checkHoleResult.value(), usually(continuation), rarely(slowCase)); 4164 4165 m_out.appendTo(slowCase, continuation); 4166 ValueFromBlock slowResult = m_out.anchor(m_out.equal( 4167 m_out.constInt64(JSValue::encode(jsBoolean(true))), 4168 vmCall(m_out.operation(operationHasIndexedProperty), m_callFrame, base, index))); 4169 m_out.jump(continuation); 4170 4171 m_out.appendTo(continuation, lastNext); 4172 setBoolean(m_out.phi(m_out.boolean, checkHoleResult, slowResult)); 4173 return; 4174 } 4175 case Array::Double: { 4176 LValue base = lowCell(m_node->child1()); 4177 LValue index = lowInt32(m_node->child2()); 4178 LValue storage = lowStorage(m_node->child3()); 4179 4180 IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties; 4181 4182 LBasicBlock checkHole = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty double check hole")); 4183 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty double slow case")); 4184 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty double continuation")); 4185 4186 if (!m_node->arrayMode().isInBounds()) { 4187 m_out.branch( 4188 m_out.aboveOrEqual( 4189 index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)), 4190 rarely(slowCase), usually(checkHole)); 4191 } else 4192 m_out.jump(checkHole); 4193 4194 LBasicBlock lastNext = m_out.appendTo(checkHole, slowCase); 4195 LValue doubleValue = m_out.loadDouble(baseIndex(heap, storage, index, m_node->child2())); 4196 ValueFromBlock checkHoleResult = m_out.anchor( 4197 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue)); 4198 m_out.branch(checkHoleResult.value(), rarely(slowCase), usually(continuation)); 4199 4200 m_out.appendTo(slowCase, continuation); 4201 ValueFromBlock slowResult = m_out.anchor(m_out.equal( 4202 m_out.constInt64(JSValue::encode(jsBoolean(true))), 4203 vmCall(m_out.operation(operationHasIndexedProperty), m_callFrame, base, index))); 4204 m_out.jump(continuation); 4205 4206 m_out.appendTo(continuation, lastNext); 4207 setBoolean(m_out.phi(m_out.boolean, checkHoleResult, slowResult)); 4208 return; 4209 } 4210 4211 default: 4212 RELEASE_ASSERT_NOT_REACHED(); 4213 return; 4214 } 4215 } 4216 4217 void compileHasGenericProperty() 4218 { 4219 LValue base = lowJSValue(m_node->child1()); 4220 LValue property = lowCell(m_node->child2()); 4221 setJSValue(vmCall(m_out.operation(operationHasGenericProperty), m_callFrame, base, property)); 4222 } 4223 4224 void compileHasStructureProperty() 4225 { 4226 LValue base = lowJSValue(m_node->child1()); 4227 LValue property = lowString(m_node->child2()); 4228 LValue enumerator = lowCell(m_node->child3()); 4229 4230 LBasicBlock correctStructure = FTL_NEW_BLOCK(m_out, ("HasStructureProperty correct structure")); 4231 LBasicBlock wrongStructure = FTL_NEW_BLOCK(m_out, ("HasStructureProperty wrong structure")); 4232 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("HasStructureProperty continuation")); 4233 4234 m_out.branch(m_out.notEqual( 4235 m_out.load32(base, m_heaps.JSCell_structureID), 4236 m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedStructureID)), 4237 rarely(wrongStructure), usually(correctStructure)); 4238 4239 LBasicBlock lastNext = m_out.appendTo(correctStructure, wrongStructure); 4240 ValueFromBlock correctStructureResult = m_out.anchor(m_out.booleanTrue); 4241 m_out.jump(continuation); 4242 4243 m_out.appendTo(wrongStructure, continuation); 4244 ValueFromBlock wrongStructureResult = m_out.anchor( 4245 m_out.equal( 4246 m_out.constInt64(JSValue::encode(jsBoolean(true))), 4247 vmCall(m_out.operation(operationHasGenericProperty), m_callFrame, base, property))); 4248 m_out.jump(continuation); 4249 4250 m_out.appendTo(continuation, lastNext); 4251 setBoolean(m_out.phi(m_out.boolean, correctStructureResult, wrongStructureResult)); 4252 } 4253 4254 void compileGetDirectPname() 4255 { 4256 LValue base = lowCell(m_graph.varArgChild(m_node, 0)); 4257 LValue property = lowCell(m_graph.varArgChild(m_node, 1)); 4258 LValue index = lowInt32(m_graph.varArgChild(m_node, 2)); 4259 LValue enumerator = lowCell(m_graph.varArgChild(m_node, 3)); 4260 4261 LBasicBlock checkOffset = FTL_NEW_BLOCK(m_out, ("GetDirectPname check offset")); 4262 LBasicBlock inlineLoad = FTL_NEW_BLOCK(m_out, ("GetDirectPname inline load")); 4263 LBasicBlock outOfLineLoad = FTL_NEW_BLOCK(m_out, ("GetDirectPname out-of-line load")); 4264 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetDirectPname slow case")); 4265 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetDirectPname continuation")); 4266 4267 m_out.branch(m_out.notEqual( 4268 m_out.load32(base, m_heaps.JSCell_structureID), 4269 m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedStructureID)), 4270 rarely(slowCase), usually(checkOffset)); 4271 4272 LBasicBlock lastNext = m_out.appendTo(checkOffset, inlineLoad); 4273 m_out.branch(m_out.aboveOrEqual(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedInlineCapacity)), 4274 unsure(outOfLineLoad), unsure(inlineLoad)); 4275 4276 m_out.appendTo(inlineLoad, outOfLineLoad); 4277 ValueFromBlock inlineResult = m_out.anchor( 4278 m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), 4279 base, m_out.zeroExt(index, m_out.int64), ScaleEight, JSObject::offsetOfInlineStorage()))); 4280 m_out.jump(continuation); 4281 4282 m_out.appendTo(outOfLineLoad, slowCase); 4283 LValue storage = m_out.loadPtr(base, m_heaps.JSObject_butterfly); 4284 LValue realIndex = m_out.signExt( 4285 m_out.neg(m_out.sub(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedInlineCapacity))), 4286 m_out.int64); 4287 int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue); 4288 ValueFromBlock outOfLineResult = m_out.anchor( 4289 m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), storage, realIndex, ScaleEight, offsetOfFirstProperty))); 4290 m_out.jump(continuation); 4291 4292 m_out.appendTo(slowCase, continuation); 4293 ValueFromBlock slowCaseResult = m_out.anchor( 4294 vmCall(m_out.operation(operationGetByVal), m_callFrame, base, property)); 4295 m_out.jump(continuation); 4296 4297 m_out.appendTo(continuation, lastNext); 4298 setJSValue(m_out.phi(m_out.int64, inlineResult, outOfLineResult, slowCaseResult)); 4299 } 4300 4301 void compileGetEnumerableLength() 4302 { 4303 LValue base = lowCell(m_node->child1()); 4304 setInt32(vmCall(m_out.operation(operationGetEnumerableLength), m_callFrame, base)); 4305 } 4306 4307 void compileGetStructurePropertyEnumerator() 4308 { 4309 LValue base = lowCell(m_node->child1()); 4310 LValue length = lowInt32(m_node->child2()); 4311 setJSValue(vmCall(m_out.operation(operationGetStructurePropertyEnumerator), m_callFrame, base, length)); 4312 } 4313 4314 void compileGetGenericPropertyEnumerator() 4315 { 4316 LValue base = lowCell(m_node->child1()); 4317 LValue length = lowInt32(m_node->child2()); 4318 LValue enumerator = lowCell(m_node->child3()); 4319 setJSValue(vmCall(m_out.operation(operationGetGenericPropertyEnumerator), m_callFrame, base, length, enumerator)); 4320 } 4321 4322 void compileGetEnumeratorPname() 4323 { 4324 LValue enumerator = lowCell(m_node->child1()); 4325 LValue index = lowInt32(m_node->child2()); 4326 4327 LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorPname in bounds")); 4328 LBasicBlock outOfBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorPname out of bounds")); 4329 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetEnumeratorPname continuation")); 4330 4331 m_out.branch(m_out.below(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesLength)), 4332 usually(inBounds), rarely(outOfBounds)); 4333 4334 LBasicBlock lastNext = m_out.appendTo(inBounds, outOfBounds); 4335 LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector); 4336 ValueFromBlock inBoundsResult = m_out.anchor( 4337 m_out.load64(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector, 4338 storage, m_out.signExt(index, m_out.int64), ScaleEight))); 4339 m_out.jump(continuation); 4340 4341 m_out.appendTo(outOfBounds, continuation); 4342 ValueFromBlock outOfBoundsResult = m_out.anchor(m_out.constInt64(ValueNull)); 4343 m_out.jump(continuation); 4344 4345 m_out.appendTo(continuation, lastNext); 4346 setJSValue(m_out.phi(m_out.int64, inBoundsResult, outOfBoundsResult)); 4347 } 4348 4349 void compileToIndexString() 4350 { 4351 LValue index = lowInt32(m_node->child1()); 4352 setJSValue(vmCall(m_out.operation(operationToIndexString), m_callFrame, index)); 4353 } 4354 4105 4355 #if ENABLE(FTL_NATIVE_CALL_INLINING) 4106 4356 LValue getFunctionBySymbol(const CString symbol) … … 5266 5516 LValue lowJSValue(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) 5267 5517 { 5268 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);5518 DFG_ASSERT(m_graph, m_node, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse); 5269 5519 DFG_ASSERT(m_graph, m_node, !isDouble(edge.useKind())); 5270 5520 DFG_ASSERT(m_graph, m_node, edge.useKind() != Int52RepUse); … … 5560 5810 speculateObject(edge); 5561 5811 break; 5812 case FunctionUse: 5813 speculateFunction(edge); 5814 break; 5562 5815 case ObjectOrOtherUse: 5563 5816 speculateObjectOrOther(edge); … … 5694 5947 } 5695 5948 5949 LValue isFunction(LValue cell) { return isType(cell, JSFunctionType); } 5950 LValue isNotFunction(LValue cell) { return isNotType(cell, JSFunctionType); } 5951 5696 5952 LValue isType(LValue cell, JSType type) 5697 5953 { … … 5716 5972 } 5717 5973 5974 void speculateFunction(Edge edge, LValue cell) 5975 { 5976 FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecFunction, isNotFunction(cell)); 5977 } 5978 5979 void speculateFunction(Edge edge) 5980 { 5981 speculateFunction(edge, lowCell(edge)); 5982 } 5983 5718 5984 void speculateObjectOrOther(Edge edge) 5719 5985 { … … 5721 5987 return; 5722 5988 5723 LValue value = lowJSValue(edge );5989 LValue value = lowJSValue(edge, ManualOperandSpeculation); 5724 5990 5725 5991 LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("speculateObjectOrOther cell case"));
Note:
See TracChangeset
for help on using the changeset viewer.