| 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 4812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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(kDoubleAlignmentMask)); |
| 4832 j(zero, &aligned, Label::kNear); | 4832 j(zero, &aligned, Label::kNear); |
| 4833 if ((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 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4866 | 4866 |
| 4867 | 4867 |
| 4868 void MacroAssembler::Allocate(int object_size, | 4868 void MacroAssembler::Allocate(int object_size, |
| 4869 Register result, | 4869 Register result, |
| 4870 Register result_end, | 4870 Register result_end, |
| 4871 Register scratch, | 4871 Register scratch, |
| 4872 Label* gc_required, | 4872 Label* gc_required, |
| 4873 AllocationFlags flags) { | 4873 AllocationFlags flags) { |
| 4874 DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); | 4874 DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); |
| 4875 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 4875 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
| 4876 DCHECK((flags & ALLOCATION_FOLDED) == 0); |
| 4876 if (!FLAG_inline_new) { | 4877 if (!FLAG_inline_new) { |
| 4877 if (emit_debug_code()) { | 4878 if (emit_debug_code()) { |
| 4878 // Trash the registers to simulate an allocation failure. | 4879 // Trash the registers to simulate an allocation failure. |
| 4879 movl(result, Immediate(0x7091)); | 4880 movl(result, Immediate(0x7091)); |
| 4880 if (result_end.is_valid()) { | 4881 if (result_end.is_valid()) { |
| 4881 movl(result_end, Immediate(0x7191)); | 4882 movl(result_end, Immediate(0x7191)); |
| 4882 } | 4883 } |
| 4883 if (scratch.is_valid()) { | 4884 if (scratch.is_valid()) { |
| 4884 movl(scratch, Immediate(0x7291)); | 4885 movl(scratch, Immediate(0x7291)); |
| 4885 } | 4886 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4903 Register top_reg = result_end.is_valid() ? result_end : result; | 4904 Register top_reg = result_end.is_valid() ? result_end : result; |
| 4904 | 4905 |
| 4905 if (!top_reg.is(result)) { | 4906 if (!top_reg.is(result)) { |
| 4906 movp(top_reg, result); | 4907 movp(top_reg, result); |
| 4907 } | 4908 } |
| 4908 addp(top_reg, Immediate(object_size)); | 4909 addp(top_reg, Immediate(object_size)); |
| 4909 Operand limit_operand = ExternalOperand(allocation_limit); | 4910 Operand limit_operand = ExternalOperand(allocation_limit); |
| 4910 cmpp(top_reg, limit_operand); | 4911 cmpp(top_reg, limit_operand); |
| 4911 j(above, gc_required); | 4912 j(above, gc_required); |
| 4912 | 4913 |
| 4913 // Update allocation top. | 4914 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
| 4914 UpdateAllocationTopHelper(top_reg, scratch, flags); | 4915 // The top pointer is not updated for allocation folding dominators. |
| 4916 UpdateAllocationTopHelper(top_reg, scratch, flags); |
| 4917 } |
| 4915 | 4918 |
| 4916 if (top_reg.is(result)) { | 4919 if (top_reg.is(result)) { |
| 4917 subp(result, Immediate(object_size - kHeapObjectTag)); | 4920 subp(result, Immediate(object_size - kHeapObjectTag)); |
| 4918 } else { | 4921 } else { |
| 4919 // Tag the result. | 4922 // Tag the result. |
| 4920 DCHECK(kHeapObjectTag == 1); | 4923 DCHECK(kHeapObjectTag == 1); |
| 4921 incp(result); | 4924 incp(result); |
| 4922 } | 4925 } |
| 4923 } | 4926 } |
| 4924 | 4927 |
| 4925 | 4928 |
| 4926 void MacroAssembler::Allocate(int header_size, | 4929 void MacroAssembler::Allocate(int header_size, |
| 4927 ScaleFactor element_size, | 4930 ScaleFactor element_size, |
| 4928 Register element_count, | 4931 Register element_count, |
| 4929 Register result, | 4932 Register result, |
| 4930 Register result_end, | 4933 Register result_end, |
| 4931 Register scratch, | 4934 Register scratch, |
| 4932 Label* gc_required, | 4935 Label* gc_required, |
| 4933 AllocationFlags flags) { | 4936 AllocationFlags flags) { |
| 4934 DCHECK((flags & SIZE_IN_WORDS) == 0); | 4937 DCHECK((flags & SIZE_IN_WORDS) == 0); |
| 4938 DCHECK((flags & ALLOCATION_FOLDING_DOMINATOR) == 0); |
| 4939 DCHECK((flags & ALLOCATION_FOLDED) == 0); |
| 4935 leap(result_end, Operand(element_count, element_size, header_size)); | 4940 leap(result_end, Operand(element_count, element_size, header_size)); |
| 4936 Allocate(result_end, result, result_end, scratch, gc_required, flags); | 4941 Allocate(result_end, result, result_end, scratch, gc_required, flags); |
| 4937 } | 4942 } |
| 4938 | 4943 |
| 4939 | 4944 |
| 4940 void MacroAssembler::Allocate(Register object_size, | 4945 void MacroAssembler::Allocate(Register object_size, |
| 4941 Register result, | 4946 Register result, |
| 4942 Register result_end, | 4947 Register result_end, |
| 4943 Register scratch, | 4948 Register scratch, |
| 4944 Label* gc_required, | 4949 Label* gc_required, |
| 4945 AllocationFlags flags) { | 4950 AllocationFlags flags) { |
| 4946 DCHECK((flags & SIZE_IN_WORDS) == 0); | 4951 DCHECK((flags & SIZE_IN_WORDS) == 0); |
| 4952 DCHECK((flags & ALLOCATION_FOLDED) == 0); |
| 4947 if (!FLAG_inline_new) { | 4953 if (!FLAG_inline_new) { |
| 4948 if (emit_debug_code()) { | 4954 if (emit_debug_code()) { |
| 4949 // Trash the registers to simulate an allocation failure. | 4955 // Trash the registers to simulate an allocation failure. |
| 4950 movl(result, Immediate(0x7091)); | 4956 movl(result, Immediate(0x7091)); |
| 4951 movl(result_end, Immediate(0x7191)); | 4957 movl(result_end, Immediate(0x7191)); |
| 4952 if (scratch.is_valid()) { | 4958 if (scratch.is_valid()) { |
| 4953 movl(scratch, Immediate(0x7291)); | 4959 movl(scratch, Immediate(0x7291)); |
| 4954 } | 4960 } |
| 4955 // object_size is left unchanged by this function. | 4961 // object_size is left unchanged by this function. |
| 4956 } | 4962 } |
| 4957 jmp(gc_required); | 4963 jmp(gc_required); |
| 4958 return; | 4964 return; |
| 4959 } | 4965 } |
| 4960 DCHECK(!result.is(result_end)); | 4966 DCHECK(!result.is(result_end)); |
| 4961 | 4967 |
| 4962 // Load address of new object into result. | 4968 // Load address of new object into result. |
| 4963 LoadAllocationTopHelper(result, scratch, flags); | 4969 LoadAllocationTopHelper(result, scratch, flags); |
| 4964 | 4970 |
| 4965 if ((flags & DOUBLE_ALIGNMENT) != 0) { | 4971 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
| 4966 MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); | 4972 MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); |
| 4967 } | 4973 } |
| 4968 | 4974 |
| 4969 // Calculate new top and bail out if new space is exhausted. | |
| 4970 ExternalReference allocation_limit = | 4975 ExternalReference allocation_limit = |
| 4971 AllocationUtils::GetAllocationLimitReference(isolate(), flags); | 4976 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
| 4972 if (!object_size.is(result_end)) { | 4977 if (!object_size.is(result_end)) { |
| 4973 movp(result_end, object_size); | 4978 movp(result_end, object_size); |
| 4974 } | 4979 } |
| 4975 addp(result_end, result); | 4980 addp(result_end, result); |
| 4976 j(carry, gc_required); | |
| 4977 Operand limit_operand = ExternalOperand(allocation_limit); | 4981 Operand limit_operand = ExternalOperand(allocation_limit); |
| 4978 cmpp(result_end, limit_operand); | 4982 cmpp(result_end, limit_operand); |
| 4979 j(above, gc_required); | 4983 j(above, gc_required); |
| 4980 | 4984 |
| 4981 // Update allocation top. | 4985 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
| 4982 UpdateAllocationTopHelper(result_end, scratch, flags); | 4986 // The top pointer is not updated for allocation folding dominators. |
| 4987 UpdateAllocationTopHelper(result_end, scratch, flags); |
| 4988 } |
| 4983 | 4989 |
| 4984 // Tag the result. | 4990 // Tag the result. |
| 4985 addp(result, Immediate(kHeapObjectTag)); | 4991 addp(result, Immediate(kHeapObjectTag)); |
| 4986 } | 4992 } |
| 4987 | 4993 |
| 4994 void MacroAssembler::FastAllocate(int object_size, Register result, |
| 4995 Register result_end, AllocationFlags flags) { |
| 4996 DCHECK(!result.is(result_end)); |
| 4997 // Load address of new object into result. |
| 4998 LoadAllocationTopHelper(result, no_reg, flags); |
| 4999 |
| 5000 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
| 5001 MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); |
| 5002 } |
| 5003 |
| 5004 leap(result_end, Operand(result, object_size)); |
| 5005 |
| 5006 UpdateAllocationTopHelper(result_end, no_reg, flags); |
| 5007 |
| 5008 addp(result, Immediate(kHeapObjectTag)); |
| 5009 } |
| 5010 |
| 5011 void MacroAssembler::FastAllocate(Register object_size, Register result, |
| 5012 Register result_end, AllocationFlags flags) { |
| 5013 DCHECK(!result.is(result_end)); |
| 5014 // Load address of new object into result. |
| 5015 LoadAllocationTopHelper(result, no_reg, flags); |
| 5016 |
| 5017 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
| 5018 MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); |
| 5019 } |
| 5020 |
| 5021 leap(result_end, Operand(result, object_size, times_1, 0)); |
| 5022 |
| 5023 UpdateAllocationTopHelper(result_end, no_reg, flags); |
| 5024 |
| 5025 addp(result, Immediate(kHeapObjectTag)); |
| 5026 } |
| 4988 | 5027 |
| 4989 void MacroAssembler::AllocateHeapNumber(Register result, | 5028 void MacroAssembler::AllocateHeapNumber(Register result, |
| 4990 Register scratch, | 5029 Register scratch, |
| 4991 Label* gc_required, | 5030 Label* gc_required, |
| 4992 MutableMode mode) { | 5031 MutableMode mode) { |
| 4993 // Allocate heap number in new space. | 5032 // Allocate heap number in new space. |
| 4994 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, | 5033 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, |
| 4995 NO_ALLOCATION_FLAGS); | 5034 NO_ALLOCATION_FLAGS); |
| 4996 | 5035 |
| 4997 Heap::RootListIndex map_index = mode == MUTABLE | 5036 Heap::RootListIndex map_index = mode == MUTABLE |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5682 movl(rax, dividend); | 5721 movl(rax, dividend); |
| 5683 shrl(rax, Immediate(31)); | 5722 shrl(rax, Immediate(31)); |
| 5684 addl(rdx, rax); | 5723 addl(rdx, rax); |
| 5685 } | 5724 } |
| 5686 | 5725 |
| 5687 | 5726 |
| 5688 } // namespace internal | 5727 } // namespace internal |
| 5689 } // namespace v8 | 5728 } // namespace v8 |
| 5690 | 5729 |
| 5691 #endif // V8_TARGET_ARCH_X64 | 5730 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |