OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 4799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4810 } | 4810 } |
4811 } | 4811 } |
4812 | 4812 |
4813 | 4813 |
4814 void MacroAssembler::MakeSureDoubleAlignedHelper(Register result, | 4814 void MacroAssembler::MakeSureDoubleAlignedHelper(Register result, |
4815 Register scratch, | 4815 Register scratch, |
4816 Label* gc_required, | 4816 Label* gc_required, |
4817 AllocationFlags flags) { | 4817 AllocationFlags flags) { |
4818 if (kPointerSize == kDoubleSize) { | 4818 if (kPointerSize == kDoubleSize) { |
4819 if (FLAG_debug_code) { | 4819 if (FLAG_debug_code) { |
4820 testl(result, Immediate(kDoubleAlignmentMask)); | 4820 testl(result, Immediate(kDoubleAlignmentMaskTagged)); |
4821 Check(zero, kAllocationIsNotDoubleAligned); | 4821 Check(zero, kAllocationIsNotDoubleAligned); |
4822 } | 4822 } |
4823 } else { | 4823 } else { |
4824 // Align the next allocation. Storing the filler map without checking top | 4824 // Align the next allocation. Storing the filler map without checking top |
4825 // is safe in new-space because the limit of the heap is aligned there. | 4825 // is safe in new-space because the limit of the heap is aligned there. |
4826 DCHECK(kPointerSize * 2 == kDoubleSize); | 4826 DCHECK(kPointerSize * 2 == kDoubleSize); |
4827 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); | 4827 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); |
4828 // Make sure scratch is not clobbered by this function as it might be | 4828 // Make sure scratch is not clobbered by this function as it might be |
4829 // used in UpdateAllocationTopHelper later. | 4829 // used in UpdateAllocationTopHelper later. |
4830 DCHECK(!scratch.is(kScratchRegister)); | 4830 DCHECK(!scratch.is(kScratchRegister)); |
4831 Label aligned; | 4831 Label aligned; |
4832 testl(result, Immediate(kDoubleAlignmentMask)); | 4832 testl(result, Immediate(kDoubleAlignmentMaskTagged)); |
4833 j(zero, &aligned, Label::kNear); | 4833 j(zero, &aligned, Label::kNear); |
4834 if (((flags & ALLOCATION_FOLDED) == 0) && ((flags & PRETENURE) != 0)) { | 4834 if (((flags & ALLOCATION_FOLDED) == 0) && ((flags & PRETENURE) != 0)) { |
4835 ExternalReference allocation_limit = | 4835 ExternalReference allocation_limit = |
4836 AllocationUtils::GetAllocationLimitReference(isolate(), flags); | 4836 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
4837 cmpp(result, ExternalOperand(allocation_limit)); | 4837 cmpp(result, ExternalOperand(allocation_limit)); |
4838 j(above_equal, gc_required); | 4838 j(above_equal, gc_required); |
4839 } | 4839 } |
4840 LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); | 4840 LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); |
4841 movp(Operand(result, 0), kScratchRegister); | 4841 movp(Operand(result, -kHeapObjectTag), kScratchRegister); |
4842 addp(result, Immediate(kDoubleSize / 2)); | 4842 addp(result, Immediate(kDoubleSize / 2)); |
4843 bind(&aligned); | 4843 bind(&aligned); |
4844 } | 4844 } |
4845 } | 4845 } |
4846 | 4846 |
4847 | 4847 |
4848 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, | 4848 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, |
4849 Register scratch, | 4849 Register scratch, |
4850 AllocationFlags flags) { | 4850 AllocationFlags flags) { |
4851 if (emit_debug_code()) { | 4851 if (emit_debug_code()) { |
4852 testp(result_end, Immediate(kObjectAlignmentMask)); | 4852 testp(result_end, Immediate(kObjectAlignmentMask)); |
4853 Check(zero, kUnalignedAllocationInNewSpace); | 4853 Check(not_zero, kUnalignedAllocationInNewSpace); |
4854 } | 4854 } |
4855 | 4855 |
4856 ExternalReference allocation_top = | 4856 ExternalReference allocation_top = |
4857 AllocationUtils::GetAllocationTopReference(isolate(), flags); | 4857 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
4858 | 4858 |
4859 // Update new top. | 4859 // Update new top. |
4860 if (scratch.is_valid()) { | 4860 if (scratch.is_valid()) { |
4861 // Scratch already contains address of allocation top. | 4861 // Scratch already contains address of allocation top. |
4862 movp(Operand(scratch, 0), result_end); | 4862 movp(Operand(scratch, 0), result_end); |
4863 } else { | 4863 } else { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4911 Operand limit_operand = ExternalOperand(allocation_limit); | 4911 Operand limit_operand = ExternalOperand(allocation_limit); |
4912 cmpp(top_reg, limit_operand); | 4912 cmpp(top_reg, limit_operand); |
4913 j(above, gc_required); | 4913 j(above, gc_required); |
4914 | 4914 |
4915 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { | 4915 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
4916 // The top pointer is not updated for allocation folding dominators. | 4916 // The top pointer is not updated for allocation folding dominators. |
4917 UpdateAllocationTopHelper(top_reg, scratch, flags); | 4917 UpdateAllocationTopHelper(top_reg, scratch, flags); |
4918 } | 4918 } |
4919 | 4919 |
4920 if (top_reg.is(result)) { | 4920 if (top_reg.is(result)) { |
4921 subp(result, Immediate(object_size - kHeapObjectTag)); | 4921 subp(result, Immediate(object_size)); |
4922 } else { | |
4923 // Tag the result. | |
4924 DCHECK(kHeapObjectTag == 1); | |
4925 incp(result); | |
4926 } | 4922 } |
4927 } | 4923 } |
4928 | 4924 |
4929 | 4925 |
4930 void MacroAssembler::Allocate(int header_size, | 4926 void MacroAssembler::Allocate(int header_size, |
4931 ScaleFactor element_size, | 4927 ScaleFactor element_size, |
4932 Register element_count, | 4928 Register element_count, |
4933 Register result, | 4929 Register result, |
4934 Register result_end, | 4930 Register result_end, |
4935 Register scratch, | 4931 Register scratch, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4980 } | 4976 } |
4981 addp(result_end, result); | 4977 addp(result_end, result); |
4982 Operand limit_operand = ExternalOperand(allocation_limit); | 4978 Operand limit_operand = ExternalOperand(allocation_limit); |
4983 cmpp(result_end, limit_operand); | 4979 cmpp(result_end, limit_operand); |
4984 j(above, gc_required); | 4980 j(above, gc_required); |
4985 | 4981 |
4986 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { | 4982 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
4987 // The top pointer is not updated for allocation folding dominators. | 4983 // The top pointer is not updated for allocation folding dominators. |
4988 UpdateAllocationTopHelper(result_end, scratch, flags); | 4984 UpdateAllocationTopHelper(result_end, scratch, flags); |
4989 } | 4985 } |
4990 | |
4991 // Tag the result. | |
4992 addp(result, Immediate(kHeapObjectTag)); | |
4993 } | 4986 } |
4994 | 4987 |
4995 void MacroAssembler::FastAllocate(int object_size, Register result, | 4988 void MacroAssembler::FastAllocate(int object_size, Register result, |
4996 Register result_end, AllocationFlags flags) { | 4989 Register result_end, AllocationFlags flags) { |
4997 DCHECK(!result.is(result_end)); | 4990 DCHECK(!result.is(result_end)); |
4998 // Load address of new object into result. | 4991 // Load address of new object into result. |
4999 LoadAllocationTopHelper(result, no_reg, flags); | 4992 LoadAllocationTopHelper(result, no_reg, flags); |
5000 | 4993 |
5001 if ((flags & DOUBLE_ALIGNMENT) != 0) { | 4994 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
5002 MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); | 4995 MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); |
5003 } | 4996 } |
5004 | 4997 |
5005 leap(result_end, Operand(result, object_size)); | 4998 leap(result_end, Operand(result, object_size)); |
5006 | 4999 |
5007 UpdateAllocationTopHelper(result_end, no_reg, flags); | 5000 UpdateAllocationTopHelper(result_end, no_reg, flags); |
5008 | |
5009 addp(result, Immediate(kHeapObjectTag)); | |
5010 } | 5001 } |
5011 | 5002 |
5012 void MacroAssembler::FastAllocate(Register object_size, Register result, | 5003 void MacroAssembler::FastAllocate(Register object_size, Register result, |
5013 Register result_end, AllocationFlags flags) { | 5004 Register result_end, AllocationFlags flags) { |
5014 DCHECK(!result.is(result_end)); | 5005 DCHECK(!result.is(result_end)); |
5015 // Load address of new object into result. | 5006 // Load address of new object into result. |
5016 LoadAllocationTopHelper(result, no_reg, flags); | 5007 LoadAllocationTopHelper(result, no_reg, flags); |
5017 | 5008 |
5018 if ((flags & DOUBLE_ALIGNMENT) != 0) { | 5009 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
5019 MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); | 5010 MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); |
5020 } | 5011 } |
5021 | 5012 |
5022 leap(result_end, Operand(result, object_size, times_1, 0)); | 5013 leap(result_end, Operand(result, object_size, times_1, 0)); |
5023 | 5014 |
5024 UpdateAllocationTopHelper(result_end, no_reg, flags); | 5015 UpdateAllocationTopHelper(result_end, no_reg, flags); |
5025 | |
5026 addp(result, Immediate(kHeapObjectTag)); | |
5027 } | 5016 } |
5028 | 5017 |
5029 void MacroAssembler::AllocateHeapNumber(Register result, | 5018 void MacroAssembler::AllocateHeapNumber(Register result, |
5030 Register scratch, | 5019 Register scratch, |
5031 Label* gc_required, | 5020 Label* gc_required, |
5032 MutableMode mode) { | 5021 MutableMode mode) { |
5033 // Allocate heap number in new space. | 5022 // Allocate heap number in new space. |
5034 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, | 5023 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, |
5035 NO_ALLOCATION_FLAGS); | 5024 NO_ALLOCATION_FLAGS); |
5036 | 5025 |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5722 movl(rax, dividend); | 5711 movl(rax, dividend); |
5723 shrl(rax, Immediate(31)); | 5712 shrl(rax, Immediate(31)); |
5724 addl(rdx, rax); | 5713 addl(rdx, rax); |
5725 } | 5714 } |
5726 | 5715 |
5727 | 5716 |
5728 } // namespace internal | 5717 } // namespace internal |
5729 } // namespace v8 | 5718 } // namespace v8 |
5730 | 5719 |
5731 #endif // V8_TARGET_ARCH_X64 | 5720 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |