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