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