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 4895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4906 movp(top_reg, result); | 4906 movp(top_reg, result); |
4907 } | 4907 } |
4908 addp(top_reg, Immediate(object_size)); | 4908 addp(top_reg, Immediate(object_size)); |
4909 Operand limit_operand = ExternalOperand(allocation_limit); | 4909 Operand limit_operand = ExternalOperand(allocation_limit); |
4910 cmpp(top_reg, limit_operand); | 4910 cmpp(top_reg, limit_operand); |
4911 j(above, gc_required); | 4911 j(above, gc_required); |
4912 | 4912 |
4913 // Update allocation top. | 4913 // Update allocation top. |
4914 UpdateAllocationTopHelper(top_reg, scratch, flags); | 4914 UpdateAllocationTopHelper(top_reg, scratch, flags); |
4915 | 4915 |
4916 bool tag_result = (flags & TAG_OBJECT) != 0; | |
4917 if (top_reg.is(result)) { | 4916 if (top_reg.is(result)) { |
4918 if (tag_result) { | 4917 subp(result, Immediate(object_size - kHeapObjectTag)); |
4919 subp(result, Immediate(object_size - kHeapObjectTag)); | 4918 } else { |
4920 } else { | 4919 // Tag the result. |
4921 subp(result, Immediate(object_size)); | |
4922 } | |
4923 } else if (tag_result) { | |
4924 // Tag the result if requested. | |
4925 DCHECK(kHeapObjectTag == 1); | 4920 DCHECK(kHeapObjectTag == 1); |
4926 incp(result); | 4921 incp(result); |
4927 } | 4922 } |
4928 } | 4923 } |
4929 | 4924 |
4930 | 4925 |
4931 void MacroAssembler::Allocate(int header_size, | 4926 void MacroAssembler::Allocate(int header_size, |
4932 ScaleFactor element_size, | 4927 ScaleFactor element_size, |
4933 Register element_count, | 4928 Register element_count, |
4934 Register result, | 4929 Register result, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4979 } | 4974 } |
4980 addp(result_end, result); | 4975 addp(result_end, result); |
4981 j(carry, gc_required); | 4976 j(carry, gc_required); |
4982 Operand limit_operand = ExternalOperand(allocation_limit); | 4977 Operand limit_operand = ExternalOperand(allocation_limit); |
4983 cmpp(result_end, limit_operand); | 4978 cmpp(result_end, limit_operand); |
4984 j(above, gc_required); | 4979 j(above, gc_required); |
4985 | 4980 |
4986 // Update allocation top. | 4981 // Update allocation top. |
4987 UpdateAllocationTopHelper(result_end, scratch, flags); | 4982 UpdateAllocationTopHelper(result_end, scratch, flags); |
4988 | 4983 |
4989 // Tag the result if requested. | 4984 // Tag the result. |
4990 if ((flags & TAG_OBJECT) != 0) { | 4985 addp(result, Immediate(kHeapObjectTag)); |
4991 addp(result, Immediate(kHeapObjectTag)); | |
4992 } | |
4993 } | 4986 } |
4994 | 4987 |
4995 | 4988 |
4996 void MacroAssembler::AllocateHeapNumber(Register result, | 4989 void MacroAssembler::AllocateHeapNumber(Register result, |
4997 Register scratch, | 4990 Register scratch, |
4998 Label* gc_required, | 4991 Label* gc_required, |
4999 MutableMode mode) { | 4992 MutableMode mode) { |
5000 // Allocate heap number in new space. | 4993 // Allocate heap number in new space. |
5001 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); | 4994 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, |
| 4995 NO_ALLOCATION_FLAGS); |
5002 | 4996 |
5003 Heap::RootListIndex map_index = mode == MUTABLE | 4997 Heap::RootListIndex map_index = mode == MUTABLE |
5004 ? Heap::kMutableHeapNumberMapRootIndex | 4998 ? Heap::kMutableHeapNumberMapRootIndex |
5005 : Heap::kHeapNumberMapRootIndex; | 4999 : Heap::kHeapNumberMapRootIndex; |
5006 | 5000 |
5007 // Set the map. | 5001 // Set the map. |
5008 LoadRoot(kScratchRegister, map_index); | 5002 LoadRoot(kScratchRegister, map_index); |
5009 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 5003 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
5010 } | 5004 } |
5011 | 5005 |
(...skipping 11 matching lines...) Expand all Loading... |
5023 DCHECK(kShortSize == 2); | 5017 DCHECK(kShortSize == 2); |
5024 // scratch1 = length * 2 + kObjectAlignmentMask. | 5018 // scratch1 = length * 2 + kObjectAlignmentMask. |
5025 leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + | 5019 leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + |
5026 kHeaderAlignment)); | 5020 kHeaderAlignment)); |
5027 andp(scratch1, Immediate(~kObjectAlignmentMask)); | 5021 andp(scratch1, Immediate(~kObjectAlignmentMask)); |
5028 if (kHeaderAlignment > 0) { | 5022 if (kHeaderAlignment > 0) { |
5029 subp(scratch1, Immediate(kHeaderAlignment)); | 5023 subp(scratch1, Immediate(kHeaderAlignment)); |
5030 } | 5024 } |
5031 | 5025 |
5032 // Allocate two byte string in new space. | 5026 // Allocate two byte string in new space. |
5033 Allocate(SeqTwoByteString::kHeaderSize, | 5027 Allocate(SeqTwoByteString::kHeaderSize, times_1, scratch1, result, scratch2, |
5034 times_1, | 5028 scratch3, gc_required, NO_ALLOCATION_FLAGS); |
5035 scratch1, | |
5036 result, | |
5037 scratch2, | |
5038 scratch3, | |
5039 gc_required, | |
5040 TAG_OBJECT); | |
5041 | 5029 |
5042 // Set the map, length and hash field. | 5030 // Set the map, length and hash field. |
5043 LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); | 5031 LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); |
5044 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 5032 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
5045 Integer32ToSmi(scratch1, length); | 5033 Integer32ToSmi(scratch1, length); |
5046 movp(FieldOperand(result, String::kLengthOffset), scratch1); | 5034 movp(FieldOperand(result, String::kLengthOffset), scratch1); |
5047 movp(FieldOperand(result, String::kHashFieldOffset), | 5035 movp(FieldOperand(result, String::kHashFieldOffset), |
5048 Immediate(String::kEmptyHashField)); | 5036 Immediate(String::kEmptyHashField)); |
5049 } | 5037 } |
5050 | 5038 |
5051 | 5039 |
5052 void MacroAssembler::AllocateOneByteString(Register result, Register length, | 5040 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
5053 Register scratch1, Register scratch2, | 5041 Register scratch1, Register scratch2, |
5054 Register scratch3, | 5042 Register scratch3, |
5055 Label* gc_required) { | 5043 Label* gc_required) { |
5056 // Calculate the number of bytes needed for the characters in the string while | 5044 // Calculate the number of bytes needed for the characters in the string while |
5057 // observing object alignment. | 5045 // observing object alignment. |
5058 const int kHeaderAlignment = SeqOneByteString::kHeaderSize & | 5046 const int kHeaderAlignment = SeqOneByteString::kHeaderSize & |
5059 kObjectAlignmentMask; | 5047 kObjectAlignmentMask; |
5060 movl(scratch1, length); | 5048 movl(scratch1, length); |
5061 DCHECK(kCharSize == 1); | 5049 DCHECK(kCharSize == 1); |
5062 addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); | 5050 addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); |
5063 andp(scratch1, Immediate(~kObjectAlignmentMask)); | 5051 andp(scratch1, Immediate(~kObjectAlignmentMask)); |
5064 if (kHeaderAlignment > 0) { | 5052 if (kHeaderAlignment > 0) { |
5065 subp(scratch1, Immediate(kHeaderAlignment)); | 5053 subp(scratch1, Immediate(kHeaderAlignment)); |
5066 } | 5054 } |
5067 | 5055 |
5068 // Allocate one-byte string in new space. | 5056 // Allocate one-byte string in new space. |
5069 Allocate(SeqOneByteString::kHeaderSize, | 5057 Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, result, scratch2, |
5070 times_1, | 5058 scratch3, gc_required, NO_ALLOCATION_FLAGS); |
5071 scratch1, | |
5072 result, | |
5073 scratch2, | |
5074 scratch3, | |
5075 gc_required, | |
5076 TAG_OBJECT); | |
5077 | 5059 |
5078 // Set the map, length and hash field. | 5060 // Set the map, length and hash field. |
5079 LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex); | 5061 LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex); |
5080 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 5062 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
5081 Integer32ToSmi(scratch1, length); | 5063 Integer32ToSmi(scratch1, length); |
5082 movp(FieldOperand(result, String::kLengthOffset), scratch1); | 5064 movp(FieldOperand(result, String::kLengthOffset), scratch1); |
5083 movp(FieldOperand(result, String::kHashFieldOffset), | 5065 movp(FieldOperand(result, String::kHashFieldOffset), |
5084 Immediate(String::kEmptyHashField)); | 5066 Immediate(String::kEmptyHashField)); |
5085 } | 5067 } |
5086 | 5068 |
5087 | 5069 |
5088 void MacroAssembler::AllocateTwoByteConsString(Register result, | 5070 void MacroAssembler::AllocateTwoByteConsString(Register result, |
5089 Register scratch1, | 5071 Register scratch1, |
5090 Register scratch2, | 5072 Register scratch2, |
5091 Label* gc_required) { | 5073 Label* gc_required) { |
5092 // Allocate heap number in new space. | 5074 // Allocate heap number in new space. |
5093 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 5075 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
5094 TAG_OBJECT); | 5076 NO_ALLOCATION_FLAGS); |
5095 | 5077 |
5096 // Set the map. The other fields are left uninitialized. | 5078 // Set the map. The other fields are left uninitialized. |
5097 LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); | 5079 LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); |
5098 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 5080 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
5099 } | 5081 } |
5100 | 5082 |
5101 | 5083 |
5102 void MacroAssembler::AllocateOneByteConsString(Register result, | 5084 void MacroAssembler::AllocateOneByteConsString(Register result, |
5103 Register scratch1, | 5085 Register scratch1, |
5104 Register scratch2, | 5086 Register scratch2, |
5105 Label* gc_required) { | 5087 Label* gc_required) { |
5106 Allocate(ConsString::kSize, | 5088 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
5107 result, | 5089 NO_ALLOCATION_FLAGS); |
5108 scratch1, | |
5109 scratch2, | |
5110 gc_required, | |
5111 TAG_OBJECT); | |
5112 | 5090 |
5113 // Set the map. The other fields are left uninitialized. | 5091 // Set the map. The other fields are left uninitialized. |
5114 LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex); | 5092 LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex); |
5115 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 5093 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
5116 } | 5094 } |
5117 | 5095 |
5118 | 5096 |
5119 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 5097 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
5120 Register scratch1, | 5098 Register scratch1, |
5121 Register scratch2, | 5099 Register scratch2, |
5122 Label* gc_required) { | 5100 Label* gc_required) { |
5123 // Allocate heap number in new space. | 5101 // Allocate heap number in new space. |
5124 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 5102 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
5125 TAG_OBJECT); | 5103 NO_ALLOCATION_FLAGS); |
5126 | 5104 |
5127 // Set the map. The other fields are left uninitialized. | 5105 // Set the map. The other fields are left uninitialized. |
5128 LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); | 5106 LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); |
5129 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 5107 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
5130 } | 5108 } |
5131 | 5109 |
5132 | 5110 |
5133 void MacroAssembler::AllocateOneByteSlicedString(Register result, | 5111 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
5134 Register scratch1, | 5112 Register scratch1, |
5135 Register scratch2, | 5113 Register scratch2, |
5136 Label* gc_required) { | 5114 Label* gc_required) { |
5137 // Allocate heap number in new space. | 5115 // Allocate heap number in new space. |
5138 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 5116 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
5139 TAG_OBJECT); | 5117 NO_ALLOCATION_FLAGS); |
5140 | 5118 |
5141 // Set the map. The other fields are left uninitialized. | 5119 // Set the map. The other fields are left uninitialized. |
5142 LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex); | 5120 LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex); |
5143 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 5121 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
5144 } | 5122 } |
5145 | 5123 |
5146 | 5124 |
5147 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 5125 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
5148 Register value, Register scratch, | 5126 Register value, Register scratch, |
5149 Label* gc_required) { | 5127 Label* gc_required) { |
5150 DCHECK(!result.is(constructor)); | 5128 DCHECK(!result.is(constructor)); |
5151 DCHECK(!result.is(scratch)); | 5129 DCHECK(!result.is(scratch)); |
5152 DCHECK(!result.is(value)); | 5130 DCHECK(!result.is(value)); |
5153 | 5131 |
5154 // Allocate JSValue in new space. | 5132 // Allocate JSValue in new space. |
5155 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); | 5133 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, |
| 5134 NO_ALLOCATION_FLAGS); |
5156 | 5135 |
5157 // Initialize the JSValue. | 5136 // Initialize the JSValue. |
5158 LoadGlobalFunctionInitialMap(constructor, scratch); | 5137 LoadGlobalFunctionInitialMap(constructor, scratch); |
5159 movp(FieldOperand(result, HeapObject::kMapOffset), scratch); | 5138 movp(FieldOperand(result, HeapObject::kMapOffset), scratch); |
5160 LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); | 5139 LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); |
5161 movp(FieldOperand(result, JSObject::kPropertiesOffset), scratch); | 5140 movp(FieldOperand(result, JSObject::kPropertiesOffset), scratch); |
5162 movp(FieldOperand(result, JSObject::kElementsOffset), scratch); | 5141 movp(FieldOperand(result, JSObject::kElementsOffset), scratch); |
5163 movp(FieldOperand(result, JSValue::kValueOffset), value); | 5142 movp(FieldOperand(result, JSValue::kValueOffset), value); |
5164 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 5143 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
5165 } | 5144 } |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5703 movl(rax, dividend); | 5682 movl(rax, dividend); |
5704 shrl(rax, Immediate(31)); | 5683 shrl(rax, Immediate(31)); |
5705 addl(rdx, rax); | 5684 addl(rdx, rax); |
5706 } | 5685 } |
5707 | 5686 |
5708 | 5687 |
5709 } // namespace internal | 5688 } // namespace internal |
5710 } // namespace v8 | 5689 } // namespace v8 |
5711 | 5690 |
5712 #endif // V8_TARGET_ARCH_X64 | 5691 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |