OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 HConstant* HGraph::GetConstant1() { | 676 HConstant* HGraph::GetConstant1() { |
677 return GetConstant(&constant_1_, 1); | 677 return GetConstant(&constant_1_, 1); |
678 } | 678 } |
679 | 679 |
680 | 680 |
681 HConstant* HGraph::GetConstantMinus1() { | 681 HConstant* HGraph::GetConstantMinus1() { |
682 return GetConstant(&constant_minus1_, -1); | 682 return GetConstant(&constant_minus1_, -1); |
683 } | 683 } |
684 | 684 |
685 | 685 |
686 HConstant* HGraph::GetConstantBool(bool value) { | |
687 return value ? GetConstantTrue() : GetConstantFalse(); | |
688 } | |
689 | |
690 | |
691 #define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value) \ | 686 #define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value) \ |
692 HConstant* HGraph::GetConstant##Name() { \ | 687 HConstant* HGraph::GetConstant##Name() { \ |
693 if (!constant_##name##_.is_set()) { \ | 688 if (!constant_##name##_.is_set()) { \ |
694 HConstant* constant = new(zone()) HConstant( \ | 689 HConstant* constant = new(zone()) HConstant( \ |
695 Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \ | 690 Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \ |
696 Unique<Map>::CreateImmovable(isolate()->factory()->type##_map()), \ | 691 Unique<Map>::CreateImmovable(isolate()->factory()->type##_map()), \ |
697 false, \ | 692 false, \ |
698 Representation::Tagged(), \ | 693 Representation::Tagged(), \ |
699 htype, \ | 694 htype, \ |
700 true, \ | 695 true, \ |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 // hash = hash * 2057; | 1660 // hash = hash * 2057; |
1666 hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); | 1661 hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); |
1667 hash->ClearFlag(HValue::kCanOverflow); | 1662 hash->ClearFlag(HValue::kCanOverflow); |
1668 | 1663 |
1669 // hash = hash ^ (hash >> 16); | 1664 // hash = hash ^ (hash >> 16); |
1670 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); | 1665 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); |
1671 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); | 1666 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); |
1672 } | 1667 } |
1673 | 1668 |
1674 | 1669 |
1675 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad( | 1670 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, |
1676 HValue* receiver, HValue* elements, HValue* key, HValue* hash, | 1671 HValue* elements, |
1677 LanguageMode language_mode) { | 1672 HValue* key, |
| 1673 HValue* hash) { |
1678 HValue* capacity = | 1674 HValue* capacity = |
1679 Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), | 1675 Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), |
1680 nullptr, FAST_ELEMENTS); | 1676 nullptr, FAST_ELEMENTS); |
1681 | 1677 |
1682 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); | 1678 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); |
1683 mask->ChangeRepresentation(Representation::Integer32()); | 1679 mask->ChangeRepresentation(Representation::Integer32()); |
1684 mask->ClearFlag(HValue::kCanOverflow); | 1680 mask->ClearFlag(HValue::kCanOverflow); |
1685 | 1681 |
1686 HValue* entry = hash; | 1682 HValue* entry = hash; |
1687 HValue* count = graph()->GetConstant1(); | 1683 HValue* count = graph()->GetConstant1(); |
(...skipping 21 matching lines...) Expand all Loading... |
1709 | 1705 |
1710 HValue* candidate_key = | 1706 HValue* candidate_key = |
1711 Add<HLoadKeyed>(elements, key_index, nullptr, FAST_ELEMENTS); | 1707 Add<HLoadKeyed>(elements, key_index, nullptr, FAST_ELEMENTS); |
1712 IfBuilder if_undefined(this); | 1708 IfBuilder if_undefined(this); |
1713 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, | 1709 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, |
1714 graph()->GetConstantUndefined()); | 1710 graph()->GetConstantUndefined()); |
1715 if_undefined.Then(); | 1711 if_undefined.Then(); |
1716 { | 1712 { |
1717 // element == undefined means "not found". Call the runtime. | 1713 // element == undefined means "not found". Call the runtime. |
1718 // TODO(jkummerow): walk the prototype chain instead. | 1714 // TODO(jkummerow): walk the prototype chain instead. |
1719 Add<HPushArguments>(receiver, key, Add<HConstant>(language_mode)); | 1715 Add<HPushArguments>(receiver, key); |
1720 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), | 1716 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), |
1721 Runtime::FunctionForId(Runtime::kKeyedGetProperty), | 1717 Runtime::FunctionForId(Runtime::kKeyedGetProperty), |
1722 3)); | 1718 2)); |
1723 } | 1719 } |
1724 if_undefined.Else(); | 1720 if_undefined.Else(); |
1725 { | 1721 { |
1726 IfBuilder if_match(this); | 1722 IfBuilder if_match(this); |
1727 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); | 1723 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); |
1728 if_match.Then(); | 1724 if_match.Then(); |
1729 if_match.Else(); | 1725 if_match.Else(); |
1730 | 1726 |
1731 // Update non-internalized string in the dictionary with internalized key? | 1727 // Update non-internalized string in the dictionary with internalized key? |
1732 IfBuilder if_update_with_internalized(this); | 1728 IfBuilder if_update_with_internalized(this); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1769 Add<HConstant>(details_mask)); | 1765 Add<HConstant>(details_mask)); |
1770 IfBuilder details_compare(this); | 1766 IfBuilder details_compare(this); |
1771 details_compare.If<HCompareNumericAndBranch>( | 1767 details_compare.If<HCompareNumericAndBranch>( |
1772 details, graph()->GetConstant0(), Token::EQ); | 1768 details, graph()->GetConstant0(), Token::EQ); |
1773 details_compare.Then(); | 1769 details_compare.Then(); |
1774 HValue* result_index = | 1770 HValue* result_index = |
1775 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); | 1771 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); |
1776 result_index->ClearFlag(HValue::kCanOverflow); | 1772 result_index->ClearFlag(HValue::kCanOverflow); |
1777 Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS)); | 1773 Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS)); |
1778 details_compare.Else(); | 1774 details_compare.Else(); |
1779 Add<HPushArguments>(receiver, key, Add<HConstant>(language_mode)); | 1775 Add<HPushArguments>(receiver, key); |
1780 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), | 1776 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), |
1781 Runtime::FunctionForId(Runtime::kKeyedGetProperty), | 1777 Runtime::FunctionForId(Runtime::kKeyedGetProperty), |
1782 3)); | 1778 2)); |
1783 details_compare.End(); | 1779 details_compare.End(); |
1784 | 1780 |
1785 found_key_match.Else(); | 1781 found_key_match.Else(); |
1786 found_key_match.JoinContinuation(&return_or_loop_continuation); | 1782 found_key_match.JoinContinuation(&return_or_loop_continuation); |
1787 } | 1783 } |
1788 if_undefined.JoinContinuation(&return_or_loop_continuation); | 1784 if_undefined.JoinContinuation(&return_or_loop_continuation); |
1789 | 1785 |
1790 IfBuilder return_or_loop(this, &return_or_loop_continuation); | 1786 IfBuilder return_or_loop(this, &return_or_loop_continuation); |
1791 return_or_loop.Then(); | 1787 return_or_loop.Then(); |
1792 probe_loop.Break(); | 1788 probe_loop.Break(); |
(...skipping 4427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6220 if (IsJSObjectFieldAccessor()) return IsLoad(); | 6216 if (IsJSObjectFieldAccessor()) return IsLoad(); |
6221 if (IsJSArrayBufferViewFieldAccessor()) return IsLoad(); | 6217 if (IsJSArrayBufferViewFieldAccessor()) return IsLoad(); |
6222 if (map_->function_with_prototype() && !map_->has_non_instance_prototype() && | 6218 if (map_->function_with_prototype() && !map_->has_non_instance_prototype() && |
6223 name_.is_identical_to(isolate()->factory()->prototype_string())) { | 6219 name_.is_identical_to(isolate()->factory()->prototype_string())) { |
6224 return IsLoad(); | 6220 return IsLoad(); |
6225 } | 6221 } |
6226 if (!LookupDescriptor()) return false; | 6222 if (!LookupDescriptor()) return false; |
6227 if (IsFound()) return IsLoad() || !IsReadOnly(); | 6223 if (IsFound()) return IsLoad() || !IsReadOnly(); |
6228 if (IsIntegerIndexedExotic()) return false; | 6224 if (IsIntegerIndexedExotic()) return false; |
6229 if (!LookupInPrototypes()) return false; | 6225 if (!LookupInPrototypes()) return false; |
6230 if (IsLoad()) return !is_strong(builder_->function_language_mode()); | 6226 if (IsLoad()) return true; |
6231 | 6227 |
6232 if (IsAccessorConstant()) return true; | 6228 if (IsAccessorConstant()) return true; |
6233 LookupTransition(*map_, *name_, NONE); | 6229 LookupTransition(*map_, *name_, NONE); |
6234 if (IsTransitionToData() && map_->unused_property_fields() > 0) { | 6230 if (IsTransitionToData() && map_->unused_property_fields() > 0) { |
6235 // Construct the object field access. | 6231 // Construct the object field access. |
6236 int descriptor = transition()->LastAdded(); | 6232 int descriptor = transition()->LastAdded(); |
6237 int index = | 6233 int index = |
6238 transition()->instance_descriptors()->GetFieldIndex(descriptor) - | 6234 transition()->instance_descriptors()->GetFieldIndex(descriptor) - |
6239 map_->inobject_properties(); | 6235 map_->inobject_properties(); |
6240 PropertyDetails details = | 6236 PropertyDetails details = |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7038 Handle<TypeFeedbackVector> vector = | 7034 Handle<TypeFeedbackVector> vector = |
7039 handle(current_feedback_vector(), isolate()); | 7035 handle(current_feedback_vector(), isolate()); |
7040 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); | 7036 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); |
7041 | 7037 |
7042 if (!expr->AsProperty()->key()->IsPropertyName()) { | 7038 if (!expr->AsProperty()->key()->IsPropertyName()) { |
7043 // It's possible that a keyed load of a constant string was converted | 7039 // It's possible that a keyed load of a constant string was converted |
7044 // to a named load. Here, at the last minute, we need to make sure to | 7040 // to a named load. Here, at the last minute, we need to make sure to |
7045 // use a generic Keyed Load if we are using the type vector, because | 7041 // use a generic Keyed Load if we are using the type vector, because |
7046 // it has to share information with full code. | 7042 // it has to share information with full code. |
7047 HConstant* key = Add<HConstant>(name); | 7043 HConstant* key = Add<HConstant>(name); |
7048 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( | 7044 HLoadKeyedGeneric* result = |
7049 object, key, function_language_mode(), PREMONOMORPHIC); | 7045 New<HLoadKeyedGeneric>(object, key, PREMONOMORPHIC); |
7050 result->SetVectorAndSlot(vector, slot); | 7046 result->SetVectorAndSlot(vector, slot); |
7051 return result; | 7047 return result; |
7052 } | 7048 } |
7053 | 7049 |
7054 HLoadNamedGeneric* result = New<HLoadNamedGeneric>( | 7050 HLoadNamedGeneric* result = |
7055 object, name, function_language_mode(), PREMONOMORPHIC); | 7051 New<HLoadNamedGeneric>(object, name, PREMONOMORPHIC); |
7056 result->SetVectorAndSlot(vector, slot); | 7052 result->SetVectorAndSlot(vector, slot); |
7057 return result; | 7053 return result; |
7058 } else { | 7054 } else { |
7059 return New<HStoreNamedGeneric>(object, name, value, | 7055 return New<HStoreNamedGeneric>(object, name, value, |
7060 function_language_mode(), PREMONOMORPHIC); | 7056 function_language_mode(), PREMONOMORPHIC); |
7061 } | 7057 } |
7062 } | 7058 } |
7063 | 7059 |
7064 | 7060 |
7065 | 7061 |
7066 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( | 7062 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( |
7067 PropertyAccessType access_type, | 7063 PropertyAccessType access_type, |
7068 Expression* expr, | 7064 Expression* expr, |
7069 HValue* object, | 7065 HValue* object, |
7070 HValue* key, | 7066 HValue* key, |
7071 HValue* value) { | 7067 HValue* value) { |
7072 if (access_type == LOAD) { | 7068 if (access_type == LOAD) { |
7073 InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); | 7069 InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); |
7074 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( | 7070 HLoadKeyedGeneric* result = |
7075 object, key, function_language_mode(), initial_state); | 7071 New<HLoadKeyedGeneric>(object, key, initial_state); |
7076 // HLoadKeyedGeneric with vector ics benefits from being encoded as | 7072 // HLoadKeyedGeneric with vector ics benefits from being encoded as |
7077 // MEGAMORPHIC because the vector/slot combo becomes unnecessary. | 7073 // MEGAMORPHIC because the vector/slot combo becomes unnecessary. |
7078 if (initial_state != MEGAMORPHIC) { | 7074 if (initial_state != MEGAMORPHIC) { |
7079 // We need to pass vector information. | 7075 // We need to pass vector information. |
7080 Handle<TypeFeedbackVector> vector = | 7076 Handle<TypeFeedbackVector> vector = |
7081 handle(current_feedback_vector(), isolate()); | 7077 handle(current_feedback_vector(), isolate()); |
7082 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); | 7078 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); |
7083 result->SetVectorAndSlot(vector, slot); | 7079 result->SetVectorAndSlot(vector, slot); |
7084 } | 7080 } |
7085 return result; | 7081 return result; |
(...skipping 6118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13204 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13200 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13205 } | 13201 } |
13206 | 13202 |
13207 #ifdef DEBUG | 13203 #ifdef DEBUG |
13208 graph_->Verify(false); // No full verify. | 13204 graph_->Verify(false); // No full verify. |
13209 #endif | 13205 #endif |
13210 } | 13206 } |
13211 | 13207 |
13212 } // namespace internal | 13208 } // namespace internal |
13213 } // namespace v8 | 13209 } // namespace v8 |
OLD | NEW |