OLD | NEW |
---|---|
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 4730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4741 } | 4741 } |
4742 | 4742 |
4743 template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*, | 4743 template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*, |
4744 Label*); | 4744 Label*); |
4745 | 4745 |
4746 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, | 4746 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, |
4747 Node* descriptors, Node* nof, | 4747 Node* descriptors, Node* nof, |
4748 Label* if_found, | 4748 Label* if_found, |
4749 Variable* var_name_index, | 4749 Variable* var_name_index, |
4750 Label* if_not_found) { | 4750 Label* if_not_found) { |
4751 Comment("DescriptorLookupLinear"); | |
4751 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); | 4752 Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); |
4752 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); | 4753 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); |
4753 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor)); | 4754 Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor)); |
4754 | 4755 |
4755 BuildFastLoop(last_exclusive, first_inclusive, | 4756 BuildFastLoop(last_exclusive, first_inclusive, |
4756 [this, descriptors, unique_name, if_found, | 4757 [this, descriptors, unique_name, if_found, |
4757 var_name_index](Node* name_index) { | 4758 var_name_index](Node* name_index) { |
4758 Node* candidate_name = | 4759 Node* candidate_name = |
4759 LoadFixedArrayElement(descriptors, name_index); | 4760 LoadFixedArrayElement(descriptors, name_index); |
4760 var_name_index->Bind(name_index); | 4761 var_name_index->Bind(name_index); |
4761 GotoIf(WordEqual(candidate_name, unique_name), if_found); | 4762 GotoIf(WordEqual(candidate_name, unique_name), if_found); |
4762 }, | 4763 }, |
4763 -DescriptorArray::kDescriptorSize, INTPTR_PARAMETERS, | 4764 -DescriptorArray::kDescriptorSize, INTPTR_PARAMETERS, |
4764 IndexAdvanceMode::kPre); | 4765 IndexAdvanceMode::kPre); |
4765 Goto(if_not_found); | 4766 Goto(if_not_found); |
4766 } | 4767 } |
4767 | 4768 |
4769 Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) { | |
4770 return LoadAndUntagToWord32FixedArrayElement( | |
4771 descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)); | |
4772 } | |
4773 | |
4774 namespace { | |
4775 | |
4776 Node* DescriptorNumberToIndex(CodeStubAssembler* a, Node* descriptor_number) { | |
4777 Node* descriptor_size = a->Int32Constant(DescriptorArray::kDescriptorSize); | |
4778 Node* index = a->Int32Mul(descriptor_number, descriptor_size); | |
4779 return a->ChangeInt32ToIntPtr(index); | |
4780 } | |
4781 | |
4782 } // namespace | |
4783 | |
4784 Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) { | |
4785 return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)), | |
4786 DescriptorNumberToIndex(this, descriptor_number)); | |
4787 } | |
4788 | |
4789 Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex( | |
4790 Node* descriptors, Node* descriptor_number) { | |
4791 const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize; | |
4792 Node* details = LoadAndUntagToWord32FixedArrayElement( | |
4793 descriptors, DescriptorNumberToIndex(this, descriptor_number), | |
4794 details_offset); | |
4795 return DecodeWord32<PropertyDetails::DescriptorPointer>(details); | |
4796 } | |
4797 | |
4798 Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors, | |
4799 Node* descriptor_number) { | |
4800 const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize; | |
4801 return LoadFixedArrayElement(descriptors, | |
4802 DescriptorNumberToIndex(this, descriptor_number), | |
4803 key_offset); | |
4804 } | |
4805 | |
4806 void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name, | |
4807 Node* descriptors, Node* nof, | |
4808 Label* if_found, | |
4809 Variable* var_name_index, | |
4810 Label* if_not_found) { | |
4811 Comment("DescriptorLookupBinary"); | |
4812 Variable var_low(this, MachineRepresentation::kWord32, Int32Constant(0)); | |
4813 Node* limit = | |
4814 Int32Sub(DescriptorArrayNumberOfEntries(descriptors), Int32Constant(1)); | |
4815 Variable var_high(this, MachineRepresentation::kWord32, limit); | |
4816 Node* hash = LoadNameHashField(unique_name); | |
4817 CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0))); | |
4818 | |
4819 // Assume non-empty array. | |
4820 CSA_ASSERT(this, Uint32LessThanOrEqual(var_low.value(), var_high.value())); | |
4821 | |
4822 Variable* loop_vars[] = {&var_high, &var_low}; | |
4823 Label binary_loop(this, 2, loop_vars); | |
4824 Goto(&binary_loop); | |
4825 Bind(&binary_loop); | |
4826 { | |
4827 // mid = low + (high - low) / 2 (to avoid overflow in "(low + high) / 2"). | |
4828 Node* mid = | |
4829 Int32Add(var_low.value(), | |
4830 Word32Shr(Int32Sub(var_high.value(), var_low.value()), 1)); | |
4831 // mid_name = descriptors->GetSortedKey(mid). | |
4832 Node* sorted_key_index = DescriptorArrayGetSortedKeyIndex(descriptors, mid); | |
4833 Node* mid_name = DescriptorArrayGetKey(descriptors, sorted_key_index); | |
4834 | |
4835 Node* mid_hash = LoadNameHashField(mid_name); | |
4836 | |
4837 Label mid_greater(this), mid_less(this), merge(this); | |
4838 Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less); | |
4839 Bind(&mid_greater); | |
4840 { | |
4841 var_high.Bind(mid); | |
4842 Goto(&merge); | |
4843 } | |
4844 Bind(&mid_less); | |
4845 { | |
4846 var_low.Bind(Int32Add(mid, Int32Constant(1))); | |
4847 Goto(&merge); | |
4848 } | |
4849 Bind(&merge); | |
4850 GotoIf(Word32NotEqual(var_low.value(), var_high.value()), &binary_loop); | |
4851 } | |
4852 | |
4853 Label scan_loop(this, &var_low); | |
4854 Goto(&scan_loop); | |
4855 Bind(&scan_loop); | |
4856 { | |
4857 GotoIf(Int32GreaterThan(var_low.value(), limit), if_not_found); | |
4858 | |
4859 Node* sort_index = | |
4860 DescriptorArrayGetSortedKeyIndex(descriptors, var_low.value()); | |
4861 Node* entry = DescriptorArrayGetKey(descriptors, sort_index); | |
Igor Sheludko
2017/02/09 23:52:07
Maybe s/entry/current_name/ ?
Jakob Kummerow
2017/02/10 00:50:57
Done.
| |
4862 Node* current_hash = LoadNameHashField(entry); | |
4863 GotoIf(Word32NotEqual(current_hash, hash), if_not_found); | |
4864 Label next(this); | |
4865 GotoIf(WordNotEqual(entry, unique_name), &next); | |
4866 GotoIf(Int32GreaterThanOrEqual(sort_index, nof), if_not_found); | |
4867 var_name_index->Bind(DescriptorArrayToKeyIndex(sort_index)); | |
4868 Goto(if_found); | |
4869 | |
4870 Bind(&next); | |
4871 var_low.Bind(Int32Add(var_low.value(), Int32Constant(1))); | |
4872 Goto(&scan_loop); | |
4873 } | |
4874 } | |
4875 | |
4876 void CodeStubAssembler::DescriptorLookup(Node* unique_name, Node* descriptors, | |
4877 Node* bitfield3, Label* if_found, | |
4878 Variable* var_name_index, | |
4879 Label* if_not_found) { | |
4880 Comment("DescriptorArrayLookup"); | |
4881 Node* nof = DecodeWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3); | |
4882 GotoIf(Word32Equal(nof, Int32Constant(0)), if_not_found); | |
4883 Label linear_search(this), binary_search(this); | |
4884 const int kMaxElementsForLinearSearch = 32; | |
4885 Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxElementsForLinearSearch)), | |
4886 &linear_search, &binary_search); | |
4887 Bind(&linear_search); | |
4888 { | |
4889 DescriptorLookupLinear(unique_name, descriptors, ChangeInt32ToIntPtr(nof), | |
4890 if_found, var_name_index, if_not_found); | |
4891 } | |
4892 Bind(&binary_search); | |
4893 { | |
4894 DescriptorLookupBinary(unique_name, descriptors, nof, if_found, | |
4895 var_name_index, if_not_found); | |
4896 } | |
4897 } | |
4898 | |
4768 void CodeStubAssembler::TryLookupProperty( | 4899 void CodeStubAssembler::TryLookupProperty( |
4769 Node* object, Node* map, Node* instance_type, Node* unique_name, | 4900 Node* object, Node* map, Node* instance_type, Node* unique_name, |
4770 Label* if_found_fast, Label* if_found_dict, Label* if_found_global, | 4901 Label* if_found_fast, Label* if_found_dict, Label* if_found_global, |
4771 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, | 4902 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, |
4772 Label* if_bailout) { | 4903 Label* if_bailout) { |
4773 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); | 4904 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); |
4774 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 4905 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
4775 | 4906 |
4776 Label if_objectisspecial(this); | 4907 Label if_objectisspecial(this); |
4777 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 4908 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
4778 GotoIf(Int32LessThanOrEqual(instance_type, | 4909 GotoIf(Int32LessThanOrEqual(instance_type, |
4779 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), | 4910 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), |
4780 &if_objectisspecial); | 4911 &if_objectisspecial); |
4781 | 4912 |
4782 uint32_t mask = | 4913 uint32_t mask = |
4783 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; | 4914 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
4784 CSA_ASSERT(this, Word32BinaryNot(IsSetWord32(LoadMapBitField(map), mask))); | 4915 CSA_ASSERT(this, Word32BinaryNot(IsSetWord32(LoadMapBitField(map), mask))); |
4785 USE(mask); | 4916 USE(mask); |
4786 | 4917 |
4787 Node* bit_field3 = LoadMapBitField3(map); | 4918 Node* bit_field3 = LoadMapBitField3(map); |
4788 Label if_isfastmap(this), if_isslowmap(this); | 4919 Label if_isfastmap(this), if_isslowmap(this); |
4789 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap, | 4920 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap, |
4790 &if_isfastmap); | 4921 &if_isfastmap); |
4791 Bind(&if_isfastmap); | 4922 Bind(&if_isfastmap); |
4792 { | 4923 { |
4793 Comment("DescriptorArrayLookup"); | |
4794 Node* nof = | |
4795 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3); | |
4796 // Bail out to the runtime for large numbers of own descriptors. The stub | |
4797 // only does linear search, which becomes too expensive in that case. | |
4798 { | |
4799 static const int32_t kMaxLinear = 210; | |
4800 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout); | |
4801 } | |
4802 Node* descriptors = LoadMapDescriptors(map); | 4924 Node* descriptors = LoadMapDescriptors(map); |
4803 var_meta_storage->Bind(descriptors); | 4925 var_meta_storage->Bind(descriptors); |
4804 | 4926 |
4805 DescriptorLookupLinear(unique_name, descriptors, nof, if_found_fast, | 4927 DescriptorLookup(unique_name, descriptors, bit_field3, if_found_fast, |
4806 var_name_index, if_not_found); | 4928 var_name_index, if_not_found); |
4807 } | 4929 } |
4808 Bind(&if_isslowmap); | 4930 Bind(&if_isslowmap); |
4809 { | 4931 { |
4810 Node* dictionary = LoadProperties(object); | 4932 Node* dictionary = LoadProperties(object); |
4811 var_meta_storage->Bind(dictionary); | 4933 var_meta_storage->Bind(dictionary); |
4812 | 4934 |
4813 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict, | 4935 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict, |
4814 var_name_index, if_not_found); | 4936 var_name_index, if_not_found); |
4815 } | 4937 } |
4816 Bind(&if_objectisspecial); | 4938 Bind(&if_objectisspecial); |
(...skipping 3557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8374 formatted.c_str(), TENURED); | 8496 formatted.c_str(), TENURED); |
8375 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 8497 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
8376 HeapConstant(string)); | 8498 HeapConstant(string)); |
8377 } | 8499 } |
8378 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 8500 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
8379 #endif | 8501 #endif |
8380 } | 8502 } |
8381 | 8503 |
8382 } // namespace internal | 8504 } // namespace internal |
8383 } // namespace v8 | 8505 } // namespace v8 |
OLD | NEW |