| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 3890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3901 // r0 points to properties hash. | 3901 // r0 points to properties hash. |
| 3902 // Compute the masked index: (hash + i + i * i) & mask. | 3902 // Compute the masked index: (hash + i + i * i) & mask. |
| 3903 Register index = r0; | 3903 Register index = r0; |
| 3904 // Capacity is smi 2^n. | 3904 // Capacity is smi 2^n. |
| 3905 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); | 3905 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); |
| 3906 __ decl(index); | 3906 __ decl(index); |
| 3907 __ andp(index, | 3907 __ andp(index, |
| 3908 Immediate(name->Hash() + NameDictionary::GetProbeOffset(i))); | 3908 Immediate(name->Hash() + NameDictionary::GetProbeOffset(i))); |
| 3909 | 3909 |
| 3910 // Scale the index by multiplying by the entry size. | 3910 // Scale the index by multiplying by the entry size. |
| 3911 DCHECK(NameDictionary::kEntrySize == 3); | 3911 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
| 3912 __ leap(index, Operand(index, index, times_2, 0)); // index *= 3. | 3912 __ leap(index, Operand(index, index, times_2, 0)); // index *= 3. |
| 3913 | 3913 |
| 3914 Register entity_name = r0; | 3914 Register entity_name = r0; |
| 3915 // Having undefined at this place means the name is not contained. | 3915 // Having undefined at this place means the name is not contained. |
| 3916 DCHECK_EQ(kSmiTagSize, 1); | 3916 STATIC_ASSERT(kSmiTagSize == 1); |
| 3917 __ movp(entity_name, Operand(properties, | 3917 __ movp(entity_name, Operand(properties, |
| 3918 index, | 3918 index, |
| 3919 times_pointer_size, | 3919 times_pointer_size, |
| 3920 kElementsStartOffset - kHeapObjectTag)); | 3920 kElementsStartOffset - kHeapObjectTag)); |
| 3921 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value()); | 3921 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value()); |
| 3922 __ j(equal, done); | 3922 __ j(equal, done); |
| 3923 | 3923 |
| 3924 // Stop if found the property. | 3924 // Stop if found the property. |
| 3925 __ Cmp(entity_name, Handle<Name>(name)); | 3925 __ Cmp(entity_name, Handle<Name>(name)); |
| 3926 __ j(equal, miss); | 3926 __ j(equal, miss); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3972 for (int i = 0; i < kInlinedProbes; i++) { | 3972 for (int i = 0; i < kInlinedProbes; i++) { |
| 3973 // Compute the masked index: (hash + i + i * i) & mask. | 3973 // Compute the masked index: (hash + i + i * i) & mask. |
| 3974 __ movl(r1, FieldOperand(name, Name::kHashFieldOffset)); | 3974 __ movl(r1, FieldOperand(name, Name::kHashFieldOffset)); |
| 3975 __ shrl(r1, Immediate(Name::kHashShift)); | 3975 __ shrl(r1, Immediate(Name::kHashShift)); |
| 3976 if (i > 0) { | 3976 if (i > 0) { |
| 3977 __ addl(r1, Immediate(NameDictionary::GetProbeOffset(i))); | 3977 __ addl(r1, Immediate(NameDictionary::GetProbeOffset(i))); |
| 3978 } | 3978 } |
| 3979 __ andp(r1, r0); | 3979 __ andp(r1, r0); |
| 3980 | 3980 |
| 3981 // Scale the index by multiplying by the entry size. | 3981 // Scale the index by multiplying by the entry size. |
| 3982 DCHECK(NameDictionary::kEntrySize == 3); | 3982 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
| 3983 __ leap(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3 | 3983 __ leap(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3 |
| 3984 | 3984 |
| 3985 // Check if the key is identical to the name. | 3985 // Check if the key is identical to the name. |
| 3986 __ cmpp(name, Operand(elements, r1, times_pointer_size, | 3986 __ cmpp(name, Operand(elements, r1, times_pointer_size, |
| 3987 kElementsStartOffset - kHeapObjectTag)); | 3987 kElementsStartOffset - kHeapObjectTag)); |
| 3988 __ j(equal, done); | 3988 __ j(equal, done); |
| 3989 } | 3989 } |
| 3990 | 3990 |
| 3991 NameDictionaryLookupStub stub(masm->isolate(), elements, r0, r1, | 3991 NameDictionaryLookupStub stub(masm->isolate(), elements, r0, r1, |
| 3992 POSITIVE_LOOKUP); | 3992 POSITIVE_LOOKUP); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4034 kPointerSize); | 4034 kPointerSize); |
| 4035 for (int i = kInlinedProbes; i < kTotalProbes; i++) { | 4035 for (int i = kInlinedProbes; i < kTotalProbes; i++) { |
| 4036 // Compute the masked index: (hash + i + i * i) & mask. | 4036 // Compute the masked index: (hash + i + i * i) & mask. |
| 4037 __ movp(scratch, args.GetArgumentOperand(1)); | 4037 __ movp(scratch, args.GetArgumentOperand(1)); |
| 4038 if (i > 0) { | 4038 if (i > 0) { |
| 4039 __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i))); | 4039 __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i))); |
| 4040 } | 4040 } |
| 4041 __ andp(scratch, Operand(rsp, 0)); | 4041 __ andp(scratch, Operand(rsp, 0)); |
| 4042 | 4042 |
| 4043 // Scale the index by multiplying by the entry size. | 4043 // Scale the index by multiplying by the entry size. |
| 4044 DCHECK(NameDictionary::kEntrySize == 3); | 4044 STATIC_ASSERT(NameDictionary::kEntrySize == 3); |
| 4045 __ leap(index(), Operand(scratch, scratch, times_2, 0)); // index *= 3. | 4045 __ leap(index(), Operand(scratch, scratch, times_2, 0)); // index *= 3. |
| 4046 | 4046 |
| 4047 // Having undefined at this place means the name is not contained. | 4047 // Having undefined at this place means the name is not contained. |
| 4048 __ movp(scratch, Operand(dictionary(), index(), times_pointer_size, | 4048 __ movp(scratch, Operand(dictionary(), index(), times_pointer_size, |
| 4049 kElementsStartOffset - kHeapObjectTag)); | 4049 kElementsStartOffset - kHeapObjectTag)); |
| 4050 | 4050 |
| 4051 __ Cmp(scratch, isolate()->factory()->undefined_value()); | 4051 __ Cmp(scratch, isolate()->factory()->undefined_value()); |
| 4052 __ j(equal, ¬_in_dictionary); | 4052 __ j(equal, ¬_in_dictionary); |
| 4053 | 4053 |
| 4054 // Stop if found the property. | 4054 // Stop if found the property. |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4731 // rax - number of arguments | 4731 // rax - number of arguments |
| 4732 // rdi - constructor? | 4732 // rdi - constructor? |
| 4733 // rsp[0] - return address | 4733 // rsp[0] - return address |
| 4734 // rsp[8] - last argument | 4734 // rsp[8] - last argument |
| 4735 Handle<Object> undefined_sentinel( | 4735 Handle<Object> undefined_sentinel( |
| 4736 masm->isolate()->heap()->undefined_value(), | 4736 masm->isolate()->heap()->undefined_value(), |
| 4737 masm->isolate()); | 4737 masm->isolate()); |
| 4738 | 4738 |
| 4739 Label normal_sequence; | 4739 Label normal_sequence; |
| 4740 if (mode == DONT_OVERRIDE) { | 4740 if (mode == DONT_OVERRIDE) { |
| 4741 DCHECK(FAST_SMI_ELEMENTS == 0); | 4741 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
| 4742 DCHECK(FAST_HOLEY_SMI_ELEMENTS == 1); | 4742 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 4743 DCHECK(FAST_ELEMENTS == 2); | 4743 STATIC_ASSERT(FAST_ELEMENTS == 2); |
| 4744 DCHECK(FAST_HOLEY_ELEMENTS == 3); | 4744 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 4745 DCHECK(FAST_DOUBLE_ELEMENTS == 4); | 4745 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
| 4746 DCHECK(FAST_HOLEY_DOUBLE_ELEMENTS == 5); | 4746 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
| 4747 | 4747 |
| 4748 // is the low bit set? If so, we are holey and that is good. | 4748 // is the low bit set? If so, we are holey and that is good. |
| 4749 __ testb(rdx, Immediate(1)); | 4749 __ testb(rdx, Immediate(1)); |
| 4750 __ j(not_zero, &normal_sequence); | 4750 __ j(not_zero, &normal_sequence); |
| 4751 } | 4751 } |
| 4752 | 4752 |
| 4753 // look at the first argument | 4753 // look at the first argument |
| 4754 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 4754 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); |
| 4755 __ movp(rcx, args.GetArgumentOperand(0)); | 4755 __ movp(rcx, args.GetArgumentOperand(0)); |
| 4756 __ testp(rcx, rcx); | 4756 __ testp(rcx, rcx); |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5435 kStackSpace, nullptr, return_value_operand, NULL); | 5435 kStackSpace, nullptr, return_value_operand, NULL); |
| 5436 } | 5436 } |
| 5437 | 5437 |
| 5438 | 5438 |
| 5439 #undef __ | 5439 #undef __ |
| 5440 | 5440 |
| 5441 } // namespace internal | 5441 } // namespace internal |
| 5442 } // namespace v8 | 5442 } // namespace v8 |
| 5443 | 5443 |
| 5444 #endif // V8_TARGET_ARCH_X64 | 5444 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |