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