| 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
| (...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1668 | 1668 |
| 1669 // hash = hash * 2057; | 1669 // hash = hash * 2057; |
| 1670 hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); | 1670 hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); |
| 1671 hash->ClearFlag(HValue::kCanOverflow); | 1671 hash->ClearFlag(HValue::kCanOverflow); |
| 1672 | 1672 |
| 1673 // hash = hash ^ (hash >> 16); | 1673 // hash = hash ^ (hash >> 16); |
| 1674 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); | 1674 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); |
| 1675 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); | 1675 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 | 1678 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, |
| 1679 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad( | 1679 HValue* elements, |
| 1680 HValue* receiver, HValue* elements, HValue* key, HValue* hash, | 1680 HValue* key, |
| 1681 LanguageMode language_mode) { | 1681 HValue* hash) { |
| 1682 HValue* capacity = | 1682 HValue* capacity = |
| 1683 Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), | 1683 Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), |
| 1684 nullptr, nullptr, FAST_ELEMENTS); | 1684 nullptr, nullptr, FAST_ELEMENTS); |
| 1685 | 1685 |
| 1686 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); | 1686 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); |
| 1687 mask->ChangeRepresentation(Representation::Integer32()); | 1687 mask->ChangeRepresentation(Representation::Integer32()); |
| 1688 mask->ClearFlag(HValue::kCanOverflow); | 1688 mask->ClearFlag(HValue::kCanOverflow); |
| 1689 | 1689 |
| 1690 HValue* entry = hash; | 1690 HValue* entry = hash; |
| 1691 HValue* count = graph()->GetConstant1(); | 1691 HValue* count = graph()->GetConstant1(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1714 HValue* candidate_key = | 1714 HValue* candidate_key = |
| 1715 Add<HLoadKeyed>(elements, key_index, nullptr, nullptr, FAST_ELEMENTS); | 1715 Add<HLoadKeyed>(elements, key_index, nullptr, nullptr, FAST_ELEMENTS); |
| 1716 IfBuilder if_undefined(this); | 1716 IfBuilder if_undefined(this); |
| 1717 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, | 1717 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, |
| 1718 graph()->GetConstantUndefined()); | 1718 graph()->GetConstantUndefined()); |
| 1719 if_undefined.Then(); | 1719 if_undefined.Then(); |
| 1720 { | 1720 { |
| 1721 // element == undefined means "not found". Call the runtime. | 1721 // element == undefined means "not found". Call the runtime. |
| 1722 // TODO(jkummerow): walk the prototype chain instead. | 1722 // TODO(jkummerow): walk the prototype chain instead. |
| 1723 Add<HPushArguments>(receiver, key); | 1723 Add<HPushArguments>(receiver, key); |
| 1724 Push(Add<HCallRuntime>( | 1724 Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kKeyedGetProperty), |
| 1725 Runtime::FunctionForId(is_strong(language_mode) | 1725 2)); |
| 1726 ? Runtime::kKeyedGetPropertyStrong | |
| 1727 : Runtime::kKeyedGetProperty), | |
| 1728 2)); | |
| 1729 } | 1726 } |
| 1730 if_undefined.Else(); | 1727 if_undefined.Else(); |
| 1731 { | 1728 { |
| 1732 IfBuilder if_match(this); | 1729 IfBuilder if_match(this); |
| 1733 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); | 1730 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); |
| 1734 if_match.Then(); | 1731 if_match.Then(); |
| 1735 if_match.Else(); | 1732 if_match.Else(); |
| 1736 | 1733 |
| 1737 // Update non-internalized string in the dictionary with internalized key? | 1734 // Update non-internalized string in the dictionary with internalized key? |
| 1738 IfBuilder if_update_with_internalized(this); | 1735 IfBuilder if_update_with_internalized(this); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1777 details_compare.If<HCompareNumericAndBranch>( | 1774 details_compare.If<HCompareNumericAndBranch>( |
| 1778 details, graph()->GetConstant0(), Token::EQ); | 1775 details, graph()->GetConstant0(), Token::EQ); |
| 1779 details_compare.Then(); | 1776 details_compare.Then(); |
| 1780 HValue* result_index = | 1777 HValue* result_index = |
| 1781 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); | 1778 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); |
| 1782 result_index->ClearFlag(HValue::kCanOverflow); | 1779 result_index->ClearFlag(HValue::kCanOverflow); |
| 1783 Push(Add<HLoadKeyed>(elements, result_index, nullptr, nullptr, | 1780 Push(Add<HLoadKeyed>(elements, result_index, nullptr, nullptr, |
| 1784 FAST_ELEMENTS)); | 1781 FAST_ELEMENTS)); |
| 1785 details_compare.Else(); | 1782 details_compare.Else(); |
| 1786 Add<HPushArguments>(receiver, key); | 1783 Add<HPushArguments>(receiver, key); |
| 1787 Push(Add<HCallRuntime>( | 1784 Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kKeyedGetProperty), |
| 1788 Runtime::FunctionForId(is_strong(language_mode) | 1785 2)); |
| 1789 ? Runtime::kKeyedGetPropertyStrong | |
| 1790 : Runtime::kKeyedGetProperty), | |
| 1791 2)); | |
| 1792 details_compare.End(); | 1786 details_compare.End(); |
| 1793 | 1787 |
| 1794 found_key_match.Else(); | 1788 found_key_match.Else(); |
| 1795 found_key_match.JoinContinuation(&return_or_loop_continuation); | 1789 found_key_match.JoinContinuation(&return_or_loop_continuation); |
| 1796 } | 1790 } |
| 1797 if_undefined.JoinContinuation(&return_or_loop_continuation); | 1791 if_undefined.JoinContinuation(&return_or_loop_continuation); |
| 1798 | 1792 |
| 1799 IfBuilder return_or_loop(this, &return_or_loop_continuation); | 1793 IfBuilder return_or_loop(this, &return_or_loop_continuation); |
| 1800 return_or_loop.Then(); | 1794 return_or_loop.Then(); |
| 1801 probe_loop.Break(); | 1795 probe_loop.Break(); |
| (...skipping 5511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7313 if (access_type == LOAD) { | 7307 if (access_type == LOAD) { |
| 7314 Handle<TypeFeedbackVector> vector = | 7308 Handle<TypeFeedbackVector> vector = |
| 7315 handle(current_feedback_vector(), isolate()); | 7309 handle(current_feedback_vector(), isolate()); |
| 7316 | 7310 |
| 7317 if (!expr->AsProperty()->key()->IsPropertyName()) { | 7311 if (!expr->AsProperty()->key()->IsPropertyName()) { |
| 7318 // It's possible that a keyed load of a constant string was converted | 7312 // It's possible that a keyed load of a constant string was converted |
| 7319 // to a named load. Here, at the last minute, we need to make sure to | 7313 // to a named load. Here, at the last minute, we need to make sure to |
| 7320 // use a generic Keyed Load if we are using the type vector, because | 7314 // use a generic Keyed Load if we are using the type vector, because |
| 7321 // it has to share information with full code. | 7315 // it has to share information with full code. |
| 7322 HConstant* key = Add<HConstant>(name); | 7316 HConstant* key = Add<HConstant>(name); |
| 7323 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( | 7317 HLoadKeyedGeneric* result = |
| 7324 object, key, function_language_mode(), PREMONOMORPHIC); | 7318 New<HLoadKeyedGeneric>(object, key, PREMONOMORPHIC); |
| 7325 result->SetVectorAndSlot(vector, slot); | 7319 result->SetVectorAndSlot(vector, slot); |
| 7326 return result; | 7320 return result; |
| 7327 } | 7321 } |
| 7328 | 7322 |
| 7329 HLoadNamedGeneric* result = New<HLoadNamedGeneric>( | 7323 HLoadNamedGeneric* result = |
| 7330 object, name, function_language_mode(), PREMONOMORPHIC); | 7324 New<HLoadNamedGeneric>(object, name, PREMONOMORPHIC); |
| 7331 result->SetVectorAndSlot(vector, slot); | 7325 result->SetVectorAndSlot(vector, slot); |
| 7332 return result; | 7326 return result; |
| 7333 } else { | 7327 } else { |
| 7334 if (current_feedback_vector()->GetKind(slot) == | 7328 if (current_feedback_vector()->GetKind(slot) == |
| 7335 FeedbackVectorSlotKind::KEYED_STORE_IC) { | 7329 FeedbackVectorSlotKind::KEYED_STORE_IC) { |
| 7336 // It's possible that a keyed store of a constant string was converted | 7330 // It's possible that a keyed store of a constant string was converted |
| 7337 // to a named store. Here, at the last minute, we need to make sure to | 7331 // to a named store. Here, at the last minute, we need to make sure to |
| 7338 // use a generic Keyed Store if we are using the type vector, because | 7332 // use a generic Keyed Store if we are using the type vector, because |
| 7339 // it has to share information with full code. | 7333 // it has to share information with full code. |
| 7340 HConstant* key = Add<HConstant>(name); | 7334 HConstant* key = Add<HConstant>(name); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7354 return result; | 7348 return result; |
| 7355 } | 7349 } |
| 7356 } | 7350 } |
| 7357 | 7351 |
| 7358 | 7352 |
| 7359 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( | 7353 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( |
| 7360 PropertyAccessType access_type, Expression* expr, FeedbackVectorSlot slot, | 7354 PropertyAccessType access_type, Expression* expr, FeedbackVectorSlot slot, |
| 7361 HValue* object, HValue* key, HValue* value) { | 7355 HValue* object, HValue* key, HValue* value) { |
| 7362 if (access_type == LOAD) { | 7356 if (access_type == LOAD) { |
| 7363 InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); | 7357 InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); |
| 7364 HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( | 7358 HLoadKeyedGeneric* result = |
| 7365 object, key, function_language_mode(), initial_state); | 7359 New<HLoadKeyedGeneric>(object, key, initial_state); |
| 7366 // HLoadKeyedGeneric with vector ics benefits from being encoded as | 7360 // HLoadKeyedGeneric with vector ics benefits from being encoded as |
| 7367 // MEGAMORPHIC because the vector/slot combo becomes unnecessary. | 7361 // MEGAMORPHIC because the vector/slot combo becomes unnecessary. |
| 7368 if (initial_state != MEGAMORPHIC) { | 7362 if (initial_state != MEGAMORPHIC) { |
| 7369 // We need to pass vector information. | 7363 // We need to pass vector information. |
| 7370 Handle<TypeFeedbackVector> vector = | 7364 Handle<TypeFeedbackVector> vector = |
| 7371 handle(current_feedback_vector(), isolate()); | 7365 handle(current_feedback_vector(), isolate()); |
| 7372 result->SetVectorAndSlot(vector, slot); | 7366 result->SetVectorAndSlot(vector, slot); |
| 7373 } | 7367 } |
| 7374 return result; | 7368 return result; |
| 7375 } else { | 7369 } else { |
| (...skipping 6210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13586 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13580 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13587 } | 13581 } |
| 13588 | 13582 |
| 13589 #ifdef DEBUG | 13583 #ifdef DEBUG |
| 13590 graph_->Verify(false); // No full verify. | 13584 graph_->Verify(false); // No full verify. |
| 13591 #endif | 13585 #endif |
| 13592 } | 13586 } |
| 13593 | 13587 |
| 13594 } // namespace internal | 13588 } // namespace internal |
| 13595 } // namespace v8 | 13589 } // namespace v8 |
| OLD | NEW |