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 |