Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 989 __ movq(FieldOperand(rax, HeapObject::kMapOffset), | 989 __ movq(FieldOperand(rax, HeapObject::kMapOffset), |
| 990 heap_number_map); | 990 heap_number_map); |
| 991 __ cvtqsi2sd(xmm0, rbx); | 991 __ cvtqsi2sd(xmm0, rbx); |
| 992 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); | 992 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); |
| 993 __ Ret(); | 993 __ Ret(); |
| 994 | 994 |
| 995 __ bind(&allocation_failed); | 995 __ bind(&allocation_failed); |
| 996 // We need tagged values in rdx and rax for the following code, | 996 // We need tagged values in rdx and rax for the following code, |
| 997 // not int32 in rax and rcx. | 997 // not int32 in rax and rcx. |
| 998 __ Integer32ToSmi(rax, rcx); | 998 __ Integer32ToSmi(rax, rcx); |
| 999 __ Integer32ToSmi(rdx, rax); | 999 __ Integer32ToSmi(rdx, rbx); |
|
Mads Ager (chromium)
2011/05/05 11:54:56
This is fixed in Florian's commit too, right?
Vyacheslav Egorov (Chromium)
2011/05/05 12:30:16
Yep, this is accidental change.
| |
| 1000 __ jmp(allocation_failure); | 1000 __ jmp(allocation_failure); |
| 1001 } | 1001 } |
| 1002 break; | 1002 break; |
| 1003 } | 1003 } |
| 1004 default: UNREACHABLE(); break; | 1004 default: UNREACHABLE(); break; |
| 1005 } | 1005 } |
| 1006 // No fall-through from this generated code. | 1006 // No fall-through from this generated code. |
| 1007 if (FLAG_debug_code) { | 1007 if (FLAG_debug_code) { |
| 1008 __ Abort("Unexpected fall-through in " | 1008 __ Abort("Unexpected fall-through in " |
| 1009 "TypeRecordingBinaryStub::GenerateFloatingPointCode."); | 1009 "TypeRecordingBinaryStub::GenerateFloatingPointCode."); |
| (...skipping 3719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4729 __ pop(rcx); | 4729 __ pop(rcx); |
| 4730 __ pop(rax); | 4730 __ pop(rax); |
| 4731 __ pop(rdx); | 4731 __ pop(rdx); |
| 4732 __ push(rcx); | 4732 __ push(rcx); |
| 4733 | 4733 |
| 4734 // Do a tail call to the rewritten stub. | 4734 // Do a tail call to the rewritten stub. |
| 4735 __ jmp(rdi); | 4735 __ jmp(rdi); |
| 4736 } | 4736 } |
| 4737 | 4737 |
| 4738 | 4738 |
| 4739 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, | |
| 4740 Label* miss, | |
| 4741 Label* done, | |
| 4742 Register properties, | |
| 4743 String* name, | |
| 4744 Register r0) { | |
| 4745 // If names of slots in range from 1 to kProbes - 1 for the hash value are | |
| 4746 // not equal to the name and kProbes-th slot is not used (its name is the | |
| 4747 // undefined value), it guarantees the hash table doesn't contain the | |
| 4748 // property. It's true even if some slots represent deleted properties | |
| 4749 // (their names are the null value). | |
| 4750 for (int i = 0; i < kInlinedProbes; i++) { | |
| 4751 // r0 points to properties hash. | |
| 4752 // Compute the masked index: (hash + i + i * i) & mask. | |
| 4753 Register index = r0; | |
| 4754 // Capacity is smi 2^n. | |
| 4755 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); | |
| 4756 __ decl(index); | |
| 4757 __ and_(index, | |
|
Lasse Reichstein
2011/05/05 14:20:13
Use andl instead of and_, one byte shorter.
| |
| 4758 Immediate(name->Hash() + StringDictionary::GetProbeOffset(i))); | |
| 4759 | |
| 4760 // Scale the index by multiplying by the entry size. | |
| 4761 ASSERT(StringDictionary::kEntrySize == 3); | |
| 4762 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. | |
|
Lasse Reichstein
2011/05/05 14:20:13
Use leal instead of lea for 32-bit operations - un
| |
| 4763 | |
| 4764 Register entity_name = r0; | |
| 4765 // Having undefined at this place means the name is not contained. | |
| 4766 ASSERT_EQ(kSmiTagSize, 1); | |
| 4767 __ movq(entity_name, Operand(properties, | |
| 4768 index, | |
| 4769 times_pointer_size, | |
| 4770 kElementsStartOffset - kHeapObjectTag)); | |
| 4771 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value()); | |
|
Lasse Reichstein
2011/05/05 14:20:13
We typically use CompareRoot for this.
| |
| 4772 __ j(equal, done); | |
| 4773 | |
| 4774 // Stop if found the property. | |
| 4775 __ Cmp(entity_name, Handle<String>(name)); | |
| 4776 __ j(equal, miss); | |
| 4777 | |
| 4778 // Check if the entry name is not a symbol. | |
| 4779 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); | |
| 4780 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | |
| 4781 Immediate(kIsSymbolMask)); | |
| 4782 __ j(zero, miss); | |
| 4783 } | |
| 4784 | |
| 4785 StringDictionaryLookupStub stub(properties, | |
| 4786 r0, | |
| 4787 r0, | |
| 4788 StringDictionaryLookupStub::NEGATIVE_LOOKUP); | |
| 4789 __ Push(Handle<Object>(name)); | |
| 4790 __ push(Immediate(name->Hash())); | |
| 4791 __ CallStub(&stub); | |
| 4792 __ testq(r0, r0); | |
|
Lasse Reichstein
2011/05/05 14:20:13
If the result is guaranteed to have its nonzero bi
| |
| 4793 __ j(not_zero, miss); | |
| 4794 __ jmp(done); | |
| 4795 } | |
| 4796 | |
| 4797 | |
| 4798 // Probe the string dictionary in the |elements| register. Jump to the | |
| 4799 // |done| label if a property with the given name is found leaving the | |
| 4800 // index into the dictionary in |r1|. Jump to the |miss| label | |
| 4801 // otherwise. | |
| 4802 void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, | |
| 4803 Label* miss, | |
| 4804 Label* done, | |
| 4805 Register elements, | |
| 4806 Register name, | |
| 4807 Register r0, | |
| 4808 Register r1) { | |
| 4809 // Assert that name contains a string. | |
| 4810 if (FLAG_debug_code) __ AbortIfNotString(name); | |
| 4811 | |
| 4812 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset)); | |
| 4813 __ decl(r0); | |
| 4814 | |
| 4815 for (int i = 0; i < kInlinedProbes; i++) { | |
| 4816 // Compute the masked index: (hash + i + i * i) & mask. | |
| 4817 __ movl(r1, FieldOperand(name, String::kHashFieldOffset)); | |
| 4818 __ shrl(r1, Immediate(String::kHashShift)); | |
| 4819 if (i > 0) { | |
| 4820 __ addl(r1, Immediate(StringDictionary::GetProbeOffset(i))); | |
| 4821 } | |
| 4822 __ and_(r1, r0); | |
|
Lasse Reichstein
2011/05/05 14:20:13
andl
| |
| 4823 | |
| 4824 // Scale the index by multiplying by the entry size. | |
| 4825 ASSERT(StringDictionary::kEntrySize == 3); | |
| 4826 __ lea(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3 | |
|
Lasse Reichstein
2011/05/05 14:20:13
leal
| |
| 4827 | |
| 4828 // Check if the key is identical to the name. | |
| 4829 __ cmpq(name, Operand(elements, r1, times_pointer_size, | |
| 4830 kElementsStartOffset - kHeapObjectTag)); | |
| 4831 __ j(equal, done); | |
| 4832 } | |
| 4833 | |
| 4834 StringDictionaryLookupStub stub(elements, | |
| 4835 r0, | |
| 4836 r1, | |
| 4837 POSITIVE_LOOKUP); | |
| 4838 __ push(name); | |
| 4839 __ movl(r0, FieldOperand(name, String::kHashFieldOffset)); | |
| 4840 __ shrl(r0, Immediate(String::kHashShift)); | |
| 4841 __ push(r0); | |
| 4842 __ CallStub(&stub); | |
| 4843 | |
| 4844 __ testq(r0, r0); | |
|
Lasse Reichstein
2011/05/05 14:20:13
Possibly testl.
| |
| 4845 __ j(zero, miss); | |
| 4846 __ jmp(done); | |
| 4847 } | |
| 4848 | |
| 4849 | |
| 4850 void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { | |
| 4851 // Stack frame on entry: | |
| 4852 // esp[0 * kPointerSize]: return address. | |
|
Lasse Reichstein
2011/05/05 14:20:13
esp->rsp
| |
| 4853 // esp[1 * kPointerSize]: key's hash. | |
| 4854 // esp[2 * kPointerSize]: key. | |
| 4855 // Registers: | |
| 4856 // dictionary_: StringDictionary to probe. | |
| 4857 // result_: used as scratch. | |
| 4858 // index_: will hold an index of entry if lookup is successful. | |
| 4859 // might alias with result_. | |
| 4860 // Returns: | |
| 4861 // result_ is zero if lookup failed, non zero otherwise. | |
|
Lasse Reichstein
2011/05/05 14:20:13
Document that it's nonzero when used as a double-w
| |
| 4862 | |
| 4863 Label in_dictionary, maybe_in_dictionary, not_in_dictionary; | |
| 4864 | |
| 4865 Register scratch = result_; | |
| 4866 | |
| 4867 __ SmiToInteger32(scratch, FieldOperand(dictionary_, kCapacityOffset)); | |
| 4868 __ decl(scratch); | |
| 4869 __ push(scratch); | |
| 4870 | |
| 4871 // If names of slots in range from 1 to kProbes - 1 for the hash value are | |
| 4872 // not equal to the name and kProbes-th slot is not used (its name is the | |
| 4873 // undefined value), it guarantees the hash table doesn't contain the | |
| 4874 // property. It's true even if some slots represent deleted properties | |
| 4875 // (their names are the null value). | |
| 4876 for (int i = kInlinedProbes; i < kTotalProbes; i++) { | |
| 4877 // Compute the masked index: (hash + i + i * i) & mask. | |
| 4878 __ movq(scratch, Operand(rsp, 2 * kPointerSize)); | |
| 4879 if (i > 0) { | |
| 4880 __ addl(scratch, Immediate(StringDictionary::GetProbeOffset(i))); | |
| 4881 } | |
| 4882 __ and_(scratch, Operand(rsp, 0)); | |
|
Lasse Reichstein
2011/05/05 14:20:13
andl
| |
| 4883 | |
| 4884 // Scale the index by multiplying by the entry size. | |
| 4885 ASSERT(StringDictionary::kEntrySize == 3); | |
| 4886 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3. | |
|
Lasse Reichstein
2011/05/05 14:20:13
leal
| |
| 4887 | |
| 4888 // Having undefined at this place means the name is not contained. | |
| 4889 __ movq(scratch, Operand(dictionary_, | |
| 4890 index_, | |
| 4891 times_pointer_size, | |
| 4892 kElementsStartOffset - kHeapObjectTag)); | |
| 4893 | |
| 4894 __ Cmp(scratch, masm->isolate()->factory()->undefined_value()); | |
|
Lasse Reichstein
2011/05/05 14:20:13
CompareRoot
| |
| 4895 __ j(equal, ¬_in_dictionary); | |
| 4896 | |
| 4897 // Stop if found the property. | |
| 4898 __ cmpq(scratch, Operand(rsp, 3 * kPointerSize)); | |
| 4899 __ j(equal, &in_dictionary); | |
| 4900 | |
| 4901 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { | |
| 4902 // If we hit a non symbol key during negative lookup | |
| 4903 // we have to bailout as this key might be equal to the | |
| 4904 // key we are looking for. | |
| 4905 | |
| 4906 // Check if the entry name is not a symbol. | |
| 4907 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); | |
| 4908 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset), | |
| 4909 Immediate(kIsSymbolMask)); | |
| 4910 __ j(zero, &maybe_in_dictionary); | |
| 4911 } | |
| 4912 } | |
| 4913 | |
| 4914 __ bind(&maybe_in_dictionary); | |
| 4915 // If we are doing negative lookup then probing failure should be | |
| 4916 // treated as a lookup success. For positive lookup probing failure | |
| 4917 // should be treated as lookup failure. | |
| 4918 if (mode_ == POSITIVE_LOOKUP) { | |
| 4919 __ movq(scratch, Immediate(0)); | |
|
Lasse Reichstein
2011/05/05 14:20:13
__ Move(scratch, 0); // will use xor
| |
| 4920 __ Drop(1); | |
| 4921 __ ret(2 * kPointerSize); | |
| 4922 } | |
| 4923 | |
| 4924 __ bind(&in_dictionary); | |
| 4925 __ movq(scratch, Immediate(1)); | |
|
Lasse Reichstein
2011/05/05 14:20:13
Consider using Move
| |
| 4926 __ Drop(1); | |
| 4927 __ ret(2 * kPointerSize); | |
| 4928 | |
| 4929 __ bind(¬_in_dictionary); | |
| 4930 __ movq(scratch, Immediate(0)); | |
|
Lasse Reichstein
2011/05/05 14:20:13
Use Move.
| |
| 4931 __ Drop(1); | |
| 4932 __ ret(2 * kPointerSize); | |
| 4933 } | |
| 4934 | |
| 4935 | |
| 4739 #undef __ | 4936 #undef __ |
| 4740 | 4937 |
| 4741 } } // namespace v8::internal | 4938 } } // namespace v8::internal |
| 4742 | 4939 |
| 4743 #endif // V8_TARGET_ARCH_X64 | 4940 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |