OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 | 1372 |
1373 | 1373 |
1374 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1374 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
1375 HValue* elements, | 1375 HValue* elements, |
1376 ElementsKind kind, | 1376 ElementsKind kind, |
1377 HValue* length) { | 1377 HValue* length) { |
1378 Factory* factory = isolate()->factory(); | 1378 Factory* factory = isolate()->factory(); |
1379 | 1379 |
1380 IfBuilder cow_checker(this); | 1380 IfBuilder cow_checker(this); |
1381 | 1381 |
1382 cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map()); | 1382 cow_checker.If<HCompareMap>( |
| 1383 elements, factory->fixed_cow_array_map(), top_info()); |
1383 cow_checker.Then(); | 1384 cow_checker.Then(); |
1384 | 1385 |
1385 HValue* capacity = AddLoadFixedArrayLength(elements); | 1386 HValue* capacity = AddLoadFixedArrayLength(elements); |
1386 | 1387 |
1387 HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, | 1388 HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, |
1388 kind, length, capacity); | 1389 kind, length, capacity); |
1389 | 1390 |
1390 environment()->Push(new_elements); | 1391 environment()->Push(new_elements); |
1391 | 1392 |
1392 cow_checker.Else(); | 1393 cow_checker.Else(); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 if_objectiskey.JoinContinuation(&found); | 1690 if_objectiskey.JoinContinuation(&found); |
1690 } | 1691 } |
1691 if_objectissmi.Else(); | 1692 if_objectissmi.Else(); |
1692 { | 1693 { |
1693 if (type->Is(Type::Smi())) { | 1694 if (type->Is(Type::Smi())) { |
1694 if_objectissmi.Deopt("Expected smi"); | 1695 if_objectissmi.Deopt("Expected smi"); |
1695 } else { | 1696 } else { |
1696 // Check if the object is a heap number. | 1697 // Check if the object is a heap number. |
1697 IfBuilder if_objectisnumber(this); | 1698 IfBuilder if_objectisnumber(this); |
1698 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( | 1699 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( |
1699 object, isolate()->factory()->heap_number_map()); | 1700 object, isolate()->factory()->heap_number_map(), top_info()); |
1700 if_objectisnumber.Then(); | 1701 if_objectisnumber.Then(); |
1701 { | 1702 { |
1702 // Compute hash for heap number similar to double_get_hash(). | 1703 // Compute hash for heap number similar to double_get_hash(). |
1703 HValue* low = Add<HLoadNamedField>( | 1704 HValue* low = Add<HLoadNamedField>( |
1704 object, objectisnumber, | 1705 object, objectisnumber, |
1705 HObjectAccess::ForHeapNumberValueLowestBits()); | 1706 HObjectAccess::ForHeapNumberValueLowestBits()); |
1706 HValue* high = Add<HLoadNamedField>( | 1707 HValue* high = Add<HLoadNamedField>( |
1707 object, objectisnumber, | 1708 object, objectisnumber, |
1708 HObjectAccess::ForHeapNumberValueHighestBits()); | 1709 HObjectAccess::ForHeapNumberValueHighestBits()); |
1709 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); | 1710 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); |
(...skipping 3923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5633 } | 5634 } |
5634 } | 5635 } |
5635 ++count; | 5636 ++count; |
5636 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 5637 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
5637 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 5638 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
5638 HUnaryControlInstruction* compare; | 5639 HUnaryControlInstruction* compare; |
5639 | 5640 |
5640 HValue* dependency; | 5641 HValue* dependency; |
5641 if (info.type()->Is(Type::Number())) { | 5642 if (info.type()->Is(Type::Number())) { |
5642 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); | 5643 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); |
5643 compare = New<HCompareMap>(object, heap_number_map, if_true, if_false); | 5644 compare = New<HCompareMap>(object, heap_number_map, top_info(), |
| 5645 if_true, if_false); |
5644 dependency = smi_check; | 5646 dependency = smi_check; |
5645 } else if (info.type()->Is(Type::String())) { | 5647 } else if (info.type()->Is(Type::String())) { |
5646 compare = New<HIsStringAndBranch>(object, if_true, if_false); | 5648 compare = New<HIsStringAndBranch>(object, if_true, if_false); |
5647 dependency = compare; | 5649 dependency = compare; |
5648 } else { | 5650 } else { |
5649 compare = New<HCompareMap>(object, info.map(), if_true, if_false); | 5651 compare = New<HCompareMap>(object, info.map(), top_info(), |
| 5652 if_true, if_false); |
5650 dependency = compare; | 5653 dependency = compare; |
5651 } | 5654 } |
5652 FinishCurrentBlock(compare); | 5655 FinishCurrentBlock(compare); |
5653 | 5656 |
5654 if (info.type()->Is(Type::Number())) { | 5657 if (info.type()->Is(Type::Number())) { |
5655 Goto(if_true, number_block); | 5658 Goto(if_true, number_block); |
5656 if_true = number_block; | 5659 if_true = number_block; |
5657 number_block->SetJoinId(ast_id); | 5660 number_block->SetJoinId(ast_id); |
5658 } | 5661 } |
5659 | 5662 |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6279 // Remember the most general elements kind, the code for its load will | 6282 // Remember the most general elements kind, the code for its load will |
6280 // properly handle all of the more specific cases. | 6283 // properly handle all of the more specific cases. |
6281 if ((i == 0) || IsMoreGeneralElementsKindTransition( | 6284 if ((i == 0) || IsMoreGeneralElementsKindTransition( |
6282 most_general_consolidated_map->elements_kind(), | 6285 most_general_consolidated_map->elements_kind(), |
6283 map->elements_kind())) { | 6286 map->elements_kind())) { |
6284 most_general_consolidated_map = map; | 6287 most_general_consolidated_map = map; |
6285 } | 6288 } |
6286 } | 6289 } |
6287 if (!has_double_maps && !has_smi_or_object_maps) return NULL; | 6290 if (!has_double_maps && !has_smi_or_object_maps) return NULL; |
6288 | 6291 |
6289 HCheckMaps* checked_object = Add<HCheckMaps>(object, maps); | 6292 HCheckMaps* checked_object = Add<HCheckMaps>(object, maps, top_info()); |
6290 // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. | 6293 // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. |
6291 // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. | 6294 // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. |
6292 ElementsKind consolidated_elements_kind = has_seen_holey_elements | 6295 ElementsKind consolidated_elements_kind = has_seen_holey_elements |
6293 ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) | 6296 ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) |
6294 : most_general_consolidated_map->elements_kind(); | 6297 : most_general_consolidated_map->elements_kind(); |
6295 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( | 6298 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
6296 checked_object, key, val, | 6299 checked_object, key, val, |
6297 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, | 6300 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
6298 consolidated_elements_kind, | 6301 consolidated_elements_kind, |
6299 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); | 6302 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6377 | 6380 |
6378 HBasicBlock* join = graph()->CreateBasicBlock(); | 6381 HBasicBlock* join = graph()->CreateBasicBlock(); |
6379 | 6382 |
6380 for (int i = 0; i < untransitionable_maps.length(); ++i) { | 6383 for (int i = 0; i < untransitionable_maps.length(); ++i) { |
6381 Handle<Map> map = untransitionable_maps[i]; | 6384 Handle<Map> map = untransitionable_maps[i]; |
6382 if (!map->IsJSObjectMap()) continue; | 6385 if (!map->IsJSObjectMap()) continue; |
6383 ElementsKind elements_kind = map->elements_kind(); | 6386 ElementsKind elements_kind = map->elements_kind(); |
6384 HBasicBlock* this_map = graph()->CreateBasicBlock(); | 6387 HBasicBlock* this_map = graph()->CreateBasicBlock(); |
6385 HBasicBlock* other_map = graph()->CreateBasicBlock(); | 6388 HBasicBlock* other_map = graph()->CreateBasicBlock(); |
6386 HCompareMap* mapcompare = | 6389 HCompareMap* mapcompare = |
6387 New<HCompareMap>(object, map, this_map, other_map); | 6390 New<HCompareMap>(object, map, top_info(), this_map, other_map); |
6388 FinishCurrentBlock(mapcompare); | 6391 FinishCurrentBlock(mapcompare); |
6389 | 6392 |
6390 set_current_block(this_map); | 6393 set_current_block(this_map); |
6391 HInstruction* access = NULL; | 6394 HInstruction* access = NULL; |
6392 if (IsDictionaryElementsKind(elements_kind)) { | 6395 if (IsDictionaryElementsKind(elements_kind)) { |
6393 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); | 6396 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); |
6394 } else { | 6397 } else { |
6395 ASSERT(IsFastElementsKind(elements_kind) || | 6398 ASSERT(IsFastElementsKind(elements_kind) || |
6396 IsExternalArrayElementsKind(elements_kind)); | 6399 IsExternalArrayElementsKind(elements_kind)); |
6397 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); | 6400 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6585 } | 6588 } |
6586 | 6589 |
6587 HValue* checked_object; | 6590 HValue* checked_object; |
6588 // Type::Number() is only supported by polymorphic load/call handling. | 6591 // Type::Number() is only supported by polymorphic load/call handling. |
6589 ASSERT(!info.type()->Is(Type::Number())); | 6592 ASSERT(!info.type()->Is(Type::Number())); |
6590 BuildCheckHeapObject(object); | 6593 BuildCheckHeapObject(object); |
6591 if (AreStringTypes(types)) { | 6594 if (AreStringTypes(types)) { |
6592 checked_object = | 6595 checked_object = |
6593 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); | 6596 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); |
6594 } else { | 6597 } else { |
6595 checked_object = Add<HCheckMaps>(object, types); | 6598 checked_object = Add<HCheckMaps>(object, types, top_info()); |
6596 } | 6599 } |
6597 return BuildMonomorphicAccess( | 6600 return BuildMonomorphicAccess( |
6598 &info, object, checked_object, value, ast_id, return_id); | 6601 &info, object, checked_object, value, ast_id, return_id); |
6599 } | 6602 } |
6600 | 6603 |
6601 return BuildNamedGeneric(access, object, name, value, is_uninitialized); | 6604 return BuildNamedGeneric(access, object, name, value, is_uninitialized); |
6602 } | 6605 } |
6603 | 6606 |
6604 | 6607 |
6605 void HOptimizedGraphBuilder::PushLoad(Property* expr, | 6608 void HOptimizedGraphBuilder::PushLoad(Property* expr, |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6837 } | 6840 } |
6838 } | 6841 } |
6839 ++count; | 6842 ++count; |
6840 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 6843 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
6841 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 6844 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
6842 HUnaryControlInstruction* compare; | 6845 HUnaryControlInstruction* compare; |
6843 | 6846 |
6844 Handle<Map> map = info.map(); | 6847 Handle<Map> map = info.map(); |
6845 if (info.type()->Is(Type::Number())) { | 6848 if (info.type()->Is(Type::Number())) { |
6846 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); | 6849 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); |
6847 compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false); | 6850 compare = New<HCompareMap>(receiver, heap_number_map, top_info(), |
| 6851 if_true, if_false); |
6848 } else if (info.type()->Is(Type::String())) { | 6852 } else if (info.type()->Is(Type::String())) { |
6849 compare = New<HIsStringAndBranch>(receiver, if_true, if_false); | 6853 compare = New<HIsStringAndBranch>(receiver, if_true, if_false); |
6850 } else { | 6854 } else { |
6851 compare = New<HCompareMap>(receiver, map, if_true, if_false); | 6855 compare = New<HCompareMap>(receiver, map, top_info(), |
| 6856 if_true, if_false); |
6852 } | 6857 } |
6853 FinishCurrentBlock(compare); | 6858 FinishCurrentBlock(compare); |
6854 | 6859 |
6855 if (info.type()->Is(Type::Number())) { | 6860 if (info.type()->Is(Type::Number())) { |
6856 Goto(if_true, number_block); | 6861 Goto(if_true, number_block); |
6857 if_true = number_block; | 6862 if_true = number_block; |
6858 number_block->SetJoinId(expr->id()); | 6863 number_block->SetJoinId(expr->id()); |
6859 } | 6864 } |
6860 | 6865 |
6861 set_current_block(if_true); | 6866 set_current_block(if_true); |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7686 PrintF("Inlining api function "); | 7691 PrintF("Inlining api function "); |
7687 function->ShortPrint(); | 7692 function->ShortPrint(); |
7688 PrintF("\n"); | 7693 PrintF("\n"); |
7689 } | 7694 } |
7690 | 7695 |
7691 bool drop_extra = false; | 7696 bool drop_extra = false; |
7692 switch (call_type) { | 7697 switch (call_type) { |
7693 case kCallApiFunction: | 7698 case kCallApiFunction: |
7694 case kCallApiMethod: | 7699 case kCallApiMethod: |
7695 // Need to check that none of the receiver maps could have changed. | 7700 // Need to check that none of the receiver maps could have changed. |
7696 Add<HCheckMaps>(receiver, receiver_maps); | 7701 Add<HCheckMaps>(receiver, receiver_maps, top_info()); |
7697 // Need to ensure the chain between receiver and api_holder is intact. | 7702 // Need to ensure the chain between receiver and api_holder is intact. |
7698 if (holder_lookup == CallOptimization::kHolderFound) { | 7703 if (holder_lookup == CallOptimization::kHolderFound) { |
7699 AddCheckPrototypeMaps(api_holder, receiver_maps->first()); | 7704 AddCheckPrototypeMaps(api_holder, receiver_maps->first()); |
7700 } else { | 7705 } else { |
7701 ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); | 7706 ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); |
7702 } | 7707 } |
7703 // Includes receiver. | 7708 // Includes receiver. |
7704 PushArgumentsFromEnvironment(argc + 1); | 7709 PushArgumentsFromEnvironment(argc + 1); |
7705 // Drop function after call. | 7710 // Drop function after call. |
7706 drop_extra = true; | 7711 drop_extra = true; |
(...skipping 3462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11169 if (ShouldProduceTraceOutput()) { | 11174 if (ShouldProduceTraceOutput()) { |
11170 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11175 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11171 } | 11176 } |
11172 | 11177 |
11173 #ifdef DEBUG | 11178 #ifdef DEBUG |
11174 graph_->Verify(false); // No full verify. | 11179 graph_->Verify(false); // No full verify. |
11175 #endif | 11180 #endif |
11176 } | 11181 } |
11177 | 11182 |
11178 } } // namespace v8::internal | 11183 } } // namespace v8::internal |
OLD | NEW |