| 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 |