| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/code-stubs.h" | 5 #include "src/code-stubs.h" |
| 6 | 6 |
| 7 #include "src/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
| 8 #include "src/crankshaft/hydrogen.h" | 8 #include "src/crankshaft/hydrogen.h" |
| 9 #include "src/crankshaft/lithium.h" | 9 #include "src/crankshaft/lithium.h" |
| 10 #include "src/field-index.h" | 10 #include "src/field-index.h" |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { | 436 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { |
| 437 Factory* factory = isolate()->factory(); | 437 Factory* factory = isolate()->factory(); |
| 438 HValue* undefined = graph()->GetConstantUndefined(); | 438 HValue* undefined = graph()->GetConstantUndefined(); |
| 439 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); | 439 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); |
| 440 | 440 |
| 441 // This stub is very performance sensitive, the generated code must be tuned | 441 // This stub is very performance sensitive, the generated code must be tuned |
| 442 // so that it doesn't build and eager frame. | 442 // so that it doesn't build and eager frame. |
| 443 info()->MarkMustNotHaveEagerFrame(); | 443 info()->MarkMustNotHaveEagerFrame(); |
| 444 | 444 |
| 445 HInstruction* allocation_site = Add<HLoadKeyed>( | 445 HInstruction* allocation_site = Add<HLoadKeyed>( |
| 446 GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS, | 446 GetParameter(0), GetParameter(1), nullptr, nullptr, FAST_ELEMENTS, |
| 447 NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag); | 447 NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag); |
| 448 IfBuilder checker(this); | 448 IfBuilder checker(this); |
| 449 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, | 449 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, |
| 450 undefined); | 450 undefined); |
| 451 checker.Then(); | 451 checker.Then(); |
| 452 | 452 |
| 453 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( | 453 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
| 454 AllocationSite::kTransitionInfoOffset); | 454 AllocationSite::kTransitionInfoOffset); |
| 455 HInstruction* boilerplate = | 455 HInstruction* boilerplate = |
| 456 Add<HLoadNamedField>(allocation_site, nullptr, access); | 456 Add<HLoadNamedField>(allocation_site, nullptr, access); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 Handle<Code> FastCloneShallowArrayStub::GenerateCode() { | 499 Handle<Code> FastCloneShallowArrayStub::GenerateCode() { |
| 500 return DoGenerateCode(this); | 500 return DoGenerateCode(this); |
| 501 } | 501 } |
| 502 | 502 |
| 503 | 503 |
| 504 template <> | 504 template <> |
| 505 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { | 505 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { |
| 506 HValue* undefined = graph()->GetConstantUndefined(); | 506 HValue* undefined = graph()->GetConstantUndefined(); |
| 507 | 507 |
| 508 HInstruction* allocation_site = Add<HLoadKeyed>( | 508 HInstruction* allocation_site = Add<HLoadKeyed>( |
| 509 GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS, | 509 GetParameter(0), GetParameter(1), nullptr, nullptr, FAST_ELEMENTS, |
| 510 NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag); | 510 NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag); |
| 511 | 511 |
| 512 IfBuilder checker(this); | 512 IfBuilder checker(this); |
| 513 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, | 513 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, |
| 514 undefined); | 514 undefined); |
| 515 checker.And(); | 515 checker.And(); |
| 516 | 516 |
| 517 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( | 517 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
| 518 AllocationSite::kTransitionInfoOffset); | 518 AllocationSite::kTransitionInfoOffset); |
| 519 HInstruction* boilerplate = | 519 HInstruction* boilerplate = |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 // next GC, and allocation sites are designed to survive several GCs anyway. | 629 // next GC, and allocation sites are designed to survive several GCs anyway. |
| 630 Add<HStoreNamedField>( | 630 Add<HStoreNamedField>( |
| 631 object, | 631 object, |
| 632 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), | 632 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), |
| 633 site); | 633 site); |
| 634 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), | 634 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), |
| 635 object); | 635 object); |
| 636 | 636 |
| 637 HInstruction* feedback_vector = GetParameter(0); | 637 HInstruction* feedback_vector = GetParameter(0); |
| 638 HInstruction* slot = GetParameter(1); | 638 HInstruction* slot = GetParameter(1); |
| 639 Add<HStoreKeyed>(feedback_vector, slot, object, FAST_ELEMENTS, | 639 Add<HStoreKeyed>(feedback_vector, slot, object, nullptr, FAST_ELEMENTS, |
| 640 INITIALIZING_STORE); | 640 INITIALIZING_STORE); |
| 641 return feedback_vector; | 641 return feedback_vector; |
| 642 } | 642 } |
| 643 | 643 |
| 644 | 644 |
| 645 Handle<Code> CreateAllocationSiteStub::GenerateCode() { | 645 Handle<Code> CreateAllocationSiteStub::GenerateCode() { |
| 646 return DoGenerateCode(this); | 646 return DoGenerateCode(this); |
| 647 } | 647 } |
| 648 | 648 |
| 649 | 649 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 661 AddStoreMapConstant(object, weak_cell_map); | 661 AddStoreMapConstant(object, weak_cell_map); |
| 662 | 662 |
| 663 HInstruction* value = GetParameter(CreateWeakCellDescriptor::kValueIndex); | 663 HInstruction* value = GetParameter(CreateWeakCellDescriptor::kValueIndex); |
| 664 Add<HStoreNamedField>(object, HObjectAccess::ForWeakCellValue(), value); | 664 Add<HStoreNamedField>(object, HObjectAccess::ForWeakCellValue(), value); |
| 665 Add<HStoreNamedField>(object, HObjectAccess::ForWeakCellNext(), | 665 Add<HStoreNamedField>(object, HObjectAccess::ForWeakCellNext(), |
| 666 graph()->GetConstantHole()); | 666 graph()->GetConstantHole()); |
| 667 | 667 |
| 668 HInstruction* feedback_vector = | 668 HInstruction* feedback_vector = |
| 669 GetParameter(CreateWeakCellDescriptor::kVectorIndex); | 669 GetParameter(CreateWeakCellDescriptor::kVectorIndex); |
| 670 HInstruction* slot = GetParameter(CreateWeakCellDescriptor::kSlotIndex); | 670 HInstruction* slot = GetParameter(CreateWeakCellDescriptor::kSlotIndex); |
| 671 Add<HStoreKeyed>(feedback_vector, slot, object, FAST_ELEMENTS, | 671 Add<HStoreKeyed>(feedback_vector, slot, object, nullptr, FAST_ELEMENTS, |
| 672 INITIALIZING_STORE); | 672 INITIALIZING_STORE); |
| 673 return graph()->GetConstant0(); | 673 return graph()->GetConstant0(); |
| 674 } | 674 } |
| 675 | 675 |
| 676 | 676 |
| 677 Handle<Code> CreateWeakCellStub::GenerateCode() { return DoGenerateCode(this); } | 677 Handle<Code> CreateWeakCellStub::GenerateCode() { return DoGenerateCode(this); } |
| 678 | 678 |
| 679 | 679 |
| 680 template <> | 680 template <> |
| 681 HValue* CodeStubGraphBuilder<LoadScriptContextFieldStub>::BuildCodeStub() { | 681 HValue* CodeStubGraphBuilder<LoadScriptContextFieldStub>::BuildCodeStub() { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 } | 817 } |
| 818 | 818 |
| 819 | 819 |
| 820 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } | 820 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } |
| 821 | 821 |
| 822 | 822 |
| 823 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key, | 823 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key, |
| 824 HValue* value) { | 824 HValue* value) { |
| 825 HValue* result = NULL; | 825 HValue* result = NULL; |
| 826 HInstruction* backing_store = | 826 HInstruction* backing_store = |
| 827 Add<HLoadKeyed>(elements, graph()->GetConstant1(), nullptr, FAST_ELEMENTS, | 827 Add<HLoadKeyed>(elements, graph()->GetConstant1(), nullptr, nullptr, |
| 828 ALLOW_RETURN_HOLE); | 828 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 829 Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map()); | 829 Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map()); |
| 830 HValue* backing_store_length = Add<HLoadNamedField>( | 830 HValue* backing_store_length = Add<HLoadNamedField>( |
| 831 backing_store, nullptr, HObjectAccess::ForFixedArrayLength()); | 831 backing_store, nullptr, HObjectAccess::ForFixedArrayLength()); |
| 832 IfBuilder in_unmapped_range(this); | 832 IfBuilder in_unmapped_range(this); |
| 833 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length, | 833 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length, |
| 834 Token::LT); | 834 Token::LT); |
| 835 in_unmapped_range.Then(); | 835 in_unmapped_range.Then(); |
| 836 { | 836 { |
| 837 if (value == NULL) { | 837 if (value == NULL) { |
| 838 result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS, | 838 result = Add<HLoadKeyed>(backing_store, key, nullptr, nullptr, |
| 839 NEVER_RETURN_HOLE); | 839 FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE); |
| 840 } else { | 840 } else { |
| 841 Add<HStoreKeyed>(backing_store, key, value, FAST_HOLEY_ELEMENTS); | 841 Add<HStoreKeyed>(backing_store, key, value, nullptr, FAST_HOLEY_ELEMENTS); |
| 842 } | 842 } |
| 843 } | 843 } |
| 844 in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange); | 844 in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange); |
| 845 in_unmapped_range.End(); | 845 in_unmapped_range.End(); |
| 846 return result; | 846 return result; |
| 847 } | 847 } |
| 848 | 848 |
| 849 | 849 |
| 850 HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver, | 850 HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver, |
| 851 HValue* key, | 851 HValue* key, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 HValue* constant_two = Add<HConstant>(2); | 888 HValue* constant_two = Add<HConstant>(2); |
| 889 HValue* elements = AddLoadElements(receiver, nullptr); | 889 HValue* elements = AddLoadElements(receiver, nullptr); |
| 890 HValue* elements_length = Add<HLoadNamedField>( | 890 HValue* elements_length = Add<HLoadNamedField>( |
| 891 elements, nullptr, HObjectAccess::ForFixedArrayLength()); | 891 elements, nullptr, HObjectAccess::ForFixedArrayLength()); |
| 892 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two); | 892 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two); |
| 893 IfBuilder in_range(this); | 893 IfBuilder in_range(this); |
| 894 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT); | 894 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT); |
| 895 in_range.Then(); | 895 in_range.Then(); |
| 896 { | 896 { |
| 897 HValue* index = AddUncasted<HAdd>(key, constant_two); | 897 HValue* index = AddUncasted<HAdd>(key, constant_two); |
| 898 HInstruction* mapped_index = Add<HLoadKeyed>( | 898 HInstruction* mapped_index = |
| 899 elements, index, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); | 899 Add<HLoadKeyed>(elements, index, nullptr, nullptr, FAST_HOLEY_ELEMENTS, |
| 900 ALLOW_RETURN_HOLE); |
| 900 | 901 |
| 901 IfBuilder is_valid(this); | 902 IfBuilder is_valid(this); |
| 902 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index, | 903 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index, |
| 903 graph()->GetConstantHole()); | 904 graph()->GetConstantHole()); |
| 904 is_valid.Then(); | 905 is_valid.Then(); |
| 905 { | 906 { |
| 906 // TODO(mvstanton): I'd like to assert from this point, that if the | 907 // TODO(mvstanton): I'd like to assert from this point, that if the |
| 907 // mapped_index is not the hole that it is indeed, a smi. An unnecessary | 908 // mapped_index is not the hole that it is indeed, a smi. An unnecessary |
| 908 // smi check is being emitted. | 909 // smi check is being emitted. |
| 909 HValue* the_context = Add<HLoadKeyed>(elements, graph()->GetConstant0(), | 910 HValue* the_context = Add<HLoadKeyed>(elements, graph()->GetConstant0(), |
| 910 nullptr, FAST_ELEMENTS); | 911 nullptr, nullptr, FAST_ELEMENTS); |
| 911 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); | 912 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); |
| 912 if (is_load) { | 913 if (is_load) { |
| 913 HValue* result = Add<HLoadKeyed>(the_context, mapped_index, nullptr, | 914 HValue* result = |
| 914 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 915 Add<HLoadKeyed>(the_context, mapped_index, nullptr, nullptr, |
| 916 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 915 environment()->Push(result); | 917 environment()->Push(result); |
| 916 } else { | 918 } else { |
| 917 DCHECK(value != NULL); | 919 DCHECK(value != NULL); |
| 918 Add<HStoreKeyed>(the_context, mapped_index, value, FAST_ELEMENTS); | 920 Add<HStoreKeyed>(the_context, mapped_index, value, nullptr, |
| 921 FAST_ELEMENTS); |
| 919 environment()->Push(value); | 922 environment()->Push(value); |
| 920 } | 923 } |
| 921 } | 924 } |
| 922 is_valid.Else(); | 925 is_valid.Else(); |
| 923 { | 926 { |
| 924 HValue* result = UnmappedCase(elements, key, value); | 927 HValue* result = UnmappedCase(elements, key, value); |
| 925 environment()->Push(is_load ? result : value); | 928 environment()->Push(is_load ? result : value); |
| 926 } | 929 } |
| 927 is_valid.End(); | 930 is_valid.End(); |
| 928 } | 931 } |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 // Now populate the elements correctly. | 1270 // Now populate the elements correctly. |
| 1268 LoopBuilder builder(this, | 1271 LoopBuilder builder(this, |
| 1269 context(), | 1272 context(), |
| 1270 LoopBuilder::kPostIncrement); | 1273 LoopBuilder::kPostIncrement); |
| 1271 HValue* start = graph()->GetConstant0(); | 1274 HValue* start = graph()->GetConstant0(); |
| 1272 HValue* key = builder.BeginBody(start, checked_length, Token::LT); | 1275 HValue* key = builder.BeginBody(start, checked_length, Token::LT); |
| 1273 HInstruction* argument_elements = Add<HArgumentsElements>(false); | 1276 HInstruction* argument_elements = Add<HArgumentsElements>(false); |
| 1274 HInstruction* argument = Add<HAccessArgumentsAt>( | 1277 HInstruction* argument = Add<HAccessArgumentsAt>( |
| 1275 argument_elements, checked_length, key); | 1278 argument_elements, checked_length, key); |
| 1276 | 1279 |
| 1277 Add<HStoreKeyed>(elements, key, argument, kind); | 1280 Add<HStoreKeyed>(elements, key, argument, nullptr, kind); |
| 1278 builder.EndBody(); | 1281 builder.EndBody(); |
| 1279 return new_object; | 1282 return new_object; |
| 1280 } | 1283 } |
| 1281 | 1284 |
| 1282 | 1285 |
| 1283 template <> | 1286 template <> |
| 1284 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { | 1287 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { |
| 1285 ElementsKind kind = casted_stub()->elements_kind(); | 1288 ElementsKind kind = casted_stub()->elements_kind(); |
| 1286 AllocationSiteOverrideMode override_mode = casted_stub()->override_mode(); | 1289 AllocationSiteOverrideMode override_mode = casted_stub()->override_mode(); |
| 1287 return BuildArrayConstructor(kind, override_mode, NONE); | 1290 return BuildArrayConstructor(kind, override_mode, NONE); |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 HValue* iterator, | 1901 HValue* iterator, |
| 1899 int field_offset) { | 1902 int field_offset) { |
| 1900 // By making sure to express these loads in the form [<hvalue> + constant] | 1903 // By making sure to express these loads in the form [<hvalue> + constant] |
| 1901 // the keyed load can be hoisted. | 1904 // the keyed load can be hoisted. |
| 1902 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength); | 1905 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength); |
| 1903 HValue* field_slot = iterator; | 1906 HValue* field_slot = iterator; |
| 1904 if (field_offset > 0) { | 1907 if (field_offset > 0) { |
| 1905 HValue* field_offset_value = Add<HConstant>(field_offset); | 1908 HValue* field_offset_value = Add<HConstant>(field_offset); |
| 1906 field_slot = AddUncasted<HAdd>(iterator, field_offset_value); | 1909 field_slot = AddUncasted<HAdd>(iterator, field_offset_value); |
| 1907 } | 1910 } |
| 1908 HInstruction* field_entry = | 1911 HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot, |
| 1909 Add<HLoadKeyed>(optimized_map, field_slot, nullptr, FAST_ELEMENTS); | 1912 nullptr, nullptr, FAST_ELEMENTS); |
| 1910 return field_entry; | 1913 return field_entry; |
| 1911 } | 1914 } |
| 1912 | 1915 |
| 1913 | 1916 |
| 1914 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( | 1917 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( |
| 1915 HValue* js_function, | 1918 HValue* js_function, |
| 1916 HValue* shared_info, | 1919 HValue* shared_info, |
| 1917 HValue* native_context) { | 1920 HValue* native_context) { |
| 1918 Counters* counters = isolate()->counters(); | 1921 Counters* counters = isolate()->counters(); |
| 1919 Factory* factory = isolate()->factory(); | 1922 Factory* factory = isolate()->factory(); |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2319 int probe_base = probe * KeyedLookupCache::kEntryLength; | 2322 int probe_base = probe * KeyedLookupCache::kEntryLength; |
| 2320 HValue* map_index = AddUncasted<HAdd>( | 2323 HValue* map_index = AddUncasted<HAdd>( |
| 2321 base_index, | 2324 base_index, |
| 2322 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); | 2325 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); |
| 2323 map_index->ClearFlag(HValue::kCanOverflow); | 2326 map_index->ClearFlag(HValue::kCanOverflow); |
| 2324 HValue* key_index = AddUncasted<HAdd>( | 2327 HValue* key_index = AddUncasted<HAdd>( |
| 2325 base_index, | 2328 base_index, |
| 2326 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); | 2329 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); |
| 2327 key_index->ClearFlag(HValue::kCanOverflow); | 2330 key_index->ClearFlag(HValue::kCanOverflow); |
| 2328 HValue* map_to_check = | 2331 HValue* map_to_check = |
| 2329 Add<HLoadKeyed>(cache_keys, map_index, nullptr, FAST_ELEMENTS, | 2332 Add<HLoadKeyed>(cache_keys, map_index, nullptr, nullptr, |
| 2330 NEVER_RETURN_HOLE, 0); | 2333 FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); |
| 2331 lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map); | 2334 lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map); |
| 2332 lookup_if->And(); | 2335 lookup_if->And(); |
| 2333 HValue* key_to_check = | 2336 HValue* key_to_check = |
| 2334 Add<HLoadKeyed>(cache_keys, key_index, nullptr, FAST_ELEMENTS, | 2337 Add<HLoadKeyed>(cache_keys, key_index, nullptr, nullptr, |
| 2335 NEVER_RETURN_HOLE, 0); | 2338 FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); |
| 2336 lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key); | 2339 lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key); |
| 2337 lookup_if->Then(); | 2340 lookup_if->Then(); |
| 2338 { | 2341 { |
| 2339 ExternalReference cache_field_offsets_ref = | 2342 ExternalReference cache_field_offsets_ref = |
| 2340 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); | 2343 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); |
| 2341 HValue* cache_field_offsets = | 2344 HValue* cache_field_offsets = |
| 2342 Add<HConstant>(cache_field_offsets_ref); | 2345 Add<HConstant>(cache_field_offsets_ref); |
| 2343 HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe)); | 2346 HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe)); |
| 2344 index->ClearFlag(HValue::kCanOverflow); | 2347 index->ClearFlag(HValue::kCanOverflow); |
| 2345 HValue* property_index = | 2348 HValue* property_index = |
| 2346 Add<HLoadKeyed>(cache_field_offsets, index, nullptr, | 2349 Add<HLoadKeyed>(cache_field_offsets, index, nullptr, cache_keys, |
| 2347 INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); | 2350 INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); |
| 2348 Push(property_index); | 2351 Push(property_index); |
| 2349 } | 2352 } |
| 2350 lookup_if->Else(); | 2353 lookup_if->Else(); |
| 2351 } | 2354 } |
| 2352 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { | 2355 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { |
| 2353 lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation); | 2356 lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation); |
| 2354 } | 2357 } |
| 2355 } | 2358 } |
| 2356 | 2359 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2379 return Pop(); | 2382 return Pop(); |
| 2380 } | 2383 } |
| 2381 | 2384 |
| 2382 | 2385 |
| 2383 Handle<Code> KeyedLoadGenericStub::GenerateCode() { | 2386 Handle<Code> KeyedLoadGenericStub::GenerateCode() { |
| 2384 return DoGenerateCode(this); | 2387 return DoGenerateCode(this); |
| 2385 } | 2388 } |
| 2386 | 2389 |
| 2387 } // namespace internal | 2390 } // namespace internal |
| 2388 } // namespace v8 | 2391 } // namespace v8 |
| OLD | NEW |