| 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-numbering.h" | 10 #include "src/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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1940 IfBuilder if_objectissmi(this); | 1942 IfBuilder if_objectissmi(this); |
| 1941 if_objectissmi.If<HIsSmiAndBranch>(object); | 1943 if_objectissmi.If<HIsSmiAndBranch>(object); |
| 1942 if_objectissmi.Then(); | 1944 if_objectissmi.Then(); |
| 1943 { | 1945 { |
| 1944 // Compute hash for smi similar to smi_get_hash(). | 1946 // Compute hash for smi similar to smi_get_hash(). |
| 1945 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); | 1947 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); |
| 1946 | 1948 |
| 1947 // Load the key. | 1949 // Load the key. |
| 1948 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); | 1950 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); |
| 1949 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, | 1951 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, |
| 1950 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 1952 nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 1951 | 1953 |
| 1952 // Check if object == key. | 1954 // Check if object == key. |
| 1953 IfBuilder if_objectiskey(this); | 1955 IfBuilder if_objectiskey(this); |
| 1954 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); | 1956 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); |
| 1955 if_objectiskey.Then(); | 1957 if_objectiskey.Then(); |
| 1956 { | 1958 { |
| 1957 // Make the key_index available. | 1959 // Make the key_index available. |
| 1958 Push(key_index); | 1960 Push(key_index); |
| 1959 } | 1961 } |
| 1960 if_objectiskey.JoinContinuation(&found); | 1962 if_objectiskey.JoinContinuation(&found); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1975 object, objectisnumber, | 1977 object, objectisnumber, |
| 1976 HObjectAccess::ForHeapNumberValueLowestBits()); | 1978 HObjectAccess::ForHeapNumberValueLowestBits()); |
| 1977 HValue* high = Add<HLoadNamedField>( | 1979 HValue* high = Add<HLoadNamedField>( |
| 1978 object, objectisnumber, | 1980 object, objectisnumber, |
| 1979 HObjectAccess::ForHeapNumberValueHighestBits()); | 1981 HObjectAccess::ForHeapNumberValueHighestBits()); |
| 1980 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); | 1982 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); |
| 1981 hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); | 1983 hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); |
| 1982 | 1984 |
| 1983 // Load the key. | 1985 // Load the key. |
| 1984 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); | 1986 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); |
| 1985 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, | 1987 HValue* key = |
| 1986 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 1988 Add<HLoadKeyed>(number_string_cache, key_index, nullptr, nullptr, |
| 1989 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 1987 | 1990 |
| 1988 // Check if the key is a heap number and compare it with the object. | 1991 // Check if the key is a heap number and compare it with the object. |
| 1989 IfBuilder if_keyisnotsmi(this); | 1992 IfBuilder if_keyisnotsmi(this); |
| 1990 HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); | 1993 HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); |
| 1991 if_keyisnotsmi.Then(); | 1994 if_keyisnotsmi.Then(); |
| 1992 { | 1995 { |
| 1993 IfBuilder if_keyisheapnumber(this); | 1996 IfBuilder if_keyisheapnumber(this); |
| 1994 if_keyisheapnumber.If<HCompareMap>( | 1997 if_keyisheapnumber.If<HCompareMap>( |
| 1995 key, isolate()->factory()->heap_number_map()); | 1998 key, isolate()->factory()->heap_number_map()); |
| 1996 if_keyisheapnumber.Then(); | 1999 if_keyisheapnumber.Then(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 // Check for cache hit. | 2031 // Check for cache hit. |
| 2029 IfBuilder if_found(this, &found); | 2032 IfBuilder if_found(this, &found); |
| 2030 if_found.Then(); | 2033 if_found.Then(); |
| 2031 { | 2034 { |
| 2032 // Count number to string operation in native code. | 2035 // Count number to string operation in native code. |
| 2033 AddIncrementCounter(isolate()->counters()->number_to_string_native()); | 2036 AddIncrementCounter(isolate()->counters()->number_to_string_native()); |
| 2034 | 2037 |
| 2035 // Load the value in case of cache hit. | 2038 // Load the value in case of cache hit. |
| 2036 HValue* key_index = Pop(); | 2039 HValue* key_index = Pop(); |
| 2037 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); | 2040 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); |
| 2038 Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, | 2041 Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, nullptr, |
| 2039 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); | 2042 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); |
| 2040 } | 2043 } |
| 2041 if_found.Else(); | 2044 if_found.Else(); |
| 2042 { | 2045 { |
| 2043 // Cache miss, fallback to runtime. | 2046 // Cache miss, fallback to runtime. |
| 2044 Add<HPushArguments>(object); | 2047 Add<HPushArguments>(object); |
| 2045 Push(Add<HCallRuntime>( | 2048 Push(Add<HCallRuntime>( |
| 2046 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), | 2049 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), |
| 2047 1)); | 2050 1)); |
| 2048 } | 2051 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2112 if_wrap.Then(); | 2115 if_wrap.Then(); |
| 2113 { | 2116 { |
| 2114 // Grab the constructor function index. | 2117 // Grab the constructor function index. |
| 2115 HValue* constructor_index = Pop(); | 2118 HValue* constructor_index = Pop(); |
| 2116 | 2119 |
| 2117 // Load native context. | 2120 // Load native context. |
| 2118 HValue* native_context = BuildGetNativeContext(); | 2121 HValue* native_context = BuildGetNativeContext(); |
| 2119 | 2122 |
| 2120 // Determine the initial map for the global constructor. | 2123 // Determine the initial map for the global constructor. |
| 2121 HValue* constructor = Add<HLoadKeyed>(native_context, constructor_index, | 2124 HValue* constructor = Add<HLoadKeyed>(native_context, constructor_index, |
| 2122 nullptr, FAST_ELEMENTS); | 2125 nullptr, nullptr, FAST_ELEMENTS); |
| 2123 HValue* constructor_initial_map = Add<HLoadNamedField>( | 2126 HValue* constructor_initial_map = Add<HLoadNamedField>( |
| 2124 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); | 2127 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); |
| 2125 // Allocate and initialize a JSValue wrapper. | 2128 // Allocate and initialize a JSValue wrapper. |
| 2126 HValue* value = | 2129 HValue* value = |
| 2127 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), | 2130 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), |
| 2128 JS_VALUE_TYPE, HAllocationMode()); | 2131 JS_VALUE_TYPE, HAllocationMode()); |
| 2129 Add<HStoreNamedField>(value, HObjectAccess::ForMap(), | 2132 Add<HStoreNamedField>(value, HObjectAccess::ForMap(), |
| 2130 constructor_initial_map); | 2133 constructor_initial_map); |
| 2131 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); | 2134 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); |
| 2132 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), | 2135 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2583 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 2586 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
| 2584 NoObservableSideEffectsScope no_effects(this); | 2587 NoObservableSideEffectsScope no_effects(this); |
| 2585 IfBuilder length_checker(this); | 2588 IfBuilder length_checker(this); |
| 2586 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2589 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
| 2587 length_checker.Then(); | 2590 length_checker.Then(); |
| 2588 IfBuilder negative_checker(this); | 2591 IfBuilder negative_checker(this); |
| 2589 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2592 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
| 2590 key, graph()->GetConstant0(), Token::GTE); | 2593 key, graph()->GetConstant0(), Token::GTE); |
| 2591 negative_checker.Then(); | 2594 negative_checker.Then(); |
| 2592 HInstruction* result = AddElementAccess( | 2595 HInstruction* result = AddElementAccess( |
| 2593 backing_store, key, val, bounds_check, elements_kind, access_type); | 2596 backing_store, key, val, bounds_check, checked_object->ActualValue(), |
| 2597 elements_kind, access_type); |
| 2594 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered); | 2598 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered); |
| 2595 negative_checker.End(); | 2599 negative_checker.End(); |
| 2596 length_checker.End(); | 2600 length_checker.End(); |
| 2597 return result; | 2601 return result; |
| 2598 } else { | 2602 } else { |
| 2599 DCHECK(store_mode == STANDARD_STORE); | 2603 DCHECK(store_mode == STANDARD_STORE); |
| 2600 checked_key = Add<HBoundsCheck>(key, length); | 2604 checked_key = Add<HBoundsCheck>(key, length); |
| 2601 return AddElementAccess( | 2605 return AddElementAccess(backing_store, checked_key, val, checked_object, |
| 2602 backing_store, checked_key, val, | 2606 checked_object->ActualValue(), elements_kind, |
| 2603 checked_object, elements_kind, access_type); | 2607 access_type); |
| 2604 } | 2608 } |
| 2605 } | 2609 } |
| 2606 DCHECK(fast_smi_only_elements || | 2610 DCHECK(fast_smi_only_elements || |
| 2607 fast_elements || | 2611 fast_elements || |
| 2608 IsFastDoubleElementsKind(elements_kind)); | 2612 IsFastDoubleElementsKind(elements_kind)); |
| 2609 | 2613 |
| 2610 // In case val is stored into a fast smi array, assure that the value is a smi | 2614 // In case val is stored into a fast smi array, assure that the value is a smi |
| 2611 // before manipulating the backing store. Otherwise the actual store may | 2615 // before manipulating the backing store. Otherwise the actual store may |
| 2612 // deopt, leaving the backing store in an invalid state. | 2616 // deopt, leaving the backing store in an invalid state. |
| 2613 if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && | 2617 if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2632 NoObservableSideEffectsScope no_effects(this); | 2636 NoObservableSideEffectsScope no_effects(this); |
| 2633 elements = BuildCopyElementsOnWrite(checked_object, elements, | 2637 elements = BuildCopyElementsOnWrite(checked_object, elements, |
| 2634 elements_kind, length); | 2638 elements_kind, length); |
| 2635 } else { | 2639 } else { |
| 2636 HCheckMaps* check_cow_map = Add<HCheckMaps>( | 2640 HCheckMaps* check_cow_map = Add<HCheckMaps>( |
| 2637 elements, isolate()->factory()->fixed_array_map()); | 2641 elements, isolate()->factory()->fixed_array_map()); |
| 2638 check_cow_map->ClearDependsOnFlag(kElementsKind); | 2642 check_cow_map->ClearDependsOnFlag(kElementsKind); |
| 2639 } | 2643 } |
| 2640 } | 2644 } |
| 2641 } | 2645 } |
| 2642 return AddElementAccess(elements, checked_key, val, checked_object, | 2646 return AddElementAccess(elements, checked_key, val, checked_object, nullptr, |
| 2643 elements_kind, access_type, load_mode); | 2647 elements_kind, access_type, load_mode); |
| 2644 } | 2648 } |
| 2645 | 2649 |
| 2646 | 2650 |
| 2647 HValue* HGraphBuilder::BuildAllocateArrayFromLength( | 2651 HValue* HGraphBuilder::BuildAllocateArrayFromLength( |
| 2648 JSArrayBuilder* array_builder, | 2652 JSArrayBuilder* array_builder, |
| 2649 HValue* length_argument) { | 2653 HValue* length_argument) { |
| 2650 if (length_argument->IsConstant() && | 2654 if (length_argument->IsConstant() && |
| 2651 HConstant::cast(length_argument)->HasSmiValue()) { | 2655 HConstant::cast(length_argument)->HasSmiValue()) { |
| 2652 int array_length = HConstant::cast(length_argument)->Integer32Value(); | 2656 int array_length = HConstant::cast(length_argument)->Integer32Value(); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2795 array, HObjectAccess::ForArrayLength(elements_kind), length_field); | 2799 array, HObjectAccess::ForArrayLength(elements_kind), length_field); |
| 2796 | 2800 |
| 2797 if (mode == TRACK_ALLOCATION_SITE) { | 2801 if (mode == TRACK_ALLOCATION_SITE) { |
| 2798 BuildCreateAllocationMemento( | 2802 BuildCreateAllocationMemento( |
| 2799 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); | 2803 array, Add<HConstant>(JSArray::kSize), allocation_site_payload); |
| 2800 } | 2804 } |
| 2801 } | 2805 } |
| 2802 | 2806 |
| 2803 | 2807 |
| 2804 HInstruction* HGraphBuilder::AddElementAccess( | 2808 HInstruction* HGraphBuilder::AddElementAccess( |
| 2805 HValue* elements, | 2809 HValue* elements, HValue* checked_key, HValue* val, HValue* dependency, |
| 2806 HValue* checked_key, | 2810 HValue* backing_store_owner, ElementsKind elements_kind, |
| 2807 HValue* val, | 2811 PropertyAccessType access_type, LoadKeyedHoleMode load_mode) { |
| 2808 HValue* dependency, | |
| 2809 ElementsKind elements_kind, | |
| 2810 PropertyAccessType access_type, | |
| 2811 LoadKeyedHoleMode load_mode) { | |
| 2812 if (access_type == STORE) { | 2812 if (access_type == STORE) { |
| 2813 DCHECK(val != NULL); | 2813 DCHECK(val != NULL); |
| 2814 if (elements_kind == UINT8_CLAMPED_ELEMENTS) { | 2814 if (elements_kind == UINT8_CLAMPED_ELEMENTS) { |
| 2815 val = Add<HClampToUint8>(val); | 2815 val = Add<HClampToUint8>(val); |
| 2816 } | 2816 } |
| 2817 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, | 2817 return Add<HStoreKeyed>(elements, checked_key, val, backing_store_owner, |
| 2818 STORE_TO_INITIALIZED_ENTRY); | 2818 elements_kind, STORE_TO_INITIALIZED_ENTRY); |
| 2819 } | 2819 } |
| 2820 | 2820 |
| 2821 DCHECK(access_type == LOAD); | 2821 DCHECK(access_type == LOAD); |
| 2822 DCHECK(val == NULL); | 2822 DCHECK(val == NULL); |
| 2823 HLoadKeyed* load = Add<HLoadKeyed>( | 2823 HLoadKeyed* load = |
| 2824 elements, checked_key, dependency, elements_kind, load_mode); | 2824 Add<HLoadKeyed>(elements, checked_key, dependency, backing_store_owner, |
| 2825 elements_kind, load_mode); |
| 2825 if (elements_kind == UINT32_ELEMENTS) { | 2826 if (elements_kind == UINT32_ELEMENTS) { |
| 2826 graph()->RecordUint32Instruction(load); | 2827 graph()->RecordUint32Instruction(load); |
| 2827 } | 2828 } |
| 2828 return load; | 2829 return load; |
| 2829 } | 2830 } |
| 2830 | 2831 |
| 2831 | 2832 |
| 2832 HLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object, | 2833 HLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object, |
| 2833 HValue* dependency) { | 2834 HValue* dependency) { |
| 2834 return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap()); | 2835 return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2915 int constant_to = to->GetInteger32Constant(); | 2916 int constant_to = to->GetInteger32Constant(); |
| 2916 | 2917 |
| 2917 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { | 2918 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { |
| 2918 initial_capacity = constant_to; | 2919 initial_capacity = constant_to; |
| 2919 } | 2920 } |
| 2920 } | 2921 } |
| 2921 | 2922 |
| 2922 if (initial_capacity >= 0) { | 2923 if (initial_capacity >= 0) { |
| 2923 for (int i = 0; i < initial_capacity; i++) { | 2924 for (int i = 0; i < initial_capacity; i++) { |
| 2924 HInstruction* key = Add<HConstant>(i); | 2925 HInstruction* key = Add<HConstant>(i); |
| 2925 Add<HStoreKeyed>(elements, key, value, elements_kind); | 2926 Add<HStoreKeyed>(elements, key, value, nullptr, elements_kind); |
| 2926 } | 2927 } |
| 2927 } else { | 2928 } else { |
| 2928 // Carefully loop backwards so that the "from" remains live through the loop | 2929 // Carefully loop backwards so that the "from" remains live through the loop |
| 2929 // rather than the to. This often corresponds to keeping length live rather | 2930 // rather than the to. This often corresponds to keeping length live rather |
| 2930 // then capacity, which helps register allocation, since length is used more | 2931 // then capacity, which helps register allocation, since length is used more |
| 2931 // other than capacity after filling with holes. | 2932 // other than capacity after filling with holes. |
| 2932 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 2933 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 2933 | 2934 |
| 2934 HValue* key = builder.BeginBody(to, from, Token::GT); | 2935 HValue* key = builder.BeginBody(to, from, Token::GT); |
| 2935 | 2936 |
| 2936 HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 2937 HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 2937 adjusted_key->ClearFlag(HValue::kCanOverflow); | 2938 adjusted_key->ClearFlag(HValue::kCanOverflow); |
| 2938 | 2939 |
| 2939 Add<HStoreKeyed>(elements, adjusted_key, value, elements_kind); | 2940 Add<HStoreKeyed>(elements, adjusted_key, value, nullptr, elements_kind); |
| 2940 | 2941 |
| 2941 builder.EndBody(); | 2942 builder.EndBody(); |
| 2942 } | 2943 } |
| 2943 } | 2944 } |
| 2944 | 2945 |
| 2945 | 2946 |
| 2946 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements, | 2947 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements, |
| 2947 ElementsKind elements_kind, | 2948 ElementsKind elements_kind, |
| 2948 HValue* from, | 2949 HValue* from, |
| 2949 HValue* to) { | 2950 HValue* to) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2972 BuildFillElementsWithValue(to_properties, kind, length, capacity, | 2973 BuildFillElementsWithValue(to_properties, kind, length, capacity, |
| 2973 graph()->GetConstantUndefined()); | 2974 graph()->GetConstantUndefined()); |
| 2974 | 2975 |
| 2975 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 2976 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 2976 | 2977 |
| 2977 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); | 2978 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); |
| 2978 | 2979 |
| 2979 key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 2980 key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 2980 key->ClearFlag(HValue::kCanOverflow); | 2981 key->ClearFlag(HValue::kCanOverflow); |
| 2981 | 2982 |
| 2982 HValue* element = Add<HLoadKeyed>(from_properties, key, nullptr, kind); | 2983 HValue* element = |
| 2984 Add<HLoadKeyed>(from_properties, key, nullptr, nullptr, kind); |
| 2983 | 2985 |
| 2984 Add<HStoreKeyed>(to_properties, key, element, kind); | 2986 Add<HStoreKeyed>(to_properties, key, element, nullptr, kind); |
| 2985 | 2987 |
| 2986 builder.EndBody(); | 2988 builder.EndBody(); |
| 2987 } | 2989 } |
| 2988 | 2990 |
| 2989 | 2991 |
| 2990 void HGraphBuilder::BuildCopyElements(HValue* from_elements, | 2992 void HGraphBuilder::BuildCopyElements(HValue* from_elements, |
| 2991 ElementsKind from_elements_kind, | 2993 ElementsKind from_elements_kind, |
| 2992 HValue* to_elements, | 2994 HValue* to_elements, |
| 2993 ElementsKind to_elements_kind, | 2995 ElementsKind to_elements_kind, |
| 2994 HValue* length, | 2996 HValue* length, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3011 // pre-initialized with holes to make sure that it's always in a | 3013 // pre-initialized with holes to make sure that it's always in a |
| 3012 // consistent state. | 3014 // consistent state. |
| 3013 BuildFillElementsWithHole(to_elements, to_elements_kind, | 3015 BuildFillElementsWithHole(to_elements, to_elements_kind, |
| 3014 graph()->GetConstant0(), NULL); | 3016 graph()->GetConstant0(), NULL); |
| 3015 } | 3017 } |
| 3016 | 3018 |
| 3017 if (constant_capacity != -1) { | 3019 if (constant_capacity != -1) { |
| 3018 // Unroll the loop for small elements kinds. | 3020 // Unroll the loop for small elements kinds. |
| 3019 for (int i = 0; i < constant_capacity; i++) { | 3021 for (int i = 0; i < constant_capacity; i++) { |
| 3020 HValue* key_constant = Add<HConstant>(i); | 3022 HValue* key_constant = Add<HConstant>(i); |
| 3021 HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant, | 3023 HInstruction* value = Add<HLoadKeyed>( |
| 3022 nullptr, from_elements_kind); | 3024 from_elements, key_constant, nullptr, nullptr, from_elements_kind); |
| 3023 Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind); | 3025 Add<HStoreKeyed>(to_elements, key_constant, value, nullptr, |
| 3026 to_elements_kind); |
| 3024 } | 3027 } |
| 3025 } else { | 3028 } else { |
| 3026 if (!pre_fill_with_holes && | 3029 if (!pre_fill_with_holes && |
| 3027 (capacity == NULL || !length->Equals(capacity))) { | 3030 (capacity == NULL || !length->Equals(capacity))) { |
| 3028 BuildFillElementsWithHole(to_elements, to_elements_kind, | 3031 BuildFillElementsWithHole(to_elements, to_elements_kind, |
| 3029 length, NULL); | 3032 length, NULL); |
| 3030 } | 3033 } |
| 3031 | 3034 |
| 3032 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 3035 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 3033 | 3036 |
| 3034 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), | 3037 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), |
| 3035 Token::GT); | 3038 Token::GT); |
| 3036 | 3039 |
| 3037 key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 3040 key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 3038 key->ClearFlag(HValue::kCanOverflow); | 3041 key->ClearFlag(HValue::kCanOverflow); |
| 3039 | 3042 |
| 3040 HValue* element = Add<HLoadKeyed>(from_elements, key, nullptr, | 3043 HValue* element = Add<HLoadKeyed>(from_elements, key, nullptr, nullptr, |
| 3041 from_elements_kind, ALLOW_RETURN_HOLE); | 3044 from_elements_kind, ALLOW_RETURN_HOLE); |
| 3042 | 3045 |
| 3043 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && | 3046 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && |
| 3044 IsFastSmiElementsKind(to_elements_kind)) | 3047 IsFastSmiElementsKind(to_elements_kind)) |
| 3045 ? FAST_HOLEY_ELEMENTS : to_elements_kind; | 3048 ? FAST_HOLEY_ELEMENTS : to_elements_kind; |
| 3046 | 3049 |
| 3047 if (IsHoleyElementsKind(from_elements_kind) && | 3050 if (IsHoleyElementsKind(from_elements_kind) && |
| 3048 from_elements_kind != to_elements_kind) { | 3051 from_elements_kind != to_elements_kind) { |
| 3049 IfBuilder if_hole(this); | 3052 IfBuilder if_hole(this); |
| 3050 if_hole.If<HCompareHoleAndBranch>(element); | 3053 if_hole.If<HCompareHoleAndBranch>(element); |
| 3051 if_hole.Then(); | 3054 if_hole.Then(); |
| 3052 HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) | 3055 HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) |
| 3053 ? Add<HConstant>(HConstant::kHoleNaN) | 3056 ? Add<HConstant>(HConstant::kHoleNaN) |
| 3054 : graph()->GetConstantHole(); | 3057 : graph()->GetConstantHole(); |
| 3055 Add<HStoreKeyed>(to_elements, key, hole_constant, kind); | 3058 Add<HStoreKeyed>(to_elements, key, hole_constant, nullptr, kind); |
| 3056 if_hole.Else(); | 3059 if_hole.Else(); |
| 3057 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); | 3060 HStoreKeyed* store = |
| 3061 Add<HStoreKeyed>(to_elements, key, element, nullptr, kind); |
| 3058 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 3062 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 3059 if_hole.End(); | 3063 if_hole.End(); |
| 3060 } else { | 3064 } else { |
| 3061 HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); | 3065 HStoreKeyed* store = |
| 3066 Add<HStoreKeyed>(to_elements, key, element, nullptr, kind); |
| 3062 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 3067 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 3063 } | 3068 } |
| 3064 | 3069 |
| 3065 builder.EndBody(); | 3070 builder.EndBody(); |
| 3066 } | 3071 } |
| 3067 | 3072 |
| 3068 Counters* counters = isolate()->counters(); | 3073 Counters* counters = isolate()->counters(); |
| 3069 AddIncrementCounter(counters->inlined_copied_elements()); | 3074 AddIncrementCounter(counters->inlined_copied_elements()); |
| 3070 } | 3075 } |
| 3071 | 3076 |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3338 } | 3343 } |
| 3339 } | 3344 } |
| 3340 return script_context; | 3345 return script_context; |
| 3341 } | 3346 } |
| 3342 | 3347 |
| 3343 | 3348 |
| 3344 HInstruction* HGraphBuilder::BuildGetArrayFunction() { | 3349 HInstruction* HGraphBuilder::BuildGetArrayFunction() { |
| 3345 HInstruction* native_context = BuildGetNativeContext(); | 3350 HInstruction* native_context = BuildGetNativeContext(); |
| 3346 HInstruction* index = | 3351 HInstruction* index = |
| 3347 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); | 3352 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); |
| 3348 return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); | 3353 return Add<HLoadKeyed>(native_context, index, nullptr, nullptr, |
| 3354 FAST_ELEMENTS); |
| 3349 } | 3355 } |
| 3350 | 3356 |
| 3351 | 3357 |
| 3352 HValue* HGraphBuilder::BuildArrayBufferViewFieldAccessor(HValue* object, | 3358 HValue* HGraphBuilder::BuildArrayBufferViewFieldAccessor(HValue* object, |
| 3353 HValue* checked_object, | 3359 HValue* checked_object, |
| 3354 FieldIndex index) { | 3360 FieldIndex index) { |
| 3355 NoObservableSideEffectsScope scope(this); | 3361 NoObservableSideEffectsScope scope(this); |
| 3356 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( | 3362 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( |
| 3357 index.offset(), Representation::Tagged()); | 3363 index.offset(), Representation::Tagged()); |
| 3358 HInstruction* buffer = Add<HLoadNamedField>( | 3364 HInstruction* buffer = Add<HLoadNamedField>( |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3426 | 3432 |
| 3427 // TODO(mvstanton): we should always have a constructor function if we | 3433 // TODO(mvstanton): we should always have a constructor function if we |
| 3428 // are creating a stub. | 3434 // are creating a stub. |
| 3429 HInstruction* native_context = constructor_function_ != NULL | 3435 HInstruction* native_context = constructor_function_ != NULL |
| 3430 ? builder()->BuildGetNativeContext(constructor_function_) | 3436 ? builder()->BuildGetNativeContext(constructor_function_) |
| 3431 : builder()->BuildGetNativeContext(); | 3437 : builder()->BuildGetNativeContext(); |
| 3432 | 3438 |
| 3433 HInstruction* index = builder()->Add<HConstant>( | 3439 HInstruction* index = builder()->Add<HConstant>( |
| 3434 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); | 3440 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
| 3435 | 3441 |
| 3436 HInstruction* map_array = | 3442 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
| 3437 builder()->Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); | 3443 native_context, index, nullptr, nullptr, FAST_ELEMENTS); |
| 3438 | 3444 |
| 3439 HInstruction* kind_index = builder()->Add<HConstant>(kind_); | 3445 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
| 3440 | 3446 |
| 3441 return builder()->Add<HLoadKeyed>(map_array, kind_index, nullptr, | 3447 return builder()->Add<HLoadKeyed>(map_array, kind_index, nullptr, nullptr, |
| 3442 FAST_ELEMENTS); | 3448 FAST_ELEMENTS); |
| 3443 } | 3449 } |
| 3444 | 3450 |
| 3445 | 3451 |
| 3446 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 3452 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 3447 // Find the map near the constructor function | 3453 // Find the map near the constructor function |
| 3448 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 3454 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 3449 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, | 3455 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, |
| 3450 access); | 3456 access); |
| 3451 } | 3457 } |
| (...skipping 1933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5385 compare_index->SetSuccessorAt(1, loop_successor); | 5391 compare_index->SetSuccessorAt(1, loop_successor); |
| 5386 FinishCurrentBlock(compare_index); | 5392 FinishCurrentBlock(compare_index); |
| 5387 | 5393 |
| 5388 set_current_block(loop_successor); | 5394 set_current_block(loop_successor); |
| 5389 Drop(5); | 5395 Drop(5); |
| 5390 | 5396 |
| 5391 set_current_block(loop_body); | 5397 set_current_block(loop_body); |
| 5392 | 5398 |
| 5393 HValue* key = | 5399 HValue* key = |
| 5394 Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache. | 5400 Add<HLoadKeyed>(environment()->ExpressionStackAt(2), // Enum cache. |
| 5395 index, index, FAST_ELEMENTS); | 5401 index, index, nullptr, FAST_ELEMENTS); |
| 5396 | 5402 |
| 5397 if (fast) { | 5403 if (fast) { |
| 5398 // Check if the expected map still matches that of the enumerable. | 5404 // Check if the expected map still matches that of the enumerable. |
| 5399 // If not just deoptimize. | 5405 // If not just deoptimize. |
| 5400 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3)); | 5406 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3)); |
| 5401 Bind(each_var, key); | 5407 Bind(each_var, key); |
| 5402 } else { | 5408 } else { |
| 5403 Add<HPushArguments>(enumerable, key); | 5409 Add<HPushArguments>(enumerable, key); |
| 5404 Runtime::FunctionId function_id = Runtime::kForInFilter; | 5410 Runtime::FunctionId function_id = Runtime::kForInFilter; |
| 5405 key = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2); | 5411 key = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2); |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6097 | 6103 |
| 6098 HValue* key = Add<HConstant>(i); | 6104 HValue* key = Add<HConstant>(i); |
| 6099 | 6105 |
| 6100 switch (boilerplate_elements_kind) { | 6106 switch (boilerplate_elements_kind) { |
| 6101 case FAST_SMI_ELEMENTS: | 6107 case FAST_SMI_ELEMENTS: |
| 6102 case FAST_HOLEY_SMI_ELEMENTS: | 6108 case FAST_HOLEY_SMI_ELEMENTS: |
| 6103 case FAST_ELEMENTS: | 6109 case FAST_ELEMENTS: |
| 6104 case FAST_HOLEY_ELEMENTS: | 6110 case FAST_HOLEY_ELEMENTS: |
| 6105 case FAST_DOUBLE_ELEMENTS: | 6111 case FAST_DOUBLE_ELEMENTS: |
| 6106 case FAST_HOLEY_DOUBLE_ELEMENTS: { | 6112 case FAST_HOLEY_DOUBLE_ELEMENTS: { |
| 6107 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, | 6113 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, nullptr, |
| 6108 boilerplate_elements_kind); | 6114 boilerplate_elements_kind); |
| 6109 instr->SetUninitialized(uninitialized); | 6115 instr->SetUninitialized(uninitialized); |
| 6110 break; | 6116 break; |
| 6111 } | 6117 } |
| 6112 default: | 6118 default: |
| 6113 UNREACHABLE(); | 6119 UNREACHABLE(); |
| 6114 break; | 6120 break; |
| 6115 } | 6121 } |
| 6116 | 6122 |
| 6117 Add<HSimulate>(expr->GetIdForElement(i)); | 6123 Add<HSimulate>(expr->GetIdForElement(i)); |
| (...skipping 2745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8863 if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); | 8869 if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); |
| 8864 | 8870 |
| 8865 length_checker.Else(); | 8871 length_checker.Else(); |
| 8866 HValue* elements = AddLoadElements(checked_object); | 8872 HValue* elements = AddLoadElements(checked_object); |
| 8867 // Ensure that we aren't popping from a copy-on-write array. | 8873 // Ensure that we aren't popping from a copy-on-write array. |
| 8868 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 8874 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 8869 elements = BuildCopyElementsOnWrite(checked_object, elements, | 8875 elements = BuildCopyElementsOnWrite(checked_object, elements, |
| 8870 elements_kind, length); | 8876 elements_kind, length); |
| 8871 } | 8877 } |
| 8872 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); | 8878 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); |
| 8873 result = AddElementAccess(elements, reduced_length, NULL, | 8879 result = AddElementAccess(elements, reduced_length, nullptr, |
| 8874 bounds_check, elements_kind, LOAD); | 8880 bounds_check, nullptr, elements_kind, LOAD); |
| 8875 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 8881 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
| 8876 ? graph()->GetConstantHole() | 8882 ? graph()->GetConstantHole() |
| 8877 : Add<HConstant>(HConstant::kHoleNaN); | 8883 : Add<HConstant>(HConstant::kHoleNaN); |
| 8878 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 8884 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 8879 elements_kind = FAST_HOLEY_ELEMENTS; | 8885 elements_kind = FAST_HOLEY_ELEMENTS; |
| 8880 } | 8886 } |
| 8881 AddElementAccess( | 8887 AddElementAccess(elements, reduced_length, hole, bounds_check, nullptr, |
| 8882 elements, reduced_length, hole, bounds_check, elements_kind, STORE); | 8888 elements_kind, STORE); |
| 8883 Add<HStoreNamedField>( | 8889 Add<HStoreNamedField>( |
| 8884 checked_object, HObjectAccess::ForArrayLength(elements_kind), | 8890 checked_object, HObjectAccess::ForArrayLength(elements_kind), |
| 8885 reduced_length, STORE_TO_INITIALIZED_ENTRY); | 8891 reduced_length, STORE_TO_INITIALIZED_ENTRY); |
| 8886 | 8892 |
| 8887 if (!ast_context()->IsEffect()) Push(result); | 8893 if (!ast_context()->IsEffect()) Push(result); |
| 8888 | 8894 |
| 8889 length_checker.End(); | 8895 length_checker.End(); |
| 8890 } | 8896 } |
| 8891 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); | 8897 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); |
| 8892 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8898 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8997 length, inline_threshold, Token::LTE); | 9003 length, inline_threshold, Token::LTE); |
| 8998 if (IsFastSmiOrObjectElementsKind(kind)) { | 9004 if (IsFastSmiOrObjectElementsKind(kind)) { |
| 8999 // We cannot handle copy-on-write backing stores here. | 9005 // We cannot handle copy-on-write backing stores here. |
| 9000 if_inline.AndIf<HCompareMap>( | 9006 if_inline.AndIf<HCompareMap>( |
| 9001 elements, isolate()->factory()->fixed_array_map()); | 9007 elements, isolate()->factory()->fixed_array_map()); |
| 9002 } | 9008 } |
| 9003 if_inline.Then(); | 9009 if_inline.Then(); |
| 9004 { | 9010 { |
| 9005 // Remember the result. | 9011 // Remember the result. |
| 9006 if (!ast_context()->IsEffect()) { | 9012 if (!ast_context()->IsEffect()) { |
| 9007 Push(AddElementAccess(elements, graph()->GetConstant0(), NULL, | 9013 Push(AddElementAccess(elements, graph()->GetConstant0(), nullptr, |
| 9008 lengthiszero, kind, LOAD)); | 9014 lengthiszero, nullptr, kind, LOAD)); |
| 9009 } | 9015 } |
| 9010 | 9016 |
| 9011 // Compute the new length. | 9017 // Compute the new length. |
| 9012 HValue* new_length = AddUncasted<HSub>( | 9018 HValue* new_length = AddUncasted<HSub>( |
| 9013 length, graph()->GetConstant1()); | 9019 length, graph()->GetConstant1()); |
| 9014 new_length->ClearFlag(HValue::kCanOverflow); | 9020 new_length->ClearFlag(HValue::kCanOverflow); |
| 9015 | 9021 |
| 9016 // Copy the remaining elements. | 9022 // Copy the remaining elements. |
| 9017 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); | 9023 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); |
| 9018 { | 9024 { |
| 9019 HValue* new_key = loop.BeginBody( | 9025 HValue* new_key = loop.BeginBody( |
| 9020 graph()->GetConstant0(), new_length, Token::LT); | 9026 graph()->GetConstant0(), new_length, Token::LT); |
| 9021 HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); | 9027 HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); |
| 9022 key->ClearFlag(HValue::kCanOverflow); | 9028 key->ClearFlag(HValue::kCanOverflow); |
| 9023 ElementsKind copy_kind = | 9029 ElementsKind copy_kind = |
| 9024 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; | 9030 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; |
| 9025 HValue* element = AddUncasted<HLoadKeyed>( | 9031 HValue* element = |
| 9026 elements, key, lengthiszero, copy_kind, ALLOW_RETURN_HOLE); | 9032 AddUncasted<HLoadKeyed>(elements, key, lengthiszero, nullptr, |
| 9027 HStoreKeyed* store = | 9033 copy_kind, ALLOW_RETURN_HOLE); |
| 9028 Add<HStoreKeyed>(elements, new_key, element, copy_kind); | 9034 HStoreKeyed* store = Add<HStoreKeyed>(elements, new_key, element, |
| 9035 nullptr, copy_kind); |
| 9029 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 9036 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 9030 } | 9037 } |
| 9031 loop.EndBody(); | 9038 loop.EndBody(); |
| 9032 | 9039 |
| 9033 // Put a hole at the end. | 9040 // Put a hole at the end. |
| 9034 HValue* hole = IsFastSmiOrObjectElementsKind(kind) | 9041 HValue* hole = IsFastSmiOrObjectElementsKind(kind) |
| 9035 ? graph()->GetConstantHole() | 9042 ? graph()->GetConstantHole() |
| 9036 : Add<HConstant>(HConstant::kHoleNaN); | 9043 : Add<HConstant>(HConstant::kHoleNaN); |
| 9037 if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; | 9044 if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; |
| 9038 Add<HStoreKeyed>( | 9045 Add<HStoreKeyed>(elements, new_length, hole, nullptr, kind, |
| 9039 elements, new_length, hole, kind, INITIALIZING_STORE); | 9046 INITIALIZING_STORE); |
| 9040 | 9047 |
| 9041 // Remember new length. | 9048 // Remember new length. |
| 9042 Add<HStoreNamedField>( | 9049 Add<HStoreNamedField>( |
| 9043 receiver, HObjectAccess::ForArrayLength(kind), | 9050 receiver, HObjectAccess::ForArrayLength(kind), |
| 9044 new_length, STORE_TO_INITIALIZED_ENTRY); | 9051 new_length, STORE_TO_INITIALIZED_ENTRY); |
| 9045 } | 9052 } |
| 9046 if_inline.Else(); | 9053 if_inline.Else(); |
| 9047 { | 9054 { |
| 9048 Add<HPushArguments>(receiver); | 9055 Add<HPushArguments>(receiver); |
| 9049 result = Add<HCallJSFunction>(function, 1); | 9056 result = Add<HCallJSFunction>(function, 1); |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9491 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { | 9498 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { |
| 9492 // Make sure that we can actually compare numbers correctly below, see | 9499 // Make sure that we can actually compare numbers correctly below, see |
| 9493 // https://code.google.com/p/chromium/issues/detail?id=407946 for details. | 9500 // https://code.google.com/p/chromium/issues/detail?id=407946 for details. |
| 9494 search_element = AddUncasted<HForceRepresentation>( | 9501 search_element = AddUncasted<HForceRepresentation>( |
| 9495 search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() | 9502 search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() |
| 9496 : Representation::Double()); | 9503 : Representation::Double()); |
| 9497 | 9504 |
| 9498 LoopBuilder loop(this, context(), direction); | 9505 LoopBuilder loop(this, context(), direction); |
| 9499 { | 9506 { |
| 9500 HValue* index = loop.BeginBody(initial, terminating, token); | 9507 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9501 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, kind, | 9508 HValue* element = AddUncasted<HLoadKeyed>( |
| 9502 ALLOW_RETURN_HOLE); | 9509 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9503 IfBuilder if_issame(this); | 9510 IfBuilder if_issame(this); |
| 9504 if_issame.If<HCompareNumericAndBranch>(element, search_element, | 9511 if_issame.If<HCompareNumericAndBranch>(element, search_element, |
| 9505 Token::EQ_STRICT); | 9512 Token::EQ_STRICT); |
| 9506 if_issame.Then(); | 9513 if_issame.Then(); |
| 9507 { | 9514 { |
| 9508 Drop(1); | 9515 Drop(1); |
| 9509 Push(index); | 9516 Push(index); |
| 9510 loop.Break(); | 9517 loop.Break(); |
| 9511 } | 9518 } |
| 9512 if_issame.End(); | 9519 if_issame.End(); |
| 9513 } | 9520 } |
| 9514 loop.EndBody(); | 9521 loop.EndBody(); |
| 9515 } else { | 9522 } else { |
| 9516 IfBuilder if_isstring(this); | 9523 IfBuilder if_isstring(this); |
| 9517 if_isstring.If<HIsStringAndBranch>(search_element); | 9524 if_isstring.If<HIsStringAndBranch>(search_element); |
| 9518 if_isstring.Then(); | 9525 if_isstring.Then(); |
| 9519 { | 9526 { |
| 9520 LoopBuilder loop(this, context(), direction); | 9527 LoopBuilder loop(this, context(), direction); |
| 9521 { | 9528 { |
| 9522 HValue* index = loop.BeginBody(initial, terminating, token); | 9529 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9523 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, | 9530 HValue* element = AddUncasted<HLoadKeyed>( |
| 9524 kind, ALLOW_RETURN_HOLE); | 9531 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9525 IfBuilder if_issame(this); | 9532 IfBuilder if_issame(this); |
| 9526 if_issame.If<HIsStringAndBranch>(element); | 9533 if_issame.If<HIsStringAndBranch>(element); |
| 9527 if_issame.AndIf<HStringCompareAndBranch>( | 9534 if_issame.AndIf<HStringCompareAndBranch>( |
| 9528 element, search_element, Token::EQ_STRICT); | 9535 element, search_element, Token::EQ_STRICT); |
| 9529 if_issame.Then(); | 9536 if_issame.Then(); |
| 9530 { | 9537 { |
| 9531 Drop(1); | 9538 Drop(1); |
| 9532 Push(index); | 9539 Push(index); |
| 9533 loop.Break(); | 9540 loop.Break(); |
| 9534 } | 9541 } |
| 9535 if_issame.End(); | 9542 if_issame.End(); |
| 9536 } | 9543 } |
| 9537 loop.EndBody(); | 9544 loop.EndBody(); |
| 9538 } | 9545 } |
| 9539 if_isstring.Else(); | 9546 if_isstring.Else(); |
| 9540 { | 9547 { |
| 9541 IfBuilder if_isnumber(this); | 9548 IfBuilder if_isnumber(this); |
| 9542 if_isnumber.If<HIsSmiAndBranch>(search_element); | 9549 if_isnumber.If<HIsSmiAndBranch>(search_element); |
| 9543 if_isnumber.OrIf<HCompareMap>( | 9550 if_isnumber.OrIf<HCompareMap>( |
| 9544 search_element, isolate()->factory()->heap_number_map()); | 9551 search_element, isolate()->factory()->heap_number_map()); |
| 9545 if_isnumber.Then(); | 9552 if_isnumber.Then(); |
| 9546 { | 9553 { |
| 9547 HValue* search_number = | 9554 HValue* search_number = |
| 9548 AddUncasted<HForceRepresentation>(search_element, | 9555 AddUncasted<HForceRepresentation>(search_element, |
| 9549 Representation::Double()); | 9556 Representation::Double()); |
| 9550 LoopBuilder loop(this, context(), direction); | 9557 LoopBuilder loop(this, context(), direction); |
| 9551 { | 9558 { |
| 9552 HValue* index = loop.BeginBody(initial, terminating, token); | 9559 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9553 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, | 9560 HValue* element = AddUncasted<HLoadKeyed>( |
| 9554 kind, ALLOW_RETURN_HOLE); | 9561 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9555 | 9562 |
| 9556 IfBuilder if_element_isnumber(this); | 9563 IfBuilder if_element_isnumber(this); |
| 9557 if_element_isnumber.If<HIsSmiAndBranch>(element); | 9564 if_element_isnumber.If<HIsSmiAndBranch>(element); |
| 9558 if_element_isnumber.OrIf<HCompareMap>( | 9565 if_element_isnumber.OrIf<HCompareMap>( |
| 9559 element, isolate()->factory()->heap_number_map()); | 9566 element, isolate()->factory()->heap_number_map()); |
| 9560 if_element_isnumber.Then(); | 9567 if_element_isnumber.Then(); |
| 9561 { | 9568 { |
| 9562 HValue* number = | 9569 HValue* number = |
| 9563 AddUncasted<HForceRepresentation>(element, | 9570 AddUncasted<HForceRepresentation>(element, |
| 9564 Representation::Double()); | 9571 Representation::Double()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9575 } | 9582 } |
| 9576 if_element_isnumber.End(); | 9583 if_element_isnumber.End(); |
| 9577 } | 9584 } |
| 9578 loop.EndBody(); | 9585 loop.EndBody(); |
| 9579 } | 9586 } |
| 9580 if_isnumber.Else(); | 9587 if_isnumber.Else(); |
| 9581 { | 9588 { |
| 9582 LoopBuilder loop(this, context(), direction); | 9589 LoopBuilder loop(this, context(), direction); |
| 9583 { | 9590 { |
| 9584 HValue* index = loop.BeginBody(initial, terminating, token); | 9591 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9585 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, | 9592 HValue* element = AddUncasted<HLoadKeyed>( |
| 9586 kind, ALLOW_RETURN_HOLE); | 9593 elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); |
| 9587 IfBuilder if_issame(this); | 9594 IfBuilder if_issame(this); |
| 9588 if_issame.If<HCompareObjectEqAndBranch>( | 9595 if_issame.If<HCompareObjectEqAndBranch>( |
| 9589 element, search_element); | 9596 element, search_element); |
| 9590 if_issame.Then(); | 9597 if_issame.Then(); |
| 9591 { | 9598 { |
| 9592 Drop(1); | 9599 Drop(1); |
| 9593 Push(index); | 9600 Push(index); |
| 9594 loop.Break(); | 9601 loop.Break(); |
| 9595 } | 9602 } |
| 9596 if_issame.End(); | 9603 if_issame.End(); |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10228 if (initialize) { | 10235 if (initialize) { |
| 10229 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); | 10236 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
| 10230 | 10237 |
| 10231 HValue* backing_store = AddUncasted<HAdd>( | 10238 HValue* backing_store = AddUncasted<HAdd>( |
| 10232 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset()), | 10239 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset()), |
| 10233 elements, Strength::WEAK, AddOfExternalAndTagged); | 10240 elements, Strength::WEAK, AddOfExternalAndTagged); |
| 10234 | 10241 |
| 10235 HValue* key = builder.BeginBody( | 10242 HValue* key = builder.BeginBody( |
| 10236 Add<HConstant>(static_cast<int32_t>(0)), | 10243 Add<HConstant>(static_cast<int32_t>(0)), |
| 10237 length, Token::LT); | 10244 length, Token::LT); |
| 10238 Add<HStoreKeyed>(backing_store, key, filler, fixed_elements_kind); | 10245 Add<HStoreKeyed>(backing_store, key, filler, elements, fixed_elements_kind); |
| 10239 | 10246 |
| 10240 builder.EndBody(); | 10247 builder.EndBody(); |
| 10241 } | 10248 } |
| 10242 return elements; | 10249 return elements; |
| 10243 } | 10250 } |
| 10244 | 10251 |
| 10245 | 10252 |
| 10246 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( | 10253 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( |
| 10247 CallRuntime* expr) { | 10254 CallRuntime* expr) { |
| 10248 ZoneList<Expression*>* arguments = expr->arguments(); | 10255 ZoneList<Expression*>* arguments = expr->arguments(); |
| (...skipping 1716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11965 | 11972 |
| 11966 | 11973 |
| 11967 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 11974 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
| 11968 Handle<FixedArrayBase> elements, | 11975 Handle<FixedArrayBase> elements, |
| 11969 ElementsKind kind, | 11976 ElementsKind kind, |
| 11970 HValue* object_elements) { | 11977 HValue* object_elements) { |
| 11971 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 11978 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 11972 int elements_length = elements->length(); | 11979 int elements_length = elements->length(); |
| 11973 for (int i = 0; i < elements_length; i++) { | 11980 for (int i = 0; i < elements_length; i++) { |
| 11974 HValue* key_constant = Add<HConstant>(i); | 11981 HValue* key_constant = Add<HConstant>(i); |
| 11975 HInstruction* value_instruction = Add<HLoadKeyed>( | 11982 HInstruction* value_instruction = |
| 11976 boilerplate_elements, key_constant, nullptr, kind, ALLOW_RETURN_HOLE); | 11983 Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, nullptr, |
| 11984 kind, ALLOW_RETURN_HOLE); |
| 11977 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, | 11985 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 11978 value_instruction, kind); | 11986 value_instruction, nullptr, kind); |
| 11979 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 11987 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 11980 } | 11988 } |
| 11981 } | 11989 } |
| 11982 | 11990 |
| 11983 | 11991 |
| 11984 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 11992 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 11985 Handle<FixedArrayBase> elements, | 11993 Handle<FixedArrayBase> elements, |
| 11986 ElementsKind kind, | 11994 ElementsKind kind, |
| 11987 HValue* object_elements, | 11995 HValue* object_elements, |
| 11988 AllocationSiteUsageContext* site_context) { | 11996 AllocationSiteUsageContext* site_context) { |
| 11989 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 11997 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 11990 int elements_length = elements->length(); | 11998 int elements_length = elements->length(); |
| 11991 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 11999 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 11992 for (int i = 0; i < elements_length; i++) { | 12000 for (int i = 0; i < elements_length; i++) { |
| 11993 Handle<Object> value(fast_elements->get(i), isolate()); | 12001 Handle<Object> value(fast_elements->get(i), isolate()); |
| 11994 HValue* key_constant = Add<HConstant>(i); | 12002 HValue* key_constant = Add<HConstant>(i); |
| 11995 if (value->IsJSObject()) { | 12003 if (value->IsJSObject()) { |
| 11996 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 12004 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 11997 Handle<AllocationSite> current_site = site_context->EnterNewScope(); | 12005 Handle<AllocationSite> current_site = site_context->EnterNewScope(); |
| 11998 HInstruction* result = | 12006 HInstruction* result = |
| 11999 BuildFastLiteral(value_object, site_context); | 12007 BuildFastLiteral(value_object, site_context); |
| 12000 site_context->ExitScope(current_site, value_object); | 12008 site_context->ExitScope(current_site, value_object); |
| 12001 Add<HStoreKeyed>(object_elements, key_constant, result, kind); | 12009 Add<HStoreKeyed>(object_elements, key_constant, result, nullptr, kind); |
| 12002 } else { | 12010 } else { |
| 12003 ElementsKind copy_kind = | 12011 ElementsKind copy_kind = |
| 12004 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; | 12012 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; |
| 12005 HInstruction* value_instruction = | 12013 HInstruction* value_instruction = |
| 12006 Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, | 12014 Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, nullptr, |
| 12007 copy_kind, ALLOW_RETURN_HOLE); | 12015 copy_kind, ALLOW_RETURN_HOLE); |
| 12008 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, | 12016 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, |
| 12009 copy_kind); | 12017 nullptr, copy_kind); |
| 12010 } | 12018 } |
| 12011 } | 12019 } |
| 12012 } | 12020 } |
| 12013 | 12021 |
| 12014 | 12022 |
| 12015 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 12023 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 12016 DCHECK(!HasStackOverflow()); | 12024 DCHECK(!HasStackOverflow()); |
| 12017 DCHECK(current_block() != NULL); | 12025 DCHECK(current_block() != NULL); |
| 12018 DCHECK(current_block()->HasPredecessor()); | 12026 DCHECK(current_block()->HasPredecessor()); |
| 12019 HInstruction* instr = BuildThisFunction(); | 12027 HInstruction* instr = BuildThisFunction(); |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12788 } | 12796 } |
| 12789 | 12797 |
| 12790 | 12798 |
| 12791 void HOptimizedGraphBuilder::GenerateFixedArrayGet(CallRuntime* call) { | 12799 void HOptimizedGraphBuilder::GenerateFixedArrayGet(CallRuntime* call) { |
| 12792 DCHECK(call->arguments()->length() == 2); | 12800 DCHECK(call->arguments()->length() == 2); |
| 12793 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12801 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12794 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12802 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 12795 HValue* index = Pop(); | 12803 HValue* index = Pop(); |
| 12796 HValue* object = Pop(); | 12804 HValue* object = Pop(); |
| 12797 HInstruction* result = New<HLoadKeyed>( | 12805 HInstruction* result = New<HLoadKeyed>( |
| 12798 object, index, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); | 12806 object, index, nullptr, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); |
| 12799 return ast_context()->ReturnInstruction(result, call->id()); | 12807 return ast_context()->ReturnInstruction(result, call->id()); |
| 12800 } | 12808 } |
| 12801 | 12809 |
| 12802 | 12810 |
| 12803 void HOptimizedGraphBuilder::GenerateFixedArraySet(CallRuntime* call) { | 12811 void HOptimizedGraphBuilder::GenerateFixedArraySet(CallRuntime* call) { |
| 12804 DCHECK(call->arguments()->length() == 3); | 12812 DCHECK(call->arguments()->length() == 3); |
| 12805 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12813 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12806 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12814 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 12807 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); | 12815 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); |
| 12808 HValue* value = Pop(); | 12816 HValue* value = Pop(); |
| 12809 HValue* index = Pop(); | 12817 HValue* index = Pop(); |
| 12810 HValue* object = Pop(); | 12818 HValue* object = Pop(); |
| 12811 NoObservableSideEffectsScope no_effects(this); | 12819 NoObservableSideEffectsScope no_effects(this); |
| 12812 Add<HStoreKeyed>(object, index, value, FAST_HOLEY_ELEMENTS); | 12820 Add<HStoreKeyed>(object, index, value, nullptr, FAST_HOLEY_ELEMENTS); |
| 12813 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 12821 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
| 12814 } | 12822 } |
| 12815 | 12823 |
| 12816 | 12824 |
| 12817 void HOptimizedGraphBuilder::GenerateTheHole(CallRuntime* call) { | 12825 void HOptimizedGraphBuilder::GenerateTheHole(CallRuntime* call) { |
| 12818 DCHECK(call->arguments()->length() == 0); | 12826 DCHECK(call->arguments()->length() == 0); |
| 12819 return ast_context()->ReturnValue(graph()->GetConstantHole()); | 12827 return ast_context()->ReturnValue(graph()->GetConstantHole()); |
| 12820 } | 12828 } |
| 12821 | 12829 |
| 12822 | 12830 |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13638 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13646 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13639 } | 13647 } |
| 13640 | 13648 |
| 13641 #ifdef DEBUG | 13649 #ifdef DEBUG |
| 13642 graph_->Verify(false); // No full verify. | 13650 graph_->Verify(false); // No full verify. |
| 13643 #endif | 13651 #endif |
| 13644 } | 13652 } |
| 13645 | 13653 |
| 13646 } // namespace internal | 13654 } // namespace internal |
| 13647 } // namespace v8 | 13655 } // namespace v8 |
| OLD | NEW |