OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3823 subq(result, Immediate(object_size)); | 3823 subq(result, Immediate(object_size)); |
3824 } | 3824 } |
3825 } else if (tag_result) { | 3825 } else if (tag_result) { |
3826 // Tag the result if requested. | 3826 // Tag the result if requested. |
3827 ASSERT(kHeapObjectTag == 1); | 3827 ASSERT(kHeapObjectTag == 1); |
3828 incq(result); | 3828 incq(result); |
3829 } | 3829 } |
3830 } | 3830 } |
3831 | 3831 |
3832 | 3832 |
3833 void MacroAssembler::AllocateInNewSpace(int header_size, | 3833 void MacroAssembler::Allocate(int header_size, |
3834 ScaleFactor element_size, | 3834 ScaleFactor element_size, |
3835 Register element_count, | 3835 Register element_count, |
3836 Register result, | 3836 Register result, |
3837 Register result_end, | 3837 Register result_end, |
3838 Register scratch, | 3838 Register scratch, |
3839 Label* gc_required, | 3839 Label* gc_required, |
3840 AllocationFlags flags) { | 3840 AllocationFlags flags) { |
3841 ASSERT((flags & SIZE_IN_WORDS) == 0); | 3841 ASSERT((flags & SIZE_IN_WORDS) == 0); |
3842 ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); | |
3843 if (!FLAG_inline_new) { | 3842 if (!FLAG_inline_new) { |
3844 if (emit_debug_code()) { | 3843 if (emit_debug_code()) { |
3845 // Trash the registers to simulate an allocation failure. | 3844 // Trash the registers to simulate an allocation failure. |
3846 movl(result, Immediate(0x7091)); | 3845 movl(result, Immediate(0x7091)); |
3847 movl(result_end, Immediate(0x7191)); | 3846 movl(result_end, Immediate(0x7191)); |
3848 if (scratch.is_valid()) { | 3847 if (scratch.is_valid()) { |
3849 movl(scratch, Immediate(0x7291)); | 3848 movl(scratch, Immediate(0x7291)); |
3850 } | 3849 } |
3851 // Register element_count is not modified by the function. | 3850 // Register element_count is not modified by the function. |
3852 } | 3851 } |
3853 jmp(gc_required); | 3852 jmp(gc_required); |
3854 return; | 3853 return; |
3855 } | 3854 } |
3856 ASSERT(!result.is(result_end)); | 3855 ASSERT(!result.is(result_end)); |
3857 | 3856 |
3858 // Load address of new object into result. | 3857 // Load address of new object into result. |
3859 LoadAllocationTopHelper(result, scratch, flags); | 3858 LoadAllocationTopHelper(result, scratch, flags); |
3860 | 3859 |
3861 // Align the next allocation. Storing the filler map without checking top is | 3860 // Align the next allocation. Storing the filler map without checking top is |
3862 // always safe because the limit of the heap is always aligned. | 3861 // always safe because the limit of the heap is always aligned. |
3863 if (((flags & DOUBLE_ALIGNMENT) != 0) && FLAG_debug_code) { | 3862 if (((flags & DOUBLE_ALIGNMENT) != 0) && FLAG_debug_code) { |
3864 testq(result, Immediate(kDoubleAlignmentMask)); | 3863 testq(result, Immediate(kDoubleAlignmentMask)); |
3865 Check(zero, "Allocation is not double aligned"); | 3864 Check(zero, "Allocation is not double aligned"); |
3866 } | 3865 } |
3867 | 3866 |
3868 // Calculate new top and bail out if new space is exhausted. | 3867 // Calculate new top and bail out if new space is exhausted. |
3869 ExternalReference new_space_allocation_limit = | 3868 ExternalReference allocation_limit = |
3870 ExternalReference::new_space_allocation_limit_address(isolate()); | 3869 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
3871 | 3870 |
3872 // We assume that element_count*element_size + header_size does not | 3871 // We assume that element_count*element_size + header_size does not |
3873 // overflow. | 3872 // overflow. |
3874 lea(result_end, Operand(element_count, element_size, header_size)); | 3873 lea(result_end, Operand(element_count, element_size, header_size)); |
3875 addq(result_end, result); | 3874 addq(result_end, result); |
3876 j(carry, gc_required); | 3875 j(carry, gc_required); |
3877 Operand limit_operand = ExternalOperand(new_space_allocation_limit); | 3876 Operand limit_operand = ExternalOperand(allocation_limit); |
3878 cmpq(result_end, limit_operand); | 3877 cmpq(result_end, limit_operand); |
3879 j(above, gc_required); | 3878 j(above, gc_required); |
3880 | 3879 |
3881 // Update allocation top. | 3880 // Update allocation top. |
3882 UpdateAllocationTopHelper(result_end, scratch, flags); | 3881 UpdateAllocationTopHelper(result_end, scratch, flags); |
3883 | 3882 |
3884 // Tag the result if requested. | 3883 // Tag the result if requested. |
3885 if ((flags & TAG_OBJECT) != 0) { | 3884 if ((flags & TAG_OBJECT) != 0) { |
3886 ASSERT(kHeapObjectTag == 1); | 3885 ASSERT(kHeapObjectTag == 1); |
3887 incq(result); | 3886 incq(result); |
3888 } | 3887 } |
3889 } | 3888 } |
3890 | 3889 |
3891 | 3890 |
3892 void MacroAssembler::AllocateInNewSpace(Register object_size, | 3891 void MacroAssembler::Allocate(Register object_size, |
3893 Register result, | 3892 Register result, |
3894 Register result_end, | 3893 Register result_end, |
3895 Register scratch, | 3894 Register scratch, |
3896 Label* gc_required, | 3895 Label* gc_required, |
3897 AllocationFlags flags) { | 3896 AllocationFlags flags) { |
3898 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); | 3897 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); |
3899 ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); | |
3900 if (!FLAG_inline_new) { | 3898 if (!FLAG_inline_new) { |
3901 if (emit_debug_code()) { | 3899 if (emit_debug_code()) { |
3902 // Trash the registers to simulate an allocation failure. | 3900 // Trash the registers to simulate an allocation failure. |
3903 movl(result, Immediate(0x7091)); | 3901 movl(result, Immediate(0x7091)); |
3904 movl(result_end, Immediate(0x7191)); | 3902 movl(result_end, Immediate(0x7191)); |
3905 if (scratch.is_valid()) { | 3903 if (scratch.is_valid()) { |
3906 movl(scratch, Immediate(0x7291)); | 3904 movl(scratch, Immediate(0x7291)); |
3907 } | 3905 } |
3908 // object_size is left unchanged by this function. | 3906 // object_size is left unchanged by this function. |
3909 } | 3907 } |
3910 jmp(gc_required); | 3908 jmp(gc_required); |
3911 return; | 3909 return; |
3912 } | 3910 } |
3913 ASSERT(!result.is(result_end)); | 3911 ASSERT(!result.is(result_end)); |
3914 | 3912 |
3915 // Load address of new object into result. | 3913 // Load address of new object into result. |
3916 LoadAllocationTopHelper(result, scratch, flags); | 3914 LoadAllocationTopHelper(result, scratch, flags); |
3917 | 3915 |
3918 // Calculate new top and bail out if new space is exhausted. | 3916 // Calculate new top and bail out if new space is exhausted. |
3919 ExternalReference new_space_allocation_limit = | 3917 ExternalReference allocation_limit = |
3920 ExternalReference::new_space_allocation_limit_address(isolate()); | 3918 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
3921 if (!object_size.is(result_end)) { | 3919 if (!object_size.is(result_end)) { |
3922 movq(result_end, object_size); | 3920 movq(result_end, object_size); |
3923 } | 3921 } |
3924 addq(result_end, result); | 3922 addq(result_end, result); |
3925 j(carry, gc_required); | 3923 j(carry, gc_required); |
3926 Operand limit_operand = ExternalOperand(new_space_allocation_limit); | 3924 Operand limit_operand = ExternalOperand(allocation_limit); |
3927 cmpq(result_end, limit_operand); | 3925 cmpq(result_end, limit_operand); |
3928 j(above, gc_required); | 3926 j(above, gc_required); |
3929 | 3927 |
3930 // Update allocation top. | 3928 // Update allocation top. |
3931 UpdateAllocationTopHelper(result_end, scratch, flags); | 3929 UpdateAllocationTopHelper(result_end, scratch, flags); |
3932 | 3930 |
3933 // Align the next allocation. Storing the filler map without checking top is | 3931 // Align the next allocation. Storing the filler map without checking top is |
3934 // always safe because the limit of the heap is always aligned. | 3932 // always safe because the limit of the heap is always aligned. |
3935 if (((flags & DOUBLE_ALIGNMENT) != 0) && FLAG_debug_code) { | 3933 if (((flags & DOUBLE_ALIGNMENT) != 0) && FLAG_debug_code) { |
3936 testq(result, Immediate(kDoubleAlignmentMask)); | 3934 testq(result, Immediate(kDoubleAlignmentMask)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3984 ASSERT(kShortSize == 2); | 3982 ASSERT(kShortSize == 2); |
3985 // scratch1 = length * 2 + kObjectAlignmentMask. | 3983 // scratch1 = length * 2 + kObjectAlignmentMask. |
3986 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + | 3984 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + |
3987 kHeaderAlignment)); | 3985 kHeaderAlignment)); |
3988 and_(scratch1, Immediate(~kObjectAlignmentMask)); | 3986 and_(scratch1, Immediate(~kObjectAlignmentMask)); |
3989 if (kHeaderAlignment > 0) { | 3987 if (kHeaderAlignment > 0) { |
3990 subq(scratch1, Immediate(kHeaderAlignment)); | 3988 subq(scratch1, Immediate(kHeaderAlignment)); |
3991 } | 3989 } |
3992 | 3990 |
3993 // Allocate two byte string in new space. | 3991 // Allocate two byte string in new space. |
3994 AllocateInNewSpace(SeqTwoByteString::kHeaderSize, | 3992 Allocate(SeqTwoByteString::kHeaderSize, |
3995 times_1, | 3993 times_1, |
3996 scratch1, | 3994 scratch1, |
3997 result, | 3995 result, |
3998 scratch2, | 3996 scratch2, |
3999 scratch3, | 3997 scratch3, |
4000 gc_required, | 3998 gc_required, |
4001 TAG_OBJECT); | 3999 TAG_OBJECT); |
4002 | 4000 |
4003 // Set the map, length and hash field. | 4001 // Set the map, length and hash field. |
4004 LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); | 4002 LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); |
4005 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 4003 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
4006 Integer32ToSmi(scratch1, length); | 4004 Integer32ToSmi(scratch1, length); |
4007 movq(FieldOperand(result, String::kLengthOffset), scratch1); | 4005 movq(FieldOperand(result, String::kLengthOffset), scratch1); |
4008 movq(FieldOperand(result, String::kHashFieldOffset), | 4006 movq(FieldOperand(result, String::kHashFieldOffset), |
4009 Immediate(String::kEmptyHashField)); | 4007 Immediate(String::kEmptyHashField)); |
4010 } | 4008 } |
4011 | 4009 |
(...skipping 10 matching lines...) Expand all Loading... |
4022 kObjectAlignmentMask; | 4020 kObjectAlignmentMask; |
4023 movl(scratch1, length); | 4021 movl(scratch1, length); |
4024 ASSERT(kCharSize == 1); | 4022 ASSERT(kCharSize == 1); |
4025 addq(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); | 4023 addq(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); |
4026 and_(scratch1, Immediate(~kObjectAlignmentMask)); | 4024 and_(scratch1, Immediate(~kObjectAlignmentMask)); |
4027 if (kHeaderAlignment > 0) { | 4025 if (kHeaderAlignment > 0) { |
4028 subq(scratch1, Immediate(kHeaderAlignment)); | 4026 subq(scratch1, Immediate(kHeaderAlignment)); |
4029 } | 4027 } |
4030 | 4028 |
4031 // Allocate ASCII string in new space. | 4029 // Allocate ASCII string in new space. |
4032 AllocateInNewSpace(SeqOneByteString::kHeaderSize, | 4030 Allocate(SeqOneByteString::kHeaderSize, |
4033 times_1, | 4031 times_1, |
4034 scratch1, | 4032 scratch1, |
4035 result, | 4033 result, |
4036 scratch2, | 4034 scratch2, |
4037 scratch3, | 4035 scratch3, |
4038 gc_required, | 4036 gc_required, |
4039 TAG_OBJECT); | 4037 TAG_OBJECT); |
4040 | 4038 |
4041 // Set the map, length and hash field. | 4039 // Set the map, length and hash field. |
4042 LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); | 4040 LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); |
4043 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 4041 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
4044 Integer32ToSmi(scratch1, length); | 4042 Integer32ToSmi(scratch1, length); |
4045 movq(FieldOperand(result, String::kLengthOffset), scratch1); | 4043 movq(FieldOperand(result, String::kLengthOffset), scratch1); |
4046 movq(FieldOperand(result, String::kHashFieldOffset), | 4044 movq(FieldOperand(result, String::kHashFieldOffset), |
4047 Immediate(String::kEmptyHashField)); | 4045 Immediate(String::kEmptyHashField)); |
4048 } | 4046 } |
4049 | 4047 |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4635 j(greater, &no_info_available); | 4633 j(greater, &no_info_available); |
4636 CompareRoot(MemOperand(scratch_reg, -AllocationSiteInfo::kSize), | 4634 CompareRoot(MemOperand(scratch_reg, -AllocationSiteInfo::kSize), |
4637 Heap::kAllocationSiteInfoMapRootIndex); | 4635 Heap::kAllocationSiteInfoMapRootIndex); |
4638 bind(&no_info_available); | 4636 bind(&no_info_available); |
4639 } | 4637 } |
4640 | 4638 |
4641 | 4639 |
4642 } } // namespace v8::internal | 4640 } } // namespace v8::internal |
4643 | 4641 |
4644 #endif // V8_TARGET_ARCH_X64 | 4642 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |