Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: src/code-stub-assembler.cc

Issue 2680973002: [stubs] Implement binary-search descriptor lookup in CSA (Closed)
Patch Set: rebased Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ic/accessor-assembler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
7 #include "src/frames.h" 7 #include "src/frames.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 4703 matching lines...) Expand 10 before | Expand all | Expand 10 after
4714 } 4714 }
4715 4715
4716 template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*, 4716 template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*,
4717 Label*); 4717 Label*);
4718 4718
4719 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, 4719 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name,
4720 Node* descriptors, Node* nof, 4720 Node* descriptors, Node* nof,
4721 Label* if_found, 4721 Label* if_found,
4722 Variable* var_name_index, 4722 Variable* var_name_index,
4723 Label* if_not_found) { 4723 Label* if_not_found) {
4724 Comment("DescriptorLookupLinear");
4724 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); 4725 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0));
4725 Node* factor = IntPtrConstant(DescriptorArray::kEntrySize); 4726 Node* factor = IntPtrConstant(DescriptorArray::kEntrySize);
4726 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor)); 4727 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor));
4727 4728
4728 BuildFastLoop(last_exclusive, first_inclusive, 4729 BuildFastLoop(last_exclusive, first_inclusive,
4729 [this, descriptors, unique_name, if_found, 4730 [this, descriptors, unique_name, if_found,
4730 var_name_index](Node* name_index) { 4731 var_name_index](Node* name_index) {
4731 Node* candidate_name = 4732 Node* candidate_name =
4732 LoadFixedArrayElement(descriptors, name_index); 4733 LoadFixedArrayElement(descriptors, name_index);
4733 var_name_index->Bind(name_index); 4734 var_name_index->Bind(name_index);
4734 GotoIf(WordEqual(candidate_name, unique_name), if_found); 4735 GotoIf(WordEqual(candidate_name, unique_name), if_found);
4735 }, 4736 },
4736 -DescriptorArray::kEntrySize, INTPTR_PARAMETERS, 4737 -DescriptorArray::kEntrySize, INTPTR_PARAMETERS,
4737 IndexAdvanceMode::kPre); 4738 IndexAdvanceMode::kPre);
4738 Goto(if_not_found); 4739 Goto(if_not_found);
4739 } 4740 }
4740 4741
4742 Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) {
4743 return LoadAndUntagToWord32FixedArrayElement(
4744 descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex));
4745 }
4746
4747 namespace {
4748
4749 Node* DescriptorNumberToIndex(CodeStubAssembler* a, Node* descriptor_number) {
4750 Node* descriptor_size = a->Int32Constant(DescriptorArray::kEntrySize);
4751 Node* index = a->Int32Mul(descriptor_number, descriptor_size);
4752 return a->ChangeInt32ToIntPtr(index);
4753 }
4754
4755 } // namespace
4756
4757 Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) {
4758 return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
4759 DescriptorNumberToIndex(this, descriptor_number));
4760 }
4761
4762 Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex(
4763 Node* descriptors, Node* descriptor_number) {
4764 const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
4765 Node* details = LoadAndUntagToWord32FixedArrayElement(
4766 descriptors, DescriptorNumberToIndex(this, descriptor_number),
4767 details_offset);
4768 return DecodeWord32<PropertyDetails::DescriptorPointer>(details);
4769 }
4770
4771 Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors,
4772 Node* descriptor_number) {
4773 const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize;
4774 return LoadFixedArrayElement(descriptors,
4775 DescriptorNumberToIndex(this, descriptor_number),
4776 key_offset);
4777 }
4778
4779 void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
4780 Node* descriptors, Node* nof,
4781 Label* if_found,
4782 Variable* var_name_index,
4783 Label* if_not_found) {
4784 Comment("DescriptorLookupBinary");
4785 Variable var_low(this, MachineRepresentation::kWord32, Int32Constant(0));
4786 Node* limit =
4787 Int32Sub(DescriptorArrayNumberOfEntries(descriptors), Int32Constant(1));
4788 Variable var_high(this, MachineRepresentation::kWord32, limit);
4789 Node* hash = LoadNameHashField(unique_name);
4790 CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0)));
4791
4792 // Assume non-empty array.
4793 CSA_ASSERT(this, Uint32LessThanOrEqual(var_low.value(), var_high.value()));
4794
4795 Variable* loop_vars[] = {&var_high, &var_low};
4796 Label binary_loop(this, 2, loop_vars);
4797 Goto(&binary_loop);
4798 Bind(&binary_loop);
4799 {
4800 // mid = low + (high - low) / 2 (to avoid overflow in "(low + high) / 2").
4801 Node* mid =
4802 Int32Add(var_low.value(),
4803 Word32Shr(Int32Sub(var_high.value(), var_low.value()), 1));
4804 // mid_name = descriptors->GetSortedKey(mid).
4805 Node* sorted_key_index = DescriptorArrayGetSortedKeyIndex(descriptors, mid);
4806 Node* mid_name = DescriptorArrayGetKey(descriptors, sorted_key_index);
4807
4808 Node* mid_hash = LoadNameHashField(mid_name);
4809
4810 Label mid_greater(this), mid_less(this), merge(this);
4811 Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less);
4812 Bind(&mid_greater);
4813 {
4814 var_high.Bind(mid);
4815 Goto(&merge);
4816 }
4817 Bind(&mid_less);
4818 {
4819 var_low.Bind(Int32Add(mid, Int32Constant(1)));
4820 Goto(&merge);
4821 }
4822 Bind(&merge);
4823 GotoIf(Word32NotEqual(var_low.value(), var_high.value()), &binary_loop);
4824 }
4825
4826 Label scan_loop(this, &var_low);
4827 Goto(&scan_loop);
4828 Bind(&scan_loop);
4829 {
4830 GotoIf(Int32GreaterThan(var_low.value(), limit), if_not_found);
4831
4832 Node* sort_index =
4833 DescriptorArrayGetSortedKeyIndex(descriptors, var_low.value());
4834 Node* current_name = DescriptorArrayGetKey(descriptors, sort_index);
4835 Node* current_hash = LoadNameHashField(current_name);
4836 GotoIf(Word32NotEqual(current_hash, hash), if_not_found);
4837 Label next(this);
4838 GotoIf(WordNotEqual(current_name, unique_name), &next);
4839 GotoIf(Int32GreaterThanOrEqual(sort_index, nof), if_not_found);
4840 var_name_index->Bind(DescriptorArrayToKeyIndex(sort_index));
4841 Goto(if_found);
4842
4843 Bind(&next);
4844 var_low.Bind(Int32Add(var_low.value(), Int32Constant(1)));
4845 Goto(&scan_loop);
4846 }
4847 }
4848
4849 void CodeStubAssembler::DescriptorLookup(Node* unique_name, Node* descriptors,
4850 Node* bitfield3, Label* if_found,
4851 Variable* var_name_index,
4852 Label* if_not_found) {
4853 Comment("DescriptorArrayLookup");
4854 Node* nof = DecodeWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3);
4855 GotoIf(Word32Equal(nof, Int32Constant(0)), if_not_found);
4856 Label linear_search(this), binary_search(this);
4857 const int kMaxElementsForLinearSearch = 32;
4858 Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxElementsForLinearSearch)),
4859 &linear_search, &binary_search);
4860 Bind(&linear_search);
4861 {
4862 DescriptorLookupLinear(unique_name, descriptors, ChangeInt32ToIntPtr(nof),
4863 if_found, var_name_index, if_not_found);
4864 }
4865 Bind(&binary_search);
4866 {
4867 DescriptorLookupBinary(unique_name, descriptors, nof, if_found,
4868 var_name_index, if_not_found);
4869 }
4870 }
4871
4741 void CodeStubAssembler::TryLookupProperty( 4872 void CodeStubAssembler::TryLookupProperty(
4742 Node* object, Node* map, Node* instance_type, Node* unique_name, 4873 Node* object, Node* map, Node* instance_type, Node* unique_name,
4743 Label* if_found_fast, Label* if_found_dict, Label* if_found_global, 4874 Label* if_found_fast, Label* if_found_dict, Label* if_found_global,
4744 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, 4875 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found,
4745 Label* if_bailout) { 4876 Label* if_bailout) {
4746 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); 4877 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep());
4747 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); 4878 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep());
4748 4879
4749 Label if_objectisspecial(this); 4880 Label if_objectisspecial(this);
4750 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); 4881 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
4751 GotoIf(Int32LessThanOrEqual(instance_type, 4882 GotoIf(Int32LessThanOrEqual(instance_type,
4752 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 4883 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
4753 &if_objectisspecial); 4884 &if_objectisspecial);
4754 4885
4755 uint32_t mask = 4886 uint32_t mask =
4756 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; 4887 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded;
4757 CSA_ASSERT(this, Word32BinaryNot(IsSetWord32(LoadMapBitField(map), mask))); 4888 CSA_ASSERT(this, Word32BinaryNot(IsSetWord32(LoadMapBitField(map), mask)));
4758 USE(mask); 4889 USE(mask);
4759 4890
4760 Node* bit_field3 = LoadMapBitField3(map); 4891 Node* bit_field3 = LoadMapBitField3(map);
4761 Label if_isfastmap(this), if_isslowmap(this); 4892 Label if_isfastmap(this), if_isslowmap(this);
4762 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap, 4893 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap,
4763 &if_isfastmap); 4894 &if_isfastmap);
4764 Bind(&if_isfastmap); 4895 Bind(&if_isfastmap);
4765 { 4896 {
4766 Comment("DescriptorArrayLookup");
4767 Node* nof =
4768 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3);
4769 // Bail out to the runtime for large numbers of own descriptors. The stub
4770 // only does linear search, which becomes too expensive in that case.
4771 {
4772 static const int32_t kMaxLinear = 210;
4773 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout);
4774 }
4775 Node* descriptors = LoadMapDescriptors(map); 4897 Node* descriptors = LoadMapDescriptors(map);
4776 var_meta_storage->Bind(descriptors); 4898 var_meta_storage->Bind(descriptors);
4777 4899
4778 DescriptorLookupLinear(unique_name, descriptors, nof, if_found_fast, 4900 DescriptorLookup(unique_name, descriptors, bit_field3, if_found_fast,
4779 var_name_index, if_not_found); 4901 var_name_index, if_not_found);
4780 } 4902 }
4781 Bind(&if_isslowmap); 4903 Bind(&if_isslowmap);
4782 { 4904 {
4783 Node* dictionary = LoadProperties(object); 4905 Node* dictionary = LoadProperties(object);
4784 var_meta_storage->Bind(dictionary); 4906 var_meta_storage->Bind(dictionary);
4785 4907
4786 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict, 4908 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict,
4787 var_name_index, if_not_found); 4909 var_name_index, if_not_found);
4788 } 4910 }
4789 Bind(&if_objectisspecial); 4911 Bind(&if_objectisspecial);
(...skipping 3536 matching lines...) Expand 10 before | Expand all | Expand 10 after
8326 formatted.c_str(), TENURED); 8448 formatted.c_str(), TENURED);
8327 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), 8449 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(),
8328 HeapConstant(string)); 8450 HeapConstant(string));
8329 } 8451 }
8330 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); 8452 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value);
8331 #endif 8453 #endif
8332 } 8454 }
8333 8455
8334 } // namespace internal 8456 } // namespace internal
8335 } // namespace v8 8457 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ic/accessor-assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698