| 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 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 new_length->ClearFlag(HValue::kCanOverflow); | 1365 new_length->ClearFlag(HValue::kCanOverflow); |
| 1366 | 1366 |
| 1367 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), | 1367 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), |
| 1368 new_length); | 1368 new_length); |
| 1369 } | 1369 } |
| 1370 | 1370 |
| 1371 if (access_type == STORE && kind == FAST_SMI_ELEMENTS) { | 1371 if (access_type == STORE && kind == FAST_SMI_ELEMENTS) { |
| 1372 HValue* checked_elements = environment()->Top(); | 1372 HValue* checked_elements = environment()->Top(); |
| 1373 | 1373 |
| 1374 // Write zero to ensure that the new element is initialized with some smi. | 1374 // Write zero to ensure that the new element is initialized with some smi. |
| 1375 Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind); | 1375 Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), nullptr, |
| 1376 kind); |
| 1376 } | 1377 } |
| 1377 | 1378 |
| 1378 length_checker.Else(); | 1379 length_checker.Else(); |
| 1379 Add<HBoundsCheck>(key, length); | 1380 Add<HBoundsCheck>(key, length); |
| 1380 | 1381 |
| 1381 environment()->Push(elements); | 1382 environment()->Push(elements); |
| 1382 length_checker.End(); | 1383 length_checker.End(); |
| 1383 | 1384 |
| 1384 return environment()->Pop(); | 1385 return environment()->Pop(); |
| 1385 } | 1386 } |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); | 1670 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); |
| 1670 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); | 1671 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); |
| 1671 } | 1672 } |
| 1672 | 1673 |
| 1673 | 1674 |
| 1674 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad( | 1675 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad( |
| 1675 HValue* receiver, HValue* elements, HValue* key, HValue* hash, | 1676 HValue* receiver, HValue* elements, HValue* key, HValue* hash, |
| 1676 LanguageMode language_mode) { | 1677 LanguageMode language_mode) { |
| 1677 HValue* capacity = | 1678 HValue* capacity = |
| 1678 Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), | 1679 Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), |
| 1679 nullptr, FAST_ELEMENTS); | 1680 nullptr, nullptr, FAST_ELEMENTS); |
| 1680 | 1681 |
| 1681 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); | 1682 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); |
| 1682 mask->ChangeRepresentation(Representation::Integer32()); | 1683 mask->ChangeRepresentation(Representation::Integer32()); |
| 1683 mask->ClearFlag(HValue::kCanOverflow); | 1684 mask->ClearFlag(HValue::kCanOverflow); |
| 1684 | 1685 |
| 1685 HValue* entry = hash; | 1686 HValue* entry = hash; |
| 1686 HValue* count = graph()->GetConstant1(); | 1687 HValue* count = graph()->GetConstant1(); |
| 1687 Push(entry); | 1688 Push(entry); |
| 1688 Push(count); | 1689 Push(count); |
| 1689 | 1690 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1700 entry = AddUncasted<HBitwise>(Token::BIT_AND, entry, mask); | 1701 entry = AddUncasted<HBitwise>(Token::BIT_AND, entry, mask); |
| 1701 int entry_size = SeededNumberDictionary::kEntrySize; | 1702 int entry_size = SeededNumberDictionary::kEntrySize; |
| 1702 HValue* base_index = AddUncasted<HMul>(entry, Add<HConstant>(entry_size)); | 1703 HValue* base_index = AddUncasted<HMul>(entry, Add<HConstant>(entry_size)); |
| 1703 base_index->ClearFlag(HValue::kCanOverflow); | 1704 base_index->ClearFlag(HValue::kCanOverflow); |
| 1704 int start_offset = SeededNumberDictionary::kElementsStartIndex; | 1705 int start_offset = SeededNumberDictionary::kElementsStartIndex; |
| 1705 HValue* key_index = | 1706 HValue* key_index = |
| 1706 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset)); | 1707 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset)); |
| 1707 key_index->ClearFlag(HValue::kCanOverflow); | 1708 key_index->ClearFlag(HValue::kCanOverflow); |
| 1708 | 1709 |
| 1709 HValue* candidate_key = | 1710 HValue* candidate_key = |
| 1710 Add<HLoadKeyed>(elements, key_index, nullptr, FAST_ELEMENTS); | 1711 Add<HLoadKeyed>(elements, key_index, nullptr, nullptr, FAST_ELEMENTS); |
| 1711 IfBuilder if_undefined(this); | 1712 IfBuilder if_undefined(this); |
| 1712 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, | 1713 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, |
| 1713 graph()->GetConstantUndefined()); | 1714 graph()->GetConstantUndefined()); |
| 1714 if_undefined.Then(); | 1715 if_undefined.Then(); |
| 1715 { | 1716 { |
| 1716 // element == undefined means "not found". Call the runtime. | 1717 // element == undefined means "not found". Call the runtime. |
| 1717 // TODO(jkummerow): walk the prototype chain instead. | 1718 // TODO(jkummerow): walk the prototype chain instead. |
| 1718 Add<HPushArguments>(receiver, key); | 1719 Add<HPushArguments>(receiver, key); |
| 1719 Push(Add<HCallRuntime>( | 1720 Push(Add<HCallRuntime>( |
| 1720 Runtime::FunctionForId(is_strong(language_mode) | 1721 Runtime::FunctionForId(is_strong(language_mode) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1743 if_update_with_internalized.If<HCompareNumericAndBranch>( | 1744 if_update_with_internalized.If<HCompareNumericAndBranch>( |
| 1744 not_internalized_bit, graph()->GetConstant0(), Token::NE); | 1745 not_internalized_bit, graph()->GetConstant0(), Token::NE); |
| 1745 if_update_with_internalized.And(); | 1746 if_update_with_internalized.And(); |
| 1746 if_update_with_internalized.IfNot<HCompareObjectEqAndBranch>( | 1747 if_update_with_internalized.IfNot<HCompareObjectEqAndBranch>( |
| 1747 candidate_key, graph()->GetConstantHole()); | 1748 candidate_key, graph()->GetConstantHole()); |
| 1748 if_update_with_internalized.AndIf<HStringCompareAndBranch>(candidate_key, | 1749 if_update_with_internalized.AndIf<HStringCompareAndBranch>(candidate_key, |
| 1749 key, Token::EQ); | 1750 key, Token::EQ); |
| 1750 if_update_with_internalized.Then(); | 1751 if_update_with_internalized.Then(); |
| 1751 // Replace a key that is a non-internalized string by the equivalent | 1752 // Replace a key that is a non-internalized string by the equivalent |
| 1752 // internalized string for faster further lookups. | 1753 // internalized string for faster further lookups. |
| 1753 Add<HStoreKeyed>(elements, key_index, key, FAST_ELEMENTS); | 1754 Add<HStoreKeyed>(elements, key_index, key, nullptr, FAST_ELEMENTS); |
| 1754 if_update_with_internalized.Else(); | 1755 if_update_with_internalized.Else(); |
| 1755 | 1756 |
| 1756 if_update_with_internalized.JoinContinuation(&found_key_match_continuation); | 1757 if_update_with_internalized.JoinContinuation(&found_key_match_continuation); |
| 1757 if_match.JoinContinuation(&found_key_match_continuation); | 1758 if_match.JoinContinuation(&found_key_match_continuation); |
| 1758 | 1759 |
| 1759 IfBuilder found_key_match(this, &found_key_match_continuation); | 1760 IfBuilder found_key_match(this, &found_key_match_continuation); |
| 1760 found_key_match.Then(); | 1761 found_key_match.Then(); |
| 1761 // Key at current probe matches. Relevant bits in the |details| field must | 1762 // Key at current probe matches. Relevant bits in the |details| field must |
| 1762 // be zero, otherwise the dictionary element requires special handling. | 1763 // be zero, otherwise the dictionary element requires special handling. |
| 1763 HValue* details_index = | 1764 HValue* details_index = |
| 1764 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 2)); | 1765 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 2)); |
| 1765 details_index->ClearFlag(HValue::kCanOverflow); | 1766 details_index->ClearFlag(HValue::kCanOverflow); |
| 1766 HValue* details = | 1767 HValue* details = Add<HLoadKeyed>(elements, details_index, nullptr, nullptr, |
| 1767 Add<HLoadKeyed>(elements, details_index, nullptr, FAST_ELEMENTS); | 1768 FAST_ELEMENTS); |
| 1768 int details_mask = PropertyDetails::TypeField::kMask; | 1769 int details_mask = PropertyDetails::TypeField::kMask; |
| 1769 details = AddUncasted<HBitwise>(Token::BIT_AND, details, | 1770 details = AddUncasted<HBitwise>(Token::BIT_AND, details, |
| 1770 Add<HConstant>(details_mask)); | 1771 Add<HConstant>(details_mask)); |
| 1771 IfBuilder details_compare(this); | 1772 IfBuilder details_compare(this); |
| 1772 details_compare.If<HCompareNumericAndBranch>( | 1773 details_compare.If<HCompareNumericAndBranch>( |
| 1773 details, graph()->GetConstant0(), Token::EQ); | 1774 details, graph()->GetConstant0(), Token::EQ); |
| 1774 details_compare.Then(); | 1775 details_compare.Then(); |
| 1775 HValue* result_index = | 1776 HValue* result_index = |
| 1776 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); | 1777 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); |
| 1777 result_index->ClearFlag(HValue::kCanOverflow); | 1778 result_index->ClearFlag(HValue::kCanOverflow); |
| 1778 Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS)); | 1779 Push(Add<HLoadKeyed>(elements, result_index, nullptr, nullptr, |
| 1780 FAST_ELEMENTS)); |
| 1779 details_compare.Else(); | 1781 details_compare.Else(); |
| 1780 Add<HPushArguments>(receiver, key); | 1782 Add<HPushArguments>(receiver, key); |
| 1781 Push(Add<HCallRuntime>( | 1783 Push(Add<HCallRuntime>( |
| 1782 Runtime::FunctionForId(is_strong(language_mode) | 1784 Runtime::FunctionForId(is_strong(language_mode) |
| 1783 ? Runtime::kKeyedGetPropertyStrong | 1785 ? Runtime::kKeyedGetPropertyStrong |
| 1784 : Runtime::kKeyedGetProperty), | 1786 : Runtime::kKeyedGetProperty), |
| 1785 2)); | 1787 2)); |
| 1786 details_compare.End(); | 1788 details_compare.End(); |
| 1787 | 1789 |
| 1788 found_key_match.Else(); | 1790 found_key_match.Else(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1938 IfBuilder if_objectissmi(this); | 1940 IfBuilder if_objectissmi(this); |
| 1939 if_objectissmi.If<HIsSmiAndBranch>(object); | 1941 if_objectissmi.If<HIsSmiAndBranch>(object); |
| 1940 if_objectissmi.Then(); | 1942 if_objectissmi.Then(); |
| 1941 { | 1943 { |
| 1942 // Compute hash for smi similar to smi_get_hash(). | 1944 // Compute hash for smi similar to smi_get_hash(). |
| 1943 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); | 1945 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); |
| 1944 | 1946 |
| 1945 // Load the key. | 1947 // Load the key. |
| 1946 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); | 1948 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); |
| 1947 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, | 1949 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, |
| 1948 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 1950 nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 1949 | 1951 |
| 1950 // Check if object == key. | 1952 // Check if object == key. |
| 1951 IfBuilder if_objectiskey(this); | 1953 IfBuilder if_objectiskey(this); |
| 1952 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); | 1954 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); |
| 1953 if_objectiskey.Then(); | 1955 if_objectiskey.Then(); |
| 1954 { | 1956 { |
| 1955 // Make the key_index available. | 1957 // Make the key_index available. |
| 1956 Push(key_index); | 1958 Push(key_index); |
| 1957 } | 1959 } |
| 1958 if_objectiskey.JoinContinuation(&found); | 1960 if_objectiskey.JoinContinuation(&found); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1973 object, objectisnumber, | 1975 object, objectisnumber, |
| 1974 HObjectAccess::ForHeapNumberValueLowestBits()); | 1976 HObjectAccess::ForHeapNumberValueLowestBits()); |
| 1975 HValue* high = Add<HLoadNamedField>( | 1977 HValue* high = Add<HLoadNamedField>( |
| 1976 object, objectisnumber, | 1978 object, objectisnumber, |
| 1977 HObjectAccess::ForHeapNumberValueHighestBits()); | 1979 HObjectAccess::ForHeapNumberValueHighestBits()); |
| 1978 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); | 1980 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); |
| 1979 hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); | 1981 hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); |
| 1980 | 1982 |
| 1981 // Load the key. | 1983 // Load the key. |
| 1982 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); | 1984 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); |
| 1983 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, | 1985 HValue* key = |
| 1984 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 1986 Add<HLoadKeyed>(number_string_cache, key_index, nullptr, nullptr, |
| 1987 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 1985 | 1988 |
| 1986 // Check if the key is a heap number and compare it with the object. | 1989 // Check if the key is a heap number and compare it with the object. |
| 1987 IfBuilder if_keyisnotsmi(this); | 1990 IfBuilder if_keyisnotsmi(this); |
| 1988 HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); | 1991 HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); |
| 1989 if_keyisnotsmi.Then(); | 1992 if_keyisnotsmi.Then(); |
| 1990 { | 1993 { |
| 1991 IfBuilder if_keyisheapnumber(this); | 1994 IfBuilder if_keyisheapnumber(this); |
| 1992 if_keyisheapnumber.If<HCompareMap>( | 1995 if_keyisheapnumber.If<HCompareMap>( |
| 1993 key, isolate()->factory()->heap_number_map()); | 1996 key, isolate()->factory()->heap_number_map()); |
| 1994 if_keyisheapnumber.Then(); | 1997 if_keyisheapnumber.Then(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 // Check for cache hit. | 2029 // Check for cache hit. |
| 2027 IfBuilder if_found(this, &found); | 2030 IfBuilder if_found(this, &found); |
| 2028 if_found.Then(); | 2031 if_found.Then(); |
| 2029 { | 2032 { |
| 2030 // Count number to string operation in native code. | 2033 // Count number to string operation in native code. |
| 2031 AddIncrementCounter(isolate()->counters()->number_to_string_native()); | 2034 AddIncrementCounter(isolate()->counters()->number_to_string_native()); |
| 2032 | 2035 |
| 2033 // Load the value in case of cache hit. | 2036 // Load the value in case of cache hit. |
| 2034 HValue* key_index = Pop(); | 2037 HValue* key_index = Pop(); |
| 2035 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); | 2038 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); |
| 2036 Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, | 2039 Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, nullptr, |
| 2037 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); | 2040 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); |
| 2038 } | 2041 } |
| 2039 if_found.Else(); | 2042 if_found.Else(); |
| 2040 { | 2043 { |
| 2041 // Cache miss, fallback to runtime. | 2044 // Cache miss, fallback to runtime. |
| 2042 Add<HPushArguments>(object); | 2045 Add<HPushArguments>(object); |
| 2043 Push(Add<HCallRuntime>( | 2046 Push(Add<HCallRuntime>( |
| 2044 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), | 2047 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), |
| 2045 1)); | 2048 1)); |
| 2046 } | 2049 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2110 if_wrap.Then(); | 2113 if_wrap.Then(); |
| 2111 { | 2114 { |
| 2112 // Grab the constructor function index. | 2115 // Grab the constructor function index. |
| 2113 HValue* constructor_index = Pop(); | 2116 HValue* constructor_index = Pop(); |
| 2114 | 2117 |
| 2115 // Load native context. | 2118 // Load native context. |
| 2116 HValue* native_context = BuildGetNativeContext(); | 2119 HValue* native_context = BuildGetNativeContext(); |
| 2117 | 2120 |
| 2118 // Determine the initial map for the global constructor. | 2121 // Determine the initial map for the global constructor. |
| 2119 HValue* constructor = Add<HLoadKeyed>(native_context, constructor_index, | 2122 HValue* constructor = Add<HLoadKeyed>(native_context, constructor_index, |
| 2120 nullptr, FAST_ELEMENTS); | 2123 nullptr, nullptr, FAST_ELEMENTS); |
| 2121 HValue* constructor_initial_map = Add<HLoadNamedField>( | 2124 HValue* constructor_initial_map = Add<HLoadNamedField>( |
| 2122 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); | 2125 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); |
| 2123 // Allocate and initialize a JSValue wrapper. | 2126 // Allocate and initialize a JSValue wrapper. |
| 2124 HValue* value = | 2127 HValue* value = |
| 2125 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), | 2128 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), |
| 2126 JS_VALUE_TYPE, HAllocationMode()); | 2129 JS_VALUE_TYPE, HAllocationMode()); |
| 2127 Add<HStoreNamedField>(value, HObjectAccess::ForMap(), | 2130 Add<HStoreNamedField>(value, HObjectAccess::ForMap(), |
| 2128 constructor_initial_map); | 2131 constructor_initial_map); |
| 2129 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); | 2132 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); |
| 2130 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), | 2133 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2581 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 2584 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
| 2582 NoObservableSideEffectsScope no_effects(this); | 2585 NoObservableSideEffectsScope no_effects(this); |
| 2583 IfBuilder length_checker(this); | 2586 IfBuilder length_checker(this); |
| 2584 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2587 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
| 2585 length_checker.Then(); | 2588 length_checker.Then(); |
| 2586 IfBuilder negative_checker(this); | 2589 IfBuilder negative_checker(this); |
| 2587 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2590 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
| 2588 key, graph()->GetConstant0(), Token::GTE); | 2591 key, graph()->GetConstant0(), Token::GTE); |
| 2589 negative_checker.Then(); | 2592 negative_checker.Then(); |
| 2590 HInstruction* result = AddElementAccess( | 2593 HInstruction* result = AddElementAccess( |
| 2591 backing_store, key, val, bounds_check, elements_kind, access_type); | 2594 backing_store, key, val, bounds_check, checked_object->ActualValue(), |
| 2595 elements_kind, access_type); |
| 2592 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered); | 2596 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered); |
| 2593 negative_checker.End(); | 2597 negative_checker.End(); |
| 2594 length_checker.End(); | 2598 length_checker.End(); |
| 2595 return result; | 2599 return result; |
| 2596 } else { | 2600 } else { |
| 2597 DCHECK(store_mode == STANDARD_STORE); | 2601 DCHECK(store_mode == STANDARD_STORE); |
| 2598 checked_key = Add<HBoundsCheck>(key, length); | 2602 checked_key = Add<HBoundsCheck>(key, length); |
| 2599 return AddElementAccess( | 2603 return AddElementAccess(backing_store, checked_key, val, checked_object, |
| 2600 backing_store, checked_key, val, | 2604 checked_object->ActualValue(), elements_kind, |
| 2601 checked_object, elements_kind, access_type); | 2605 access_type); |
| 2602 } | 2606 } |
| 2603 } | 2607 } |
| 2604 DCHECK(fast_smi_only_elements || | 2608 DCHECK(fast_smi_only_elements || |
| 2605 fast_elements || | 2609 fast_elements || |
| 2606 IsFastDoubleElementsKind(elements_kind)); | 2610 IsFastDoubleElementsKind(elements_kind)); |
| 2607 | 2611 |
| 2608 // In case val is stored into a fast smi array, assure that the value is a smi | 2612 // In case val is stored into a fast smi array, assure that the value is a smi |
| 2609 // before manipulating the backing store. Otherwise the actual store may | 2613 // before manipulating the backing store. Otherwise the actual store may |
| 2610 // deopt, leaving the backing store in an invalid state. | 2614 // deopt, leaving the backing store in an invalid state. |
| 2611 if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && | 2615 if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2630 NoObservableSideEffectsScope no_effects(this); | 2634 NoObservableSideEffectsScope no_effects(this); |
| 2631 elements = BuildCopyElementsOnWrite(checked_object, elements, | 2635 elements = BuildCopyElementsOnWrite(checked_object, elements, |
| 2632 elements_kind, length); | 2636 elements_kind, length); |
| 2633 } else { | 2637 } else { |
| 2634 HCheckMaps* check_cow_map = Add<HCheckMaps>( | 2638 HCheckMaps* check_cow_map = Add<HCheckMaps>( |
| 2635 elements, isolate()->factory()->fixed_array_map()); | 2639 elements, isolate()->factory()->fixed_array_map()); |
| 2636 check_cow_map->ClearDependsOnFlag(kElementsKind); | 2640 check_cow_map->ClearDependsOnFlag(kElementsKind); |
| 2637 } | 2641 } |
| 2638 } | 2642 } |
| 2639 } | 2643 } |
| 2640 return AddElementAccess(elements, checked_key, val, checked_object, | 2644 return AddElementAccess(elements, checked_key, val, checked_object, nullptr, |
| 2641 elements_kind, access_type, load_mode); | 2645 elements_kind, access_type, load_mode); |
| 2642 } | 2646 } |
| 2643 | 2647 |
| 2644 | 2648 |
| 2645 HValue* HGraphBuilder::BuildAllocateArrayFromLength( | 2649 HValue* HGraphBuilder::BuildAllocateArrayFromLength( |
| 2646 JSArrayBuilder* array_builder, | 2650 JSArrayBuilder* array_builder, |
| 2647 HValue* length_argument) { | 2651 HValue* length_argument) { |
| 2648 if (length_argument->IsConstant() && | 2652 if (length_argument->IsConstant() && |
| 2649 HConstant::cast(length_argument)->HasSmiValue()) { | 2653 HConstant::cast(length_argument)->HasSmiValue()) { |
| 2650 int array_length = HConstant::cast(length_argument)->Integer32Value(); | 2654 int array_length = HConstant::cast(length_argument)->Integer32Value(); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2793 array, HObjectAccess::ForArrayLength(elements_kind), length_field); | 2797 array, HObjectAccess::ForArrayLength(elements_kind), length_field); |
| 2794 | 2798 |
| 2795 if (mode == TRACK_ALLOCATION_SITE) { | 2799 if (mode == TRACK_ALLOCATION_SITE) { |
| 2796 BuildCreateAllocationMemento( | 2800 BuildCreateAllocationMemento( |
| 2797 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); | 2801 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); |
| 2798 } | 2802 } |
| 2799 } | 2803 } |
| 2800 | 2804 |
| 2801 | 2805 |
| 2802 HInstruction* HGraphBuilder::AddElementAccess( | 2806 HInstruction* HGraphBuilder::AddElementAccess( |
| 2803 HValue* elements, | 2807 HValue* elements, HValue* checked_key, HValue* val, HValue* dependency, |
| 2804 HValue* checked_key, | 2808 HValue* backing_store_owner, ElementsKind elements_kind, |
| 2805 HValue* val, | 2809 PropertyAccessType access_type, LoadKeyedHoleMode load_mode) { |
| 2806 HValue* dependency, | |
| 2807 ElementsKind elements_kind, | |
| 2808 PropertyAccessType access_type, | |
| 2809 LoadKeyedHoleMode load_mode) { | |
| 2810 if (access_type == STORE) { | 2810 if (access_type == STORE) { |
| 2811 DCHECK(val != NULL); | 2811 DCHECK(val != NULL); |
| 2812 if (elements_kind == UINT8_CLAMPED_ELEMENTS) { | 2812 if (elements_kind == UINT8_CLAMPED_ELEMENTS) { |
| 2813 val = Add<HClampToUint8>(val); | 2813 val = Add<HClampToUint8>(val); |
| 2814 } | 2814 } |
| 2815 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, | 2815 return Add<HStoreKeyed>(elements, checked_key, val, backing_store_owner, |
| 2816 STORE_TO_INITIALIZED_ENTRY); | 2816 elements_kind, STORE_TO_INITIALIZED_ENTRY); |
| 2817 } | 2817 } |
| 2818 | 2818 |
| 2819 DCHECK(access_type == LOAD); | 2819 DCHECK(access_type == LOAD); |
| 2820 DCHECK(val == NULL); | 2820 DCHECK(val == NULL); |
| 2821 HLoadKeyed* load = Add<HLoadKeyed>( | 2821 HLoadKeyed* load = |
| 2822 elements, checked_key, dependency, elements_kind, load_mode); | 2822 Add<HLoadKeyed>(elements, checked_key, dependency, backing_store_owner, |
| 2823 elements_kind, load_mode); |
| 2823 if (elements_kind == UINT32_ELEMENTS) { | 2824 if (elements_kind == UINT32_ELEMENTS) { |
| 2824 graph()->RecordUint32Instruction(load); | 2825 graph()->RecordUint32Instruction(load); |
| 2825 } | 2826 } |
| 2826 return load; | 2827 return load; |
| 2827 } | 2828 } |
| 2828 | 2829 |
| 2829 | 2830 |
| 2830 HLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object, | 2831 HLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object, |
| 2831 HValue* dependency) { | 2832 HValue* dependency) { |
| 2832 return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap()); | 2833 return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2913 int constant_to = to->GetInteger32Constant(); | 2914 int constant_to = to->GetInteger32Constant(); |
| 2914 | 2915 |
| 2915 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { | 2916 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { |
| 2916 initial_capacity = constant_to; | 2917 initial_capacity = constant_to; |
| 2917 } | 2918 } |
| 2918 } | 2919 } |
| 2919 | 2920 |
| 2920 if (initial_capacity >= 0) { | 2921 if (initial_capacity >= 0) { |
| 2921 for (int i = 0; i < initial_capacity; i++) { | 2922 for (int i = 0; i < initial_capacity; i++) { |
| 2922 HInstruction* key = Add<HConstant>(i); | 2923 HInstruction* key = Add<HConstant>(i); |
| 2923 Add<HStoreKeyed>(elements, key, value, elements_kind); | 2924 Add<HStoreKeyed>(elements, key, value, nullptr, elements_kind); |
| 2924 } | 2925 } |
| 2925 } else { | 2926 } else { |
| 2926 // Carefully loop backwards so that the "from" remains live through the loop | 2927 // Carefully loop backwards so that the "from" remains live through the loop |
| 2927 // rather than the to. This often corresponds to keeping length live rather | 2928 // rather than the to. This often corresponds to keeping length live rather |
| 2928 // then capacity, which helps register allocation, since length is used more | 2929 // then capacity, which helps register allocation, since length is used more |
| 2929 // other than capacity after filling with holes. | 2930 // other than capacity after filling with holes. |
| 2930 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 2931 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 2931 | 2932 |
| 2932 HValue* key = builder.BeginBody(to, from, Token::GT); | 2933 HValue* key = builder.BeginBody(to, from, Token::GT); |
| 2933 | 2934 |
| 2934 HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 2935 HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 2935 adjusted_key->ClearFlag(HValue::kCanOverflow); | 2936 adjusted_key->ClearFlag(HValue::kCanOverflow); |
| 2936 | 2937 |
| 2937 Add<HStoreKeyed>(elements, adjusted_key, value, elements_kind); | 2938 Add<HStoreKeyed>(elements, adjusted_key, value, nullptr, elements_kind); |
| 2938 | 2939 |
| 2939 builder.EndBody(); | 2940 builder.EndBody(); |
| 2940 } | 2941 } |
| 2941 } | 2942 } |
| 2942 | 2943 |
| 2943 | 2944 |
| 2944 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements, | 2945 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements, |
| 2945 ElementsKind elements_kind, | 2946 ElementsKind elements_kind, |
| 2946 HValue* from, | 2947 HValue* from, |
| 2947 HValue* to) { | 2948 HValue* to) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2970 BuildFillElementsWithValue(to_properties, kind, length, capacity, | 2971 BuildFillElementsWithValue(to_properties, kind, length, capacity, |
| 2971 graph()->GetConstantUndefined()); | 2972 graph()->GetConstantUndefined()); |
| 2972 | 2973 |
| 2973 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 2974 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 2974 | 2975 |
| 2975 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); | 2976 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); |
| 2976 | 2977 |
| 2977 key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 2978 key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 2978 key->ClearFlag(HValue::kCanOverflow); | 2979 key->ClearFlag(HValue::kCanOverflow); |
| 2979 | 2980 |
| 2980 HValue* element = Add<HLoadKeyed>(from_properties, key, nullptr, kind); | 2981 HValue* element = |
| 2982 Add<HLoadKeyed>(from_properties, key, nullptr, nullptr, kind); |
| 2981 | 2983 |
| 2982 Add<HStoreKeyed>(to_properties, key, element, kind); | 2984 Add<HStoreKeyed>(to_properties, key, element, nullptr, kind); |
| 2983 | 2985 |
| 2984 builder.EndBody(); | 2986 builder.EndBody(); |
| 2985 } | 2987 } |
| 2986 | 2988 |
| 2987 | 2989 |
| 2988 void HGraphBuilder::BuildCopyElements(HValue* from_elements, | 2990 void HGraphBuilder::BuildCopyElements(HValue* from_elements, |
| 2989 ElementsKind from_elements_kind, | 2991 ElementsKind from_elements_kind, |
| 2990 HValue* to_elements, | 2992 HValue* to_elements, |
| 2991 ElementsKind to_elements_kind, | 2993 ElementsKind to_elements_kind, |
| 2992 HValue* length, | 2994 HValue* length, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3009 // pre-initialized with holes to make sure that it's always in a | 3011 // pre-initialized with holes to make sure that it's always in a |
| 3010 // consistent state. | 3012 // consistent state. |
| 3011 BuildFillElementsWithHole(to_elements, to_elements_kind, | 3013 BuildFillElementsWithHole(to_elements, to_elements_kind, |
| 3012 graph()->GetConstant0(), NULL); | 3014 graph()->GetConstant0(), NULL); |
| 3013 } | 3015 } |
| 3014 | 3016 |
| 3015 if (constant_capacity != -1) { | 3017 if (constant_capacity != -1) { |
| 3016 // Unroll the loop for small elements kinds. | 3018 // Unroll the loop for small elements kinds. |
| 3017 for (int i = 0; i < constant_capacity; i++) { | 3019 for (int i = 0; i < constant_capacity; i++) { |
| 3018 HValue* key_constant = Add<HConstant>(i); | 3020 HValue* key_constant = Add<HConstant>(i); |
| 3019 HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant, | 3021 HInstruction* value = Add<HLoadKeyed>( |
| 3020 nullptr, from_elements_kind); | 3022 from_elements, key_constant, nullptr, nullptr, from_elements_kind); |
| 3021 Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind); | 3023 Add<HStoreKeyed>(to_elements, key_constant, value, nullptr, |
| 3024 to_elements_kind); |
| 3022 } | 3025 } |
| 3023 } else { | 3026 } else { |
| 3024 if (!pre_fill_with_holes && | 3027 if (!pre_fill_with_holes && |
| 3025 (capacity == NULL || !length->Equals(capacity))) { | 3028 (capacity == NULL || !length->Equals(capacity))) { |
| 3026 BuildFillElementsWithHole(to_elements, to_elements_kind, | 3029 BuildFillElementsWithHole(to_elements, to_elements_kind, |
| 3027 length, NULL); | 3030 length, NULL); |
| 3028 } | 3031 } |
| 3029 | 3032 |
| 3030 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 3033 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 3031 | 3034 |
| 3032 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), | 3035 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), |
| 3033 Token::GT); | 3036 Token::GT); |
| 3034 | 3037 |
| 3035 key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 3038 key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 3036 key->ClearFlag(HValue::kCanOverflow); | 3039 key->ClearFlag(HValue::kCanOverflow); |
| 3037 | 3040 |
| 3038 HValue* element = Add<HLoadKeyed>(from_elements, key, nullptr, | 3041 HValue* element = Add<HLoadKeyed>(from_elements, key, nullptr, nullptr, |
| 3039 from_elements_kind, ALLOW_RETURN_HOLE); | 3042 from_elements_kind, ALLOW_RETURN_HOLE); |
| 3040 | 3043 |
| 3041 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && | 3044 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && |
| 3042 IsFastSmiElementsKind(to_elements_kind)) | 3045 IsFastSmiElementsKind(to_elements_kind)) |
| 3043 ? FAST_HOLEY_ELEMENTS : to_elements_kind; | 3046 ? FAST_HOLEY_ELEMENTS : to_elements_kind; |
| 3044 | 3047 |
| 3045 if (IsHoleyElementsKind(from_elements_kind) && | 3048 if (IsHoleyElementsKind(from_elements_kind) && |
| 3046 from_elements_kind != to_elements_kind) { | 3049 from_elements_kind != to_elements_kind) { |
| 3047 IfBuilder if_hole(this); | 3050 IfBuilder if_hole(this); |
| 3048 if_hole.If<HCompareHoleAndBranch>(element); | 3051 if_hole.If<HCompareHoleAndBranch>(element); |
| 3049 if_hole.Then(); | 3052 if_hole.Then(); |
| 3050 HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) | 3053 HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) |
| 3051 ? Add<HConstant>(HConstant::kHoleNaN) | 3054 ? Add<HConstant>(HConstant::kHoleNaN) |
| 3052 : graph()->GetConstantHole(); | 3055 : graph()->GetConstantHole(); |
| 3053 Add<HStoreKeyed>(to_elements, key, hole_constant, kind); | 3056 Add<HStoreKeyed>(to_elements, key, hole_constant, nullptr, kind); |
| 3054 if_hole.Else(); | 3057 if_hole.Else(); |
| 3055 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); | 3058 HStoreKeyed* store = |
| 3059 Add<HStoreKeyed>(to_elements, key, element, nullptr, kind); |
| 3056 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 3060 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 3057 if_hole.End(); | 3061 if_hole.End(); |
| 3058 } else { | 3062 } else { |
| 3059 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); | 3063 HStoreKeyed* store = |
| 3064 Add<HStoreKeyed>(to_elements, key, element, nullptr, kind); |
| 3060 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 3065 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 3061 } | 3066 } |
| 3062 | 3067 |
| 3063 builder.EndBody(); | 3068 builder.EndBody(); |
| 3064 } | 3069 } |
| 3065 | 3070 |
| 3066 Counters* counters = isolate()->counters(); | 3071 Counters* counters = isolate()->counters(); |
| 3067 AddIncrementCounter(counters->inlined_copied_elements()); | 3072 AddIncrementCounter(counters->inlined_copied_elements()); |
| 3068 } | 3073 } |
| 3069 | 3074 |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3329 } | 3334 } |
| 3330 } | 3335 } |
| 3331 return script_context; | 3336 return script_context; |
| 3332 } | 3337 } |
| 3333 | 3338 |
| 3334 | 3339 |
| 3335 HInstruction* HGraphBuilder::BuildGetArrayFunction() { | 3340 HInstruction* HGraphBuilder::BuildGetArrayFunction() { |
| 3336 HInstruction* native_context = BuildGetNativeContext(); | 3341 HInstruction* native_context = BuildGetNativeContext(); |
| 3337 HInstruction* index = | 3342 HInstruction* index = |
| 3338 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); | 3343 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); |
| 3339 return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); | 3344 return Add<HLoadKeyed>(native_context, index, nullptr, nullptr, |
| 3345 FAST_ELEMENTS); |
| 3340 } | 3346 } |
| 3341 | 3347 |
| 3342 | 3348 |
| 3343 HValue* HGraphBuilder::BuildArrayBufferViewFieldAccessor(HValue* object, | 3349 HValue* HGraphBuilder::BuildArrayBufferViewFieldAccessor(HValue* object, |
| 3344 HValue* checked_object, | 3350 HValue* checked_object, |
| 3345 FieldIndex index) { | 3351 FieldIndex index) { |
| 3346 NoObservableSideEffectsScope scope(this); | 3352 NoObservableSideEffectsScope scope(this); |
| 3347 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( | 3353 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( |
| 3348 index.offset(), Representation::Tagged()); | 3354 index.offset(), Representation::Tagged()); |
| 3349 HInstruction* buffer = Add<HLoadNamedField>( | 3355 HInstruction* buffer = Add<HLoadNamedField>( |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3417 | 3423 |
| 3418 // TODO(mvstanton): we should always have a constructor function if we | 3424 // TODO(mvstanton): we should always have a constructor function if we |
| 3419 // are creating a stub. | 3425 // are creating a stub. |
| 3420 HInstruction* native_context = constructor_function_ != NULL | 3426 HInstruction* native_context = constructor_function_ != NULL |
| 3421 ? builder()->BuildGetNativeContext(constructor_function_) | 3427 ? builder()->BuildGetNativeContext(constructor_function_) |
| 3422 : builder()->BuildGetNativeContext(); | 3428 : builder()->BuildGetNativeContext(); |
| 3423 | 3429 |
| 3424 HInstruction* index = builder()->Add<HConstant>( | 3430 HInstruction* index = builder()->Add<HConstant>( |
| 3425 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); | 3431 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
| 3426 | 3432 |
| 3427 HInstruction* map_array = | 3433 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
| 3428 builder()->Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); | 3434 native_context, index, nullptr, nullptr, FAST_ELEMENTS); |
| 3429 | 3435 |
| 3430 HInstruction* kind_index = builder()->Add<HConstant>(kind_); | 3436 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
| 3431 | 3437 |
| 3432 return builder()->Add<HLoadKeyed>(map_array, kind_index, nullptr, | 3438 return builder()->Add<HLoadKeyed>(map_array, kind_index, nullptr, nullptr, |
| 3433 FAST_ELEMENTS); | 3439 FAST_ELEMENTS); |
| 3434 } | 3440 } |
| 3435 | 3441 |
| 3436 | 3442 |
| 3437 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 3443 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 3438 // Find the map near the constructor function | 3444 // Find the map near the constructor function |
| 3439 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 3445 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 3440 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, | 3446 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, |
| 3441 access); | 3447 access); |
| 3442 } | 3448 } |
| (...skipping 1929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5372 compare_index->SetSuccessorAt(1, loop_successor); | 5378 compare_index->SetSuccessorAt(1, loop_successor); |
| 5373 FinishCurrentBlock(compare_index); | 5379 FinishCurrentBlock(compare_index); |
| 5374 | 5380 |
| 5375 set_current_block(loop_successor); | 5381 set_current_block(loop_successor); |
| 5376 Drop(5); | 5382 Drop(5); |
| 5377 | 5383 |
| 5378 set_current_block(loop_body); | 5384 set_current_block(loop_body); |
| 5379 | 5385 |
| 5380 HValue* key = | 5386 HValue* key = |
| 5381 Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache. | 5387 Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache. |
| 5382 index, index, FAST_ELEMENTS); | 5388 index, index, nullptr, FAST_ELEMENTS); |
| 5383 | 5389 |
| 5384 if (fast) { | 5390 if (fast) { |
| 5385 // Check if the expected map still matches that of the enumerable. | 5391 // Check if the expected map still matches that of the enumerable. |
| 5386 // If not just deoptimize. | 5392 // If not just deoptimize. |
| 5387 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3)); | 5393 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3)); |
| 5388 Bind(each_var, key); | 5394 Bind(each_var, key); |
| 5389 } else { | 5395 } else { |
| 5390 Add<HPushArguments>(enumerable, key); | 5396 Add<HPushArguments>(enumerable, key); |
| 5391 Runtime::FunctionId function_id = Runtime::kForInFilter; | 5397 Runtime::FunctionId function_id = Runtime::kForInFilter; |
| 5392 key = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2); | 5398 key = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2); |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6080 | 6086 |
| 6081 HValue* key = Add<HConstant>(i); | 6087 HValue* key = Add<HConstant>(i); |
| 6082 | 6088 |
| 6083 switch (boilerplate_elements_kind) { | 6089 switch (boilerplate_elements_kind) { |
| 6084 case FAST_SMI_ELEMENTS: | 6090 case FAST_SMI_ELEMENTS: |
| 6085 case FAST_HOLEY_SMI_ELEMENTS: | 6091 case FAST_HOLEY_SMI_ELEMENTS: |
| 6086 case FAST_ELEMENTS: | 6092 case FAST_ELEMENTS: |
| 6087 case FAST_HOLEY_ELEMENTS: | 6093 case FAST_HOLEY_ELEMENTS: |
| 6088 case FAST_DOUBLE_ELEMENTS: | 6094 case FAST_DOUBLE_ELEMENTS: |
| 6089 case FAST_HOLEY_DOUBLE_ELEMENTS: { | 6095 case FAST_HOLEY_DOUBLE_ELEMENTS: { |
| 6090 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, | 6096 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, nullptr, |
| 6091 boilerplate_elements_kind); | 6097 boilerplate_elements_kind); |
| 6092 instr->SetUninitialized(uninitialized); | 6098 instr->SetUninitialized(uninitialized); |
| 6093 break; | 6099 break; |
| 6094 } | 6100 } |
| 6095 default: | 6101 default: |
| 6096 UNREACHABLE(); | 6102 UNREACHABLE(); |
| 6097 break; | 6103 break; |
| 6098 } | 6104 } |
| 6099 | 6105 |
| 6100 Add<HSimulate>(expr->GetIdForElement(i)); | 6106 Add<HSimulate>(expr->GetIdForElement(i)); |
| (...skipping 2742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8843 if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); | 8849 if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); |
| 8844 | 8850 |
| 8845 length_checker.Else(); | 8851 length_checker.Else(); |
| 8846 HValue* elements = AddLoadElements(checked_object); | 8852 HValue* elements = AddLoadElements(checked_object); |
| 8847 // Ensure that we aren't popping from a copy-on-write array. | 8853 // Ensure that we aren't popping from a copy-on-write array. |
| 8848 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 8854 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 8849 elements = BuildCopyElementsOnWrite(checked_object, elements, | 8855 elements = BuildCopyElementsOnWrite(checked_object, elements, |
| 8850 elements_kind, length); | 8856 elements_kind, length); |
| 8851 } | 8857 } |
| 8852 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); | 8858 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); |
| 8853 result = AddElementAccess(elements, reduced_length, NULL, | 8859 result = AddElementAccess(elements, reduced_length, nullptr, |
| 8854 bounds_check, elements_kind, LOAD); | 8860 bounds_check, nullptr, elements_kind, LOAD); |
| 8855 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 8861 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
| 8856 ? graph()->GetConstantHole() | 8862 ? graph()->GetConstantHole() |
| 8857 : Add<HConstant>(HConstant::kHoleNaN); | 8863 : Add<HConstant>(HConstant::kHoleNaN); |
| 8858 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 8864 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 8859 elements_kind = FAST_HOLEY_ELEMENTS; | 8865 elements_kind = FAST_HOLEY_ELEMENTS; |
| 8860 } | 8866 } |
| 8861 AddElementAccess( | 8867 AddElementAccess(elements, reduced_length, hole, bounds_check, nullptr, |
| 8862 elements, reduced_length, hole, bounds_check, elements_kind, STORE); | 8868 elements_kind, STORE); |
| 8863 Add<HStoreNamedField>( | 8869 Add<HStoreNamedField>( |
| 8864 checked_object, HObjectAccess::ForArrayLength(elements_kind), | 8870 checked_object, HObjectAccess::ForArrayLength(elements_kind), |
| 8865 reduced_length, STORE_TO_INITIALIZED_ENTRY); | 8871 reduced_length, STORE_TO_INITIALIZED_ENTRY); |
| 8866 | 8872 |
| 8867 if (!ast_context()->IsEffect()) Push(result); | 8873 if (!ast_context()->IsEffect()) Push(result); |
| 8868 | 8874 |
| 8869 length_checker.End(); | 8875 length_checker.End(); |
| 8870 } | 8876 } |
| 8871 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); | 8877 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); |
| 8872 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8878 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8977 length, inline_threshold, Token::LTE); | 8983 length, inline_threshold, Token::LTE); |
| 8978 if (IsFastSmiOrObjectElementsKind(kind)) { | 8984 if (IsFastSmiOrObjectElementsKind(kind)) { |
| 8979 // We cannot handle copy-on-write backing stores here. | 8985 // We cannot handle copy-on-write backing stores here. |
| 8980 if_inline.AndIf<HCompareMap>( | 8986 if_inline.AndIf<HCompareMap>( |
| 8981 elements, isolate()->factory()->fixed_array_map()); | 8987 elements, isolate()->factory()->fixed_array_map()); |
| 8982 } | 8988 } |
| 8983 if_inline.Then(); | 8989 if_inline.Then(); |
| 8984 { | 8990 { |
| 8985 // Remember the result. | 8991 // Remember the result. |
| 8986 if (!ast_context()->IsEffect()) { | 8992 if (!ast_context()->IsEffect()) { |
| 8987 Push(AddElementAccess(elements, graph()->GetConstant0(), NULL, | 8993 Push(AddElementAccess(elements, graph()->GetConstant0(), nullptr, |
| 8988 lengthiszero, kind, LOAD)); | 8994 lengthiszero, nullptr, kind, LOAD)); |
| 8989 } | 8995 } |
| 8990 | 8996 |
| 8991 // Compute the new length. | 8997 // Compute the new length. |
| 8992 HValue* new_length = AddUncasted<HSub>( | 8998 HValue* new_length = AddUncasted<HSub>( |
| 8993 length, graph()->GetConstant1()); | 8999 length, graph()->GetConstant1()); |
| 8994 new_length->ClearFlag(HValue::kCanOverflow); | 9000 new_length->ClearFlag(HValue::kCanOverflow); |
| 8995 | 9001 |
| 8996 // Copy the remaining elements. | 9002 // Copy the remaining elements. |
| 8997 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); | 9003 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); |
| 8998 { | 9004 { |
| 8999 HValue* new_key = loop.BeginBody( | 9005 HValue* new_key = loop.BeginBody( |
| 9000 graph()->GetConstant0(), new_length, Token::LT); | 9006 graph()->GetConstant0(), new_length, Token::LT); |
| 9001 HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); | 9007 HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); |
| 9002 key->ClearFlag(HValue::kCanOverflow); | 9008 key->ClearFlag(HValue::kCanOverflow); |
| 9003 ElementsKind copy_kind = | 9009 ElementsKind copy_kind = |
| 9004 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; | 9010 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; |
| 9005 HValue* element = AddUncasted<HLoadKeyed>( | 9011 HValue* element = |
| 9006 elements, key, lengthiszero, copy_kind, ALLOW_RETURN_HOLE); | 9012 AddUncasted<HLoadKeyed>(elements, key, lengthiszero, nullptr, |
| 9007 HStoreKeyed* store = | 9013 copy_kind, ALLOW_RETURN_HOLE); |
| 9008 Add<HStoreKeyed>(elements, new_key, element, copy_kind); | 9014 HStoreKeyed* store = Add<HStoreKeyed>(elements, new_key, element, |
| 9015 nullptr, copy_kind); |
| 9009 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 9016 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 9010 } | 9017 } |
| 9011 loop.EndBody(); | 9018 loop.EndBody(); |
| 9012 | 9019 |
| 9013 // Put a hole at the end. | 9020 // Put a hole at the end. |
| 9014 HValue* hole = IsFastSmiOrObjectElementsKind(kind) | 9021 HValue* hole = IsFastSmiOrObjectElementsKind(kind) |
| 9015 ? graph()->GetConstantHole() | 9022 ? graph()->GetConstantHole() |
| 9016 : Add<HConstant>(HConstant::kHoleNaN); | 9023 : Add<HConstant>(HConstant::kHoleNaN); |
| 9017 if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; | 9024 if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; |
| 9018 Add<HStoreKeyed>( | 9025 Add<HStoreKeyed>(elements, new_length, hole, nullptr, kind, |
| 9019 elements, new_length, hole, kind, INITIALIZING_STORE); | 9026 INITIALIZING_STORE); |
| 9020 | 9027 |
| 9021 // Remember new length. | 9028 // Remember new length. |
| 9022 Add<HStoreNamedField>( | 9029 Add<HStoreNamedField>( |
| 9023 receiver, HObjectAccess::ForArrayLength(kind), | 9030 receiver, HObjectAccess::ForArrayLength(kind), |
| 9024 new_length, STORE_TO_INITIALIZED_ENTRY); | 9031 new_length, STORE_TO_INITIALIZED_ENTRY); |
| 9025 } | 9032 } |
| 9026 if_inline.Else(); | 9033 if_inline.Else(); |
| 9027 { | 9034 { |
| 9028 Add<HPushArguments>(receiver); | 9035 Add<HPushArguments>(receiver); |
| 9029 result = Add<HCallJSFunction>(function, 1); | 9036 result = Add<HCallJSFunction>(function, 1); |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9471 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { | 9478 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { |
| 9472 // Make sure that we can actually compare numbers correctly below, see | 9479 // Make sure that we can actually compare numbers correctly below, see |
| 9473 // https://code.google.com/p/chromium/issues/detail?id=407946 for details. | 9480 // https://code.google.com/p/chromium/issues/detail?id=407946 for details. |
| 9474 search_element = AddUncasted<HForceRepresentation>( | 9481 search_element = AddUncasted<HForceRepresentation>( |
| 9475 search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() | 9482 search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() |
| 9476 : Representation::Double()); | 9483 : Representation::Double()); |
| 9477 | 9484 |
| 9478 LoopBuilder loop(this, context(), direction); | 9485 LoopBuilder loop(this, context(), direction); |
| 9479 { | 9486 { |
| 9480 HValue* index = loop.BeginBody(initial, terminating, token); | 9487 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9481 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, kind, | 9488 HValue* element = AddUncasted<HLoadKeyed>( |
| 9482 ALLOW_RETURN_HOLE); | 9489 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9483 IfBuilder if_issame(this); | 9490 IfBuilder if_issame(this); |
| 9484 if_issame.If<HCompareNumericAndBranch>(element, search_element, | 9491 if_issame.If<HCompareNumericAndBranch>(element, search_element, |
| 9485 Token::EQ_STRICT); | 9492 Token::EQ_STRICT); |
| 9486 if_issame.Then(); | 9493 if_issame.Then(); |
| 9487 { | 9494 { |
| 9488 Drop(1); | 9495 Drop(1); |
| 9489 Push(index); | 9496 Push(index); |
| 9490 loop.Break(); | 9497 loop.Break(); |
| 9491 } | 9498 } |
| 9492 if_issame.End(); | 9499 if_issame.End(); |
| 9493 } | 9500 } |
| 9494 loop.EndBody(); | 9501 loop.EndBody(); |
| 9495 } else { | 9502 } else { |
| 9496 IfBuilder if_isstring(this); | 9503 IfBuilder if_isstring(this); |
| 9497 if_isstring.If<HIsStringAndBranch>(search_element); | 9504 if_isstring.If<HIsStringAndBranch>(search_element); |
| 9498 if_isstring.Then(); | 9505 if_isstring.Then(); |
| 9499 { | 9506 { |
| 9500 LoopBuilder loop(this, context(), direction); | 9507 LoopBuilder loop(this, context(), direction); |
| 9501 { | 9508 { |
| 9502 HValue* index = loop.BeginBody(initial, terminating, token); | 9509 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9503 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, | 9510 HValue* element = AddUncasted<HLoadKeyed>( |
| 9504 kind, ALLOW_RETURN_HOLE); | 9511 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9505 IfBuilder if_issame(this); | 9512 IfBuilder if_issame(this); |
| 9506 if_issame.If<HIsStringAndBranch>(element); | 9513 if_issame.If<HIsStringAndBranch>(element); |
| 9507 if_issame.AndIf<HStringCompareAndBranch>( | 9514 if_issame.AndIf<HStringCompareAndBranch>( |
| 9508 element, search_element, Token::EQ_STRICT); | 9515 element, search_element, Token::EQ_STRICT); |
| 9509 if_issame.Then(); | 9516 if_issame.Then(); |
| 9510 { | 9517 { |
| 9511 Drop(1); | 9518 Drop(1); |
| 9512 Push(index); | 9519 Push(index); |
| 9513 loop.Break(); | 9520 loop.Break(); |
| 9514 } | 9521 } |
| 9515 if_issame.End(); | 9522 if_issame.End(); |
| 9516 } | 9523 } |
| 9517 loop.EndBody(); | 9524 loop.EndBody(); |
| 9518 } | 9525 } |
| 9519 if_isstring.Else(); | 9526 if_isstring.Else(); |
| 9520 { | 9527 { |
| 9521 IfBuilder if_isnumber(this); | 9528 IfBuilder if_isnumber(this); |
| 9522 if_isnumber.If<HIsSmiAndBranch>(search_element); | 9529 if_isnumber.If<HIsSmiAndBranch>(search_element); |
| 9523 if_isnumber.OrIf<HCompareMap>( | 9530 if_isnumber.OrIf<HCompareMap>( |
| 9524 search_element, isolate()->factory()->heap_number_map()); | 9531 search_element, isolate()->factory()->heap_number_map()); |
| 9525 if_isnumber.Then(); | 9532 if_isnumber.Then(); |
| 9526 { | 9533 { |
| 9527 HValue* search_number = | 9534 HValue* search_number = |
| 9528 AddUncasted<HForceRepresentation>(search_element, | 9535 AddUncasted<HForceRepresentation>(search_element, |
| 9529 Representation::Double()); | 9536 Representation::Double()); |
| 9530 LoopBuilder loop(this, context(), direction); | 9537 LoopBuilder loop(this, context(), direction); |
| 9531 { | 9538 { |
| 9532 HValue* index = loop.BeginBody(initial, terminating, token); | 9539 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9533 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, | 9540 HValue* element = AddUncasted<HLoadKeyed>( |
| 9534 kind, ALLOW_RETURN_HOLE); | 9541 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9535 | 9542 |
| 9536 IfBuilder if_element_isnumber(this); | 9543 IfBuilder if_element_isnumber(this); |
| 9537 if_element_isnumber.If<HIsSmiAndBranch>(element); | 9544 if_element_isnumber.If<HIsSmiAndBranch>(element); |
| 9538 if_element_isnumber.OrIf<HCompareMap>( | 9545 if_element_isnumber.OrIf<HCompareMap>( |
| 9539 element, isolate()->factory()->heap_number_map()); | 9546 element, isolate()->factory()->heap_number_map()); |
| 9540 if_element_isnumber.Then(); | 9547 if_element_isnumber.Then(); |
| 9541 { | 9548 { |
| 9542 HValue* number = | 9549 HValue* number = |
| 9543 AddUncasted<HForceRepresentation>(element, | 9550 AddUncasted<HForceRepresentation>(element, |
| 9544 Representation::Double()); | 9551 Representation::Double()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9555 } | 9562 } |
| 9556 if_element_isnumber.End(); | 9563 if_element_isnumber.End(); |
| 9557 } | 9564 } |
| 9558 loop.EndBody(); | 9565 loop.EndBody(); |
| 9559 } | 9566 } |
| 9560 if_isnumber.Else(); | 9567 if_isnumber.Else(); |
| 9561 { | 9568 { |
| 9562 LoopBuilder loop(this, context(), direction); | 9569 LoopBuilder loop(this, context(), direction); |
| 9563 { | 9570 { |
| 9564 HValue* index = loop.BeginBody(initial, terminating, token); | 9571 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9565 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, | 9572 HValue* element = AddUncasted<HLoadKeyed>( |
| 9566 kind, ALLOW_RETURN_HOLE); | 9573 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9567 IfBuilder if_issame(this); | 9574 IfBuilder if_issame(this); |
| 9568 if_issame.If<HCompareObjectEqAndBranch>( | 9575 if_issame.If<HCompareObjectEqAndBranch>( |
| 9569 element, search_element); | 9576 element, search_element); |
| 9570 if_issame.Then(); | 9577 if_issame.Then(); |
| 9571 { | 9578 { |
| 9572 Drop(1); | 9579 Drop(1); |
| 9573 Push(index); | 9580 Push(index); |
| 9574 loop.Break(); | 9581 loop.Break(); |
| 9575 } | 9582 } |
| 9576 if_issame.End(); | 9583 if_issame.End(); |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10212 if (initialize) { | 10219 if (initialize) { |
| 10213 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); | 10220 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
| 10214 | 10221 |
| 10215 HValue* backing_store = AddUncasted<HAdd>( | 10222 HValue* backing_store = AddUncasted<HAdd>( |
| 10216 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset()), | 10223 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset()), |
| 10217 elements, Strength::WEAK, AddOfExternalAndTagged); | 10224 elements, Strength::WEAK, AddOfExternalAndTagged); |
| 10218 | 10225 |
| 10219 HValue* key = builder.BeginBody( | 10226 HValue* key = builder.BeginBody( |
| 10220 Add<HConstant>(static_cast<int32_t>(0)), | 10227 Add<HConstant>(static_cast<int32_t>(0)), |
| 10221 length, Token::LT); | 10228 length, Token::LT); |
| 10222 Add<HStoreKeyed>(backing_store, key, filler, fixed_elements_kind); | 10229 Add<HStoreKeyed>(backing_store, key, filler, elements, fixed_elements_kind); |
| 10223 | 10230 |
| 10224 builder.EndBody(); | 10231 builder.EndBody(); |
| 10225 } | 10232 } |
| 10226 return elements; | 10233 return elements; |
| 10227 } | 10234 } |
| 10228 | 10235 |
| 10229 | 10236 |
| 10230 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( | 10237 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( |
| 10231 CallRuntime* expr) { | 10238 CallRuntime* expr) { |
| 10232 ZoneList<Expression*>* arguments = expr->arguments(); | 10239 ZoneList<Expression*>* arguments = expr->arguments(); |
| (...skipping 1722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11955 | 11962 |
| 11956 | 11963 |
| 11957 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 11964 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
| 11958 Handle<FixedArrayBase> elements, | 11965 Handle<FixedArrayBase> elements, |
| 11959 ElementsKind kind, | 11966 ElementsKind kind, |
| 11960 HValue* object_elements) { | 11967 HValue* object_elements) { |
| 11961 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 11968 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 11962 int elements_length = elements->length(); | 11969 int elements_length = elements->length(); |
| 11963 for (int i = 0; i < elements_length; i++) { | 11970 for (int i = 0; i < elements_length; i++) { |
| 11964 HValue* key_constant = Add<HConstant>(i); | 11971 HValue* key_constant = Add<HConstant>(i); |
| 11965 HInstruction* value_instruction = Add<HLoadKeyed>( | 11972 HInstruction* value_instruction = |
| 11966 boilerplate_elements, key_constant, nullptr, kind, ALLOW_RETURN_HOLE); | 11973 Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, nullptr, |
| 11974 kind, ALLOW_RETURN_HOLE); |
| 11967 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, | 11975 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 11968 value_instruction, kind); | 11976 value_instruction, nullptr, kind); |
| 11969 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 11977 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 11970 } | 11978 } |
| 11971 } | 11979 } |
| 11972 | 11980 |
| 11973 | 11981 |
| 11974 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 11982 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 11975 Handle<FixedArrayBase> elements, | 11983 Handle<FixedArrayBase> elements, |
| 11976 ElementsKind kind, | 11984 ElementsKind kind, |
| 11977 HValue* object_elements, | 11985 HValue* object_elements, |
| 11978 AllocationSiteUsageContext* site_context) { | 11986 AllocationSiteUsageContext* site_context) { |
| 11979 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 11987 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 11980 int elements_length = elements->length(); | 11988 int elements_length = elements->length(); |
| 11981 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 11989 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 11982 for (int i = 0; i < elements_length; i++) { | 11990 for (int i = 0; i < elements_length; i++) { |
| 11983 Handle<Object> value(fast_elements->get(i), isolate()); | 11991 Handle<Object> value(fast_elements->get(i), isolate()); |
| 11984 HValue* key_constant = Add<HConstant>(i); | 11992 HValue* key_constant = Add<HConstant>(i); |
| 11985 if (value->IsJSObject()) { | 11993 if (value->IsJSObject()) { |
| 11986 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 11994 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 11987 Handle<AllocationSite> current_site = site_context->EnterNewScope(); | 11995 Handle<AllocationSite> current_site = site_context->EnterNewScope(); |
| 11988 HInstruction* result = | 11996 HInstruction* result = |
| 11989 BuildFastLiteral(value_object, site_context); | 11997 BuildFastLiteral(value_object, site_context); |
| 11990 site_context->ExitScope(current_site, value_object); | 11998 site_context->ExitScope(current_site, value_object); |
| 11991 Add<HStoreKeyed>(object_elements, key_constant, result, kind); | 11999 Add<HStoreKeyed>(object_elements, key_constant, result, nullptr, kind); |
| 11992 } else { | 12000 } else { |
| 11993 ElementsKind copy_kind = | 12001 ElementsKind copy_kind = |
| 11994 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; | 12002 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; |
| 11995 HInstruction* value_instruction = | 12003 HInstruction* value_instruction = |
| 11996 Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, | 12004 Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, nullptr, |
| 11997 copy_kind, ALLOW_RETURN_HOLE); | 12005 copy_kind, ALLOW_RETURN_HOLE); |
| 11998 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, | 12006 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, |
| 11999 copy_kind); | 12007 nullptr, copy_kind); |
| 12000 } | 12008 } |
| 12001 } | 12009 } |
| 12002 } | 12010 } |
| 12003 | 12011 |
| 12004 | 12012 |
| 12005 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 12013 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 12006 DCHECK(!HasStackOverflow()); | 12014 DCHECK(!HasStackOverflow()); |
| 12007 DCHECK(current_block() != NULL); | 12015 DCHECK(current_block() != NULL); |
| 12008 DCHECK(current_block()->HasPredecessor()); | 12016 DCHECK(current_block()->HasPredecessor()); |
| 12009 HInstruction* instr = BuildThisFunction(); | 12017 HInstruction* instr = BuildThisFunction(); |
| (...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12762 } | 12770 } |
| 12763 | 12771 |
| 12764 | 12772 |
| 12765 void HOptimizedGraphBuilder::GenerateFixedArrayGet(CallRuntime* call) { | 12773 void HOptimizedGraphBuilder::GenerateFixedArrayGet(CallRuntime* call) { |
| 12766 DCHECK(call->arguments()->length() == 2); | 12774 DCHECK(call->arguments()->length() == 2); |
| 12767 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12775 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12768 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12776 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 12769 HValue* index = Pop(); | 12777 HValue* index = Pop(); |
| 12770 HValue* object = Pop(); | 12778 HValue* object = Pop(); |
| 12771 HInstruction* result = New<HLoadKeyed>( | 12779 HInstruction* result = New<HLoadKeyed>( |
| 12772 object, index, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); | 12780 object, index, nullptr, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); |
| 12773 return ast_context()->ReturnInstruction(result, call->id()); | 12781 return ast_context()->ReturnInstruction(result, call->id()); |
| 12774 } | 12782 } |
| 12775 | 12783 |
| 12776 | 12784 |
| 12777 void HOptimizedGraphBuilder::GenerateFixedArraySet(CallRuntime* call) { | 12785 void HOptimizedGraphBuilder::GenerateFixedArraySet(CallRuntime* call) { |
| 12778 DCHECK(call->arguments()->length() == 3); | 12786 DCHECK(call->arguments()->length() == 3); |
| 12779 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12787 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12780 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12788 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 12781 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); | 12789 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); |
| 12782 HValue* value = Pop(); | 12790 HValue* value = Pop(); |
| 12783 HValue* index = Pop(); | 12791 HValue* index = Pop(); |
| 12784 HValue* object = Pop(); | 12792 HValue* object = Pop(); |
| 12785 NoObservableSideEffectsScope no_effects(this); | 12793 NoObservableSideEffectsScope no_effects(this); |
| 12786 Add<HStoreKeyed>(object, index, value, FAST_HOLEY_ELEMENTS); | 12794 Add<HStoreKeyed>(object, index, value, nullptr, FAST_HOLEY_ELEMENTS); |
| 12787 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 12795 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
| 12788 } | 12796 } |
| 12789 | 12797 |
| 12790 | 12798 |
| 12791 void HOptimizedGraphBuilder::GenerateTheHole(CallRuntime* call) { | 12799 void HOptimizedGraphBuilder::GenerateTheHole(CallRuntime* call) { |
| 12792 DCHECK(call->arguments()->length() == 0); | 12800 DCHECK(call->arguments()->length() == 0); |
| 12793 return ast_context()->ReturnValue(graph()->GetConstantHole()); | 12801 return ast_context()->ReturnValue(graph()->GetConstantHole()); |
| 12794 } | 12802 } |
| 12795 | 12803 |
| 12796 | 12804 |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13612 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13620 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13613 } | 13621 } |
| 13614 | 13622 |
| 13615 #ifdef DEBUG | 13623 #ifdef DEBUG |
| 13616 graph_->Verify(false); // No full verify. | 13624 graph_->Verify(false); // No full verify. |
| 13617 #endif | 13625 #endif |
| 13618 } | 13626 } |
| 13619 | 13627 |
| 13620 } // namespace internal | 13628 } // namespace internal |
| 13621 } // namespace v8 | 13629 } // namespace v8 |
| OLD | NEW |