Chromium Code Reviews| 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 |