| 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 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 | 1357 |
| 1358 | 1358 |
| 1359 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1359 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
| 1360 HValue* elements, | 1360 HValue* elements, |
| 1361 ElementsKind kind, | 1361 ElementsKind kind, |
| 1362 HValue* length) { | 1362 HValue* length) { |
| 1363 Factory* factory = isolate()->factory(); | 1363 Factory* factory = isolate()->factory(); |
| 1364 | 1364 |
| 1365 IfBuilder cow_checker(this); | 1365 IfBuilder cow_checker(this); |
| 1366 | 1366 |
| 1367 cow_checker.If<HCompareMap>( | 1367 cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map()); |
| 1368 elements, factory->fixed_cow_array_map(), top_info()); | |
| 1369 cow_checker.Then(); | 1368 cow_checker.Then(); |
| 1370 | 1369 |
| 1371 HValue* capacity = AddLoadFixedArrayLength(elements); | 1370 HValue* capacity = AddLoadFixedArrayLength(elements); |
| 1372 | 1371 |
| 1373 HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, | 1372 HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, |
| 1374 kind, length, capacity); | 1373 kind, length, capacity); |
| 1375 | 1374 |
| 1376 environment()->Push(new_elements); | 1375 environment()->Push(new_elements); |
| 1377 | 1376 |
| 1378 cow_checker.Else(); | 1377 cow_checker.Else(); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1675 if_objectiskey.JoinContinuation(&found); | 1674 if_objectiskey.JoinContinuation(&found); |
| 1676 } | 1675 } |
| 1677 if_objectissmi.Else(); | 1676 if_objectissmi.Else(); |
| 1678 { | 1677 { |
| 1679 if (type->Is(Type::Smi())) { | 1678 if (type->Is(Type::Smi())) { |
| 1680 if_objectissmi.Deopt("Expected smi"); | 1679 if_objectissmi.Deopt("Expected smi"); |
| 1681 } else { | 1680 } else { |
| 1682 // Check if the object is a heap number. | 1681 // Check if the object is a heap number. |
| 1683 IfBuilder if_objectisnumber(this); | 1682 IfBuilder if_objectisnumber(this); |
| 1684 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( | 1683 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( |
| 1685 object, isolate()->factory()->heap_number_map(), top_info()); | 1684 object, isolate()->factory()->heap_number_map()); |
| 1686 if_objectisnumber.Then(); | 1685 if_objectisnumber.Then(); |
| 1687 { | 1686 { |
| 1688 // Compute hash for heap number similar to double_get_hash(). | 1687 // Compute hash for heap number similar to double_get_hash(). |
| 1689 HValue* low = Add<HLoadNamedField>( | 1688 HValue* low = Add<HLoadNamedField>( |
| 1690 object, objectisnumber, | 1689 object, objectisnumber, |
| 1691 HObjectAccess::ForHeapNumberValueLowestBits()); | 1690 HObjectAccess::ForHeapNumberValueLowestBits()); |
| 1692 HValue* high = Add<HLoadNamedField>( | 1691 HValue* high = Add<HLoadNamedField>( |
| 1693 object, objectisnumber, | 1692 object, objectisnumber, |
| 1694 HObjectAccess::ForHeapNumberValueHighestBits()); | 1693 HObjectAccess::ForHeapNumberValueHighestBits()); |
| 1695 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); | 1694 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); |
| (...skipping 4042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5738 } | 5737 } |
| 5739 } | 5738 } |
| 5740 ++count; | 5739 ++count; |
| 5741 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 5740 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 5742 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 5741 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 5743 HUnaryControlInstruction* compare; | 5742 HUnaryControlInstruction* compare; |
| 5744 | 5743 |
| 5745 HValue* dependency; | 5744 HValue* dependency; |
| 5746 if (info.type()->Is(Type::Number())) { | 5745 if (info.type()->Is(Type::Number())) { |
| 5747 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); | 5746 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); |
| 5748 compare = New<HCompareMap>(object, heap_number_map, top_info(), | 5747 compare = New<HCompareMap>(object, heap_number_map, if_true, if_false); |
| 5749 if_true, if_false); | |
| 5750 dependency = smi_check; | 5748 dependency = smi_check; |
| 5751 } else if (info.type()->Is(Type::String())) { | 5749 } else if (info.type()->Is(Type::String())) { |
| 5752 compare = New<HIsStringAndBranch>(object, if_true, if_false); | 5750 compare = New<HIsStringAndBranch>(object, if_true, if_false); |
| 5753 dependency = compare; | 5751 dependency = compare; |
| 5754 } else { | 5752 } else { |
| 5755 compare = New<HCompareMap>(object, info.map(), top_info(), | 5753 compare = New<HCompareMap>(object, info.map(), if_true, if_false); |
| 5756 if_true, if_false); | |
| 5757 dependency = compare; | 5754 dependency = compare; |
| 5758 } | 5755 } |
| 5759 FinishCurrentBlock(compare); | 5756 FinishCurrentBlock(compare); |
| 5760 | 5757 |
| 5761 if (info.type()->Is(Type::Number())) { | 5758 if (info.type()->Is(Type::Number())) { |
| 5762 GotoNoSimulate(if_true, number_block); | 5759 GotoNoSimulate(if_true, number_block); |
| 5763 if_true = number_block; | 5760 if_true = number_block; |
| 5764 } | 5761 } |
| 5765 | 5762 |
| 5766 set_current_block(if_true); | 5763 set_current_block(if_true); |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6364 // Remember the most general elements kind, the code for its load will | 6361 // Remember the most general elements kind, the code for its load will |
| 6365 // properly handle all of the more specific cases. | 6362 // properly handle all of the more specific cases. |
| 6366 if ((i == 0) || IsMoreGeneralElementsKindTransition( | 6363 if ((i == 0) || IsMoreGeneralElementsKindTransition( |
| 6367 most_general_consolidated_map->elements_kind(), | 6364 most_general_consolidated_map->elements_kind(), |
| 6368 map->elements_kind())) { | 6365 map->elements_kind())) { |
| 6369 most_general_consolidated_map = map; | 6366 most_general_consolidated_map = map; |
| 6370 } | 6367 } |
| 6371 } | 6368 } |
| 6372 if (!has_double_maps && !has_smi_or_object_maps) return NULL; | 6369 if (!has_double_maps && !has_smi_or_object_maps) return NULL; |
| 6373 | 6370 |
| 6374 HCheckMaps* checked_object = Add<HCheckMaps>(object, maps, top_info()); | 6371 HCheckMaps* checked_object = Add<HCheckMaps>(object, maps); |
| 6375 // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. | 6372 // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. |
| 6376 // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. | 6373 // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. |
| 6377 ElementsKind consolidated_elements_kind = has_seen_holey_elements | 6374 ElementsKind consolidated_elements_kind = has_seen_holey_elements |
| 6378 ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) | 6375 ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) |
| 6379 : most_general_consolidated_map->elements_kind(); | 6376 : most_general_consolidated_map->elements_kind(); |
| 6380 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( | 6377 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
| 6381 checked_object, key, val, | 6378 checked_object, key, val, |
| 6382 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, | 6379 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
| 6383 consolidated_elements_kind, | 6380 consolidated_elements_kind, |
| 6384 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); | 6381 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6462 | 6459 |
| 6463 HBasicBlock* join = graph()->CreateBasicBlock(); | 6460 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 6464 | 6461 |
| 6465 for (int i = 0; i < untransitionable_maps.length(); ++i) { | 6462 for (int i = 0; i < untransitionable_maps.length(); ++i) { |
| 6466 Handle<Map> map = untransitionable_maps[i]; | 6463 Handle<Map> map = untransitionable_maps[i]; |
| 6467 if (!map->IsJSObjectMap()) continue; | 6464 if (!map->IsJSObjectMap()) continue; |
| 6468 ElementsKind elements_kind = map->elements_kind(); | 6465 ElementsKind elements_kind = map->elements_kind(); |
| 6469 HBasicBlock* this_map = graph()->CreateBasicBlock(); | 6466 HBasicBlock* this_map = graph()->CreateBasicBlock(); |
| 6470 HBasicBlock* other_map = graph()->CreateBasicBlock(); | 6467 HBasicBlock* other_map = graph()->CreateBasicBlock(); |
| 6471 HCompareMap* mapcompare = | 6468 HCompareMap* mapcompare = |
| 6472 New<HCompareMap>(object, map, top_info(), this_map, other_map); | 6469 New<HCompareMap>(object, map, this_map, other_map); |
| 6473 FinishCurrentBlock(mapcompare); | 6470 FinishCurrentBlock(mapcompare); |
| 6474 | 6471 |
| 6475 set_current_block(this_map); | 6472 set_current_block(this_map); |
| 6476 HInstruction* access = NULL; | 6473 HInstruction* access = NULL; |
| 6477 if (IsDictionaryElementsKind(elements_kind)) { | 6474 if (IsDictionaryElementsKind(elements_kind)) { |
| 6478 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); | 6475 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); |
| 6479 } else { | 6476 } else { |
| 6480 ASSERT(IsFastElementsKind(elements_kind) || | 6477 ASSERT(IsFastElementsKind(elements_kind) || |
| 6481 IsExternalArrayElementsKind(elements_kind)); | 6478 IsExternalArrayElementsKind(elements_kind)); |
| 6482 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); | 6479 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6674 } | 6671 } |
| 6675 | 6672 |
| 6676 HValue* checked_object; | 6673 HValue* checked_object; |
| 6677 // Type::Number() is only supported by polymorphic load/call handling. | 6674 // Type::Number() is only supported by polymorphic load/call handling. |
| 6678 ASSERT(!info.type()->Is(Type::Number())); | 6675 ASSERT(!info.type()->Is(Type::Number())); |
| 6679 BuildCheckHeapObject(object); | 6676 BuildCheckHeapObject(object); |
| 6680 if (AreStringTypes(types)) { | 6677 if (AreStringTypes(types)) { |
| 6681 checked_object = | 6678 checked_object = |
| 6682 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); | 6679 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); |
| 6683 } else { | 6680 } else { |
| 6684 checked_object = Add<HCheckMaps>(object, types, top_info()); | 6681 checked_object = Add<HCheckMaps>(object, types); |
| 6685 } | 6682 } |
| 6686 return BuildMonomorphicAccess( | 6683 return BuildMonomorphicAccess( |
| 6687 &info, object, checked_object, value, ast_id, return_id); | 6684 &info, object, checked_object, value, ast_id, return_id); |
| 6688 } | 6685 } |
| 6689 | 6686 |
| 6690 return BuildNamedGeneric(access, object, name, value, is_uninitialized); | 6687 return BuildNamedGeneric(access, object, name, value, is_uninitialized); |
| 6691 } | 6688 } |
| 6692 | 6689 |
| 6693 | 6690 |
| 6694 void HOptimizedGraphBuilder::PushLoad(Property* expr, | 6691 void HOptimizedGraphBuilder::PushLoad(Property* expr, |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6926 } | 6923 } |
| 6927 } | 6924 } |
| 6928 ++count; | 6925 ++count; |
| 6929 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 6926 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 6930 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 6927 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 6931 HUnaryControlInstruction* compare; | 6928 HUnaryControlInstruction* compare; |
| 6932 | 6929 |
| 6933 Handle<Map> map = info.map(); | 6930 Handle<Map> map = info.map(); |
| 6934 if (info.type()->Is(Type::Number())) { | 6931 if (info.type()->Is(Type::Number())) { |
| 6935 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); | 6932 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); |
| 6936 compare = New<HCompareMap>(receiver, heap_number_map, top_info(), | 6933 compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false); |
| 6937 if_true, if_false); | |
| 6938 } else if (info.type()->Is(Type::String())) { | 6934 } else if (info.type()->Is(Type::String())) { |
| 6939 compare = New<HIsStringAndBranch>(receiver, if_true, if_false); | 6935 compare = New<HIsStringAndBranch>(receiver, if_true, if_false); |
| 6940 } else { | 6936 } else { |
| 6941 compare = New<HCompareMap>(receiver, map, top_info(), | 6937 compare = New<HCompareMap>(receiver, map, if_true, if_false); |
| 6942 if_true, if_false); | |
| 6943 } | 6938 } |
| 6944 FinishCurrentBlock(compare); | 6939 FinishCurrentBlock(compare); |
| 6945 | 6940 |
| 6946 if (info.type()->Is(Type::Number())) { | 6941 if (info.type()->Is(Type::Number())) { |
| 6947 GotoNoSimulate(if_true, number_block); | 6942 GotoNoSimulate(if_true, number_block); |
| 6948 if_true = number_block; | 6943 if_true = number_block; |
| 6949 } | 6944 } |
| 6950 | 6945 |
| 6951 set_current_block(if_true); | 6946 set_current_block(if_true); |
| 6952 | 6947 |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7782 function->ShortPrint(); | 7777 function->ShortPrint(); |
| 7783 PrintF("\n"); | 7778 PrintF("\n"); |
| 7784 } | 7779 } |
| 7785 | 7780 |
| 7786 bool drop_extra = false; | 7781 bool drop_extra = false; |
| 7787 bool is_store = false; | 7782 bool is_store = false; |
| 7788 switch (call_type) { | 7783 switch (call_type) { |
| 7789 case kCallApiFunction: | 7784 case kCallApiFunction: |
| 7790 case kCallApiMethod: | 7785 case kCallApiMethod: |
| 7791 // Need to check that none of the receiver maps could have changed. | 7786 // Need to check that none of the receiver maps could have changed. |
| 7792 Add<HCheckMaps>(receiver, receiver_maps, top_info()); | 7787 Add<HCheckMaps>(receiver, receiver_maps); |
| 7793 // Need to ensure the chain between receiver and api_holder is intact. | 7788 // Need to ensure the chain between receiver and api_holder is intact. |
| 7794 if (holder_lookup == CallOptimization::kHolderFound) { | 7789 if (holder_lookup == CallOptimization::kHolderFound) { |
| 7795 AddCheckPrototypeMaps(api_holder, receiver_maps->first()); | 7790 AddCheckPrototypeMaps(api_holder, receiver_maps->first()); |
| 7796 } else { | 7791 } else { |
| 7797 ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); | 7792 ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); |
| 7798 } | 7793 } |
| 7799 // Includes receiver. | 7794 // Includes receiver. |
| 7800 PushArgumentsFromEnvironment(argc + 1); | 7795 PushArgumentsFromEnvironment(argc + 1); |
| 7801 // Drop function after call. | 7796 // Drop function after call. |
| 7802 drop_extra = true; | 7797 drop_extra = true; |
| (...skipping 3491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11294 if (ShouldProduceTraceOutput()) { | 11289 if (ShouldProduceTraceOutput()) { |
| 11295 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11290 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11296 } | 11291 } |
| 11297 | 11292 |
| 11298 #ifdef DEBUG | 11293 #ifdef DEBUG |
| 11299 graph_->Verify(false); // No full verify. | 11294 graph_->Verify(false); // No full verify. |
| 11300 #endif | 11295 #endif |
| 11301 } | 11296 } |
| 11302 | 11297 |
| 11303 } } // namespace v8::internal | 11298 } } // namespace v8::internal |
| OLD | NEW |