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 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 Context::SECURITY_TOKEN_INDEX * kPointerSize; | 727 Context::SECURITY_TOKEN_INDEX * kPointerSize; |
728 mov(scratch, FieldOperand(scratch, token_offset)); | 728 mov(scratch, FieldOperand(scratch, token_offset)); |
729 cmp(scratch, FieldOperand(holder_reg, token_offset)); | 729 cmp(scratch, FieldOperand(holder_reg, token_offset)); |
730 pop(holder_reg); | 730 pop(holder_reg); |
731 j(not_equal, miss); | 731 j(not_equal, miss); |
732 | 732 |
733 bind(&same_contexts); | 733 bind(&same_contexts); |
734 } | 734 } |
735 | 735 |
736 | 736 |
| 737 void MacroAssembler::LoadFromNumberDictionary(Label* miss, |
| 738 Register elements, |
| 739 Register key, |
| 740 Register r0, |
| 741 Register r1, |
| 742 Register r2, |
| 743 Register result) { |
| 744 // Register use: |
| 745 // |
| 746 // elements - holds the slow-case elements of the receiver and is unchanged. |
| 747 // |
| 748 // key - holds the smi key on entry and is unchanged. |
| 749 // |
| 750 // Scratch registers: |
| 751 // |
| 752 // r0 - holds the untagged key on entry and holds the hash once computed. |
| 753 // |
| 754 // r1 - used to hold the capacity mask of the dictionary |
| 755 // |
| 756 // r2 - used for the index into the dictionary. |
| 757 // |
| 758 // result - holds the result on exit if the load succeeds and we fall through. |
| 759 |
| 760 Label done; |
| 761 |
| 762 // Compute the hash code from the untagged key. This must be kept in sync |
| 763 // with ComputeIntegerHash in utils.h. |
| 764 // |
| 765 // hash = ~hash + (hash << 15); |
| 766 mov(r1, r0); |
| 767 not_(r0); |
| 768 shl(r1, 15); |
| 769 add(r0, Operand(r1)); |
| 770 // hash = hash ^ (hash >> 12); |
| 771 mov(r1, r0); |
| 772 shr(r1, 12); |
| 773 xor_(r0, Operand(r1)); |
| 774 // hash = hash + (hash << 2); |
| 775 lea(r0, Operand(r0, r0, times_4, 0)); |
| 776 // hash = hash ^ (hash >> 4); |
| 777 mov(r1, r0); |
| 778 shr(r1, 4); |
| 779 xor_(r0, Operand(r1)); |
| 780 // hash = hash * 2057; |
| 781 imul(r0, r0, 2057); |
| 782 // hash = hash ^ (hash >> 16); |
| 783 mov(r1, r0); |
| 784 shr(r1, 16); |
| 785 xor_(r0, Operand(r1)); |
| 786 |
| 787 // Compute capacity mask. |
| 788 mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset)); |
| 789 shr(r1, kSmiTagSize); // convert smi to int |
| 790 dec(r1); |
| 791 |
| 792 // Generate an unrolled loop that performs a few probes before giving up. |
| 793 const int kProbes = 4; |
| 794 for (int i = 0; i < kProbes; i++) { |
| 795 // Use r2 for index calculations and keep the hash intact in r0. |
| 796 mov(r2, r0); |
| 797 // Compute the masked index: (hash + i + i * i) & mask. |
| 798 if (i > 0) { |
| 799 add(Operand(r2), Immediate(NumberDictionary::GetProbeOffset(i))); |
| 800 } |
| 801 and_(r2, Operand(r1)); |
| 802 |
| 803 // Scale the index by multiplying by the entry size. |
| 804 ASSERT(NumberDictionary::kEntrySize == 3); |
| 805 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 |
| 806 |
| 807 // Check if the key matches. |
| 808 cmp(key, FieldOperand(elements, |
| 809 r2, |
| 810 times_pointer_size, |
| 811 NumberDictionary::kElementsStartOffset)); |
| 812 if (i != (kProbes - 1)) { |
| 813 j(equal, &done); |
| 814 } else { |
| 815 j(not_equal, miss); |
| 816 } |
| 817 } |
| 818 |
| 819 bind(&done); |
| 820 // Check that the value is a normal propety. |
| 821 const int kDetailsOffset = |
| 822 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; |
| 823 ASSERT_EQ(NORMAL, 0); |
| 824 test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), |
| 825 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); |
| 826 j(not_zero, miss); |
| 827 |
| 828 // Get the value at the masked, scaled index. |
| 829 const int kValueOffset = |
| 830 NumberDictionary::kElementsStartOffset + kPointerSize; |
| 831 mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); |
| 832 } |
| 833 |
| 834 |
737 void MacroAssembler::LoadAllocationTopHelper(Register result, | 835 void MacroAssembler::LoadAllocationTopHelper(Register result, |
738 Register scratch, | 836 Register scratch, |
739 AllocationFlags flags) { | 837 AllocationFlags flags) { |
740 ExternalReference new_space_allocation_top = | 838 ExternalReference new_space_allocation_top = |
741 ExternalReference::new_space_allocation_top_address(isolate()); | 839 ExternalReference::new_space_allocation_top_address(isolate()); |
742 | 840 |
743 // Just return if allocation top is already known. | 841 // Just return if allocation top is already known. |
744 if ((flags & RESULT_CONTAINS_TOP) != 0) { | 842 if ((flags & RESULT_CONTAINS_TOP) != 0) { |
745 // No use of scratch if allocation top is provided. | 843 // No use of scratch if allocation top is provided. |
746 ASSERT(scratch.is(no_reg)); | 844 ASSERT(scratch.is(no_reg)); |
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2129 | 2227 |
2130 // Check that the code was patched as expected. | 2228 // Check that the code was patched as expected. |
2131 ASSERT(masm_.pc_ == address_ + size_); | 2229 ASSERT(masm_.pc_ == address_ + size_); |
2132 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2230 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2133 } | 2231 } |
2134 | 2232 |
2135 | 2233 |
2136 } } // namespace v8::internal | 2234 } } // namespace v8::internal |
2137 | 2235 |
2138 #endif // V8_TARGET_ARCH_IA32 | 2236 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |