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 |