| 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 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
| (...skipping 3956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3967 Addu(result, result, Operand(kDoubleSize / 2)); | 3967 Addu(result, result, Operand(kDoubleSize / 2)); |
| 3968 bind(&aligned); | 3968 bind(&aligned); |
| 3969 } | 3969 } |
| 3970 | 3970 |
| 3971 // Calculate new top and bail out if new space is exhausted. Use result | 3971 // Calculate new top and bail out if new space is exhausted. Use result |
| 3972 // to calculate the new top. | 3972 // to calculate the new top. |
| 3973 Addu(result_end, result, Operand(object_size)); | 3973 Addu(result_end, result, Operand(object_size)); |
| 3974 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); | 3974 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
| 3975 sw(result_end, MemOperand(top_address)); | 3975 sw(result_end, MemOperand(top_address)); |
| 3976 | 3976 |
| 3977 // Tag object if requested. | 3977 // Tag object. |
| 3978 if ((flags & TAG_OBJECT) != 0) { | 3978 Addu(result, result, Operand(kHeapObjectTag)); |
| 3979 Addu(result, result, Operand(kHeapObjectTag)); | |
| 3980 } | |
| 3981 } | 3979 } |
| 3982 | 3980 |
| 3983 | 3981 |
| 3984 void MacroAssembler::Allocate(Register object_size, Register result, | 3982 void MacroAssembler::Allocate(Register object_size, Register result, |
| 3985 Register result_end, Register scratch, | 3983 Register result_end, Register scratch, |
| 3986 Label* gc_required, AllocationFlags flags) { | 3984 Label* gc_required, AllocationFlags flags) { |
| 3987 if (!FLAG_inline_new) { | 3985 if (!FLAG_inline_new) { |
| 3988 if (emit_debug_code()) { | 3986 if (emit_debug_code()) { |
| 3989 // Trash the registers to simulate an allocation failure. | 3987 // Trash the registers to simulate an allocation failure. |
| 3990 li(result, 0x7091); | 3988 li(result, 0x7091); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4058 } | 4056 } |
| 4059 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); | 4057 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
| 4060 | 4058 |
| 4061 // Update allocation top. result temporarily holds the new top. | 4059 // Update allocation top. result temporarily holds the new top. |
| 4062 if (emit_debug_code()) { | 4060 if (emit_debug_code()) { |
| 4063 And(alloc_limit, result_end, Operand(kObjectAlignmentMask)); | 4061 And(alloc_limit, result_end, Operand(kObjectAlignmentMask)); |
| 4064 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg)); | 4062 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg)); |
| 4065 } | 4063 } |
| 4066 sw(result_end, MemOperand(top_address)); | 4064 sw(result_end, MemOperand(top_address)); |
| 4067 | 4065 |
| 4068 // Tag object if requested. | 4066 // Tag object. |
| 4069 if ((flags & TAG_OBJECT) != 0) { | 4067 Addu(result, result, Operand(kHeapObjectTag)); |
| 4070 Addu(result, result, Operand(kHeapObjectTag)); | |
| 4071 } | |
| 4072 } | 4068 } |
| 4073 | 4069 |
| 4074 | 4070 |
| 4075 void MacroAssembler::AllocateTwoByteString(Register result, | 4071 void MacroAssembler::AllocateTwoByteString(Register result, |
| 4076 Register length, | 4072 Register length, |
| 4077 Register scratch1, | 4073 Register scratch1, |
| 4078 Register scratch2, | 4074 Register scratch2, |
| 4079 Register scratch3, | 4075 Register scratch3, |
| 4080 Label* gc_required) { | 4076 Label* gc_required) { |
| 4081 // Calculate the number of bytes needed for the characters in the string while | 4077 // Calculate the number of bytes needed for the characters in the string while |
| 4082 // observing object alignment. | 4078 // observing object alignment. |
| 4083 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 4079 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 4084 sll(scratch1, length, 1); // Length in bytes, not chars. | 4080 sll(scratch1, length, 1); // Length in bytes, not chars. |
| 4085 addiu(scratch1, scratch1, | 4081 addiu(scratch1, scratch1, |
| 4086 kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); | 4082 kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); |
| 4087 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 4083 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
| 4088 | 4084 |
| 4089 // Allocate two-byte string in new space. | 4085 // Allocate two-byte string in new space. |
| 4090 Allocate(scratch1, | 4086 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
| 4091 result, | 4087 NO_ALLOCATION_FLAGS); |
| 4092 scratch2, | |
| 4093 scratch3, | |
| 4094 gc_required, | |
| 4095 TAG_OBJECT); | |
| 4096 | 4088 |
| 4097 // Set the map, length and hash field. | 4089 // Set the map, length and hash field. |
| 4098 InitializeNewString(result, | 4090 InitializeNewString(result, |
| 4099 length, | 4091 length, |
| 4100 Heap::kStringMapRootIndex, | 4092 Heap::kStringMapRootIndex, |
| 4101 scratch1, | 4093 scratch1, |
| 4102 scratch2); | 4094 scratch2); |
| 4103 } | 4095 } |
| 4104 | 4096 |
| 4105 | 4097 |
| 4106 void MacroAssembler::AllocateOneByteString(Register result, Register length, | 4098 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
| 4107 Register scratch1, Register scratch2, | 4099 Register scratch1, Register scratch2, |
| 4108 Register scratch3, | 4100 Register scratch3, |
| 4109 Label* gc_required) { | 4101 Label* gc_required) { |
| 4110 // Calculate the number of bytes needed for the characters in the string | 4102 // Calculate the number of bytes needed for the characters in the string |
| 4111 // while observing object alignment. | 4103 // while observing object alignment. |
| 4112 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 4104 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 4113 DCHECK(kCharSize == 1); | 4105 DCHECK(kCharSize == 1); |
| 4114 addiu(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); | 4106 addiu(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); |
| 4115 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 4107 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
| 4116 | 4108 |
| 4117 // Allocate one-byte string in new space. | 4109 // Allocate one-byte string in new space. |
| 4118 Allocate(scratch1, | 4110 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
| 4119 result, | 4111 NO_ALLOCATION_FLAGS); |
| 4120 scratch2, | |
| 4121 scratch3, | |
| 4122 gc_required, | |
| 4123 TAG_OBJECT); | |
| 4124 | 4112 |
| 4125 // Set the map, length and hash field. | 4113 // Set the map, length and hash field. |
| 4126 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, | 4114 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, |
| 4127 scratch1, scratch2); | 4115 scratch1, scratch2); |
| 4128 } | 4116 } |
| 4129 | 4117 |
| 4130 | 4118 |
| 4131 void MacroAssembler::AllocateTwoByteConsString(Register result, | 4119 void MacroAssembler::AllocateTwoByteConsString(Register result, |
| 4132 Register length, | 4120 Register length, |
| 4133 Register scratch1, | 4121 Register scratch1, |
| 4134 Register scratch2, | 4122 Register scratch2, |
| 4135 Label* gc_required) { | 4123 Label* gc_required) { |
| 4136 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 4124 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
| 4137 TAG_OBJECT); | 4125 NO_ALLOCATION_FLAGS); |
| 4138 InitializeNewString(result, | 4126 InitializeNewString(result, |
| 4139 length, | 4127 length, |
| 4140 Heap::kConsStringMapRootIndex, | 4128 Heap::kConsStringMapRootIndex, |
| 4141 scratch1, | 4129 scratch1, |
| 4142 scratch2); | 4130 scratch2); |
| 4143 } | 4131 } |
| 4144 | 4132 |
| 4145 | 4133 |
| 4146 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, | 4134 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, |
| 4147 Register scratch1, | 4135 Register scratch1, |
| 4148 Register scratch2, | 4136 Register scratch2, |
| 4149 Label* gc_required) { | 4137 Label* gc_required) { |
| 4150 Allocate(ConsString::kSize, | 4138 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
| 4151 result, | 4139 NO_ALLOCATION_FLAGS); |
| 4152 scratch1, | |
| 4153 scratch2, | |
| 4154 gc_required, | |
| 4155 TAG_OBJECT); | |
| 4156 | 4140 |
| 4157 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, | 4141 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, |
| 4158 scratch1, scratch2); | 4142 scratch1, scratch2); |
| 4159 } | 4143 } |
| 4160 | 4144 |
| 4161 | 4145 |
| 4162 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 4146 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
| 4163 Register length, | 4147 Register length, |
| 4164 Register scratch1, | 4148 Register scratch1, |
| 4165 Register scratch2, | 4149 Register scratch2, |
| 4166 Label* gc_required) { | 4150 Label* gc_required) { |
| 4167 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 4151 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 4168 TAG_OBJECT); | 4152 NO_ALLOCATION_FLAGS); |
| 4169 | 4153 |
| 4170 InitializeNewString(result, | 4154 InitializeNewString(result, |
| 4171 length, | 4155 length, |
| 4172 Heap::kSlicedStringMapRootIndex, | 4156 Heap::kSlicedStringMapRootIndex, |
| 4173 scratch1, | 4157 scratch1, |
| 4174 scratch2); | 4158 scratch2); |
| 4175 } | 4159 } |
| 4176 | 4160 |
| 4177 | 4161 |
| 4178 void MacroAssembler::AllocateOneByteSlicedString(Register result, | 4162 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
| 4179 Register length, | 4163 Register length, |
| 4180 Register scratch1, | 4164 Register scratch1, |
| 4181 Register scratch2, | 4165 Register scratch2, |
| 4182 Label* gc_required) { | 4166 Label* gc_required) { |
| 4183 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 4167 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 4184 TAG_OBJECT); | 4168 NO_ALLOCATION_FLAGS); |
| 4185 | 4169 |
| 4186 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, | 4170 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, |
| 4187 scratch1, scratch2); | 4171 scratch1, scratch2); |
| 4188 } | 4172 } |
| 4189 | 4173 |
| 4190 | 4174 |
| 4191 void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, | 4175 void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, |
| 4192 Label* not_unique_name) { | 4176 Label* not_unique_name) { |
| 4193 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); | 4177 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); |
| 4194 Label succeed; | 4178 Label succeed; |
| 4195 And(at, reg, Operand(kIsNotStringMask | kIsNotInternalizedMask)); | 4179 And(at, reg, Operand(kIsNotStringMask | kIsNotInternalizedMask)); |
| 4196 Branch(&succeed, eq, at, Operand(zero_reg)); | 4180 Branch(&succeed, eq, at, Operand(zero_reg)); |
| 4197 Branch(not_unique_name, ne, reg, Operand(SYMBOL_TYPE)); | 4181 Branch(not_unique_name, ne, reg, Operand(SYMBOL_TYPE)); |
| 4198 | 4182 |
| 4199 bind(&succeed); | 4183 bind(&succeed); |
| 4200 } | 4184 } |
| 4201 | 4185 |
| 4202 | 4186 |
| 4203 // Allocates a heap number or jumps to the label if the young space is full and | 4187 // Allocates a heap number or jumps to the label if the young space is full and |
| 4204 // a scavenge is needed. | 4188 // a scavenge is needed. |
| 4205 void MacroAssembler::AllocateHeapNumber(Register result, | 4189 void MacroAssembler::AllocateHeapNumber(Register result, |
| 4206 Register scratch1, | 4190 Register scratch1, |
| 4207 Register scratch2, | 4191 Register scratch2, |
| 4208 Register heap_number_map, | 4192 Register heap_number_map, |
| 4209 Label* need_gc, | 4193 Label* need_gc, |
| 4210 TaggingMode tagging_mode, | |
| 4211 MutableMode mode) { | 4194 MutableMode mode) { |
| 4212 // Allocate an object in the heap for the heap number and tag it as a heap | 4195 // Allocate an object in the heap for the heap number and tag it as a heap |
| 4213 // object. | 4196 // object. |
| 4214 Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc, | 4197 Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc, |
| 4215 tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS); | 4198 NO_ALLOCATION_FLAGS); |
| 4216 | 4199 |
| 4217 Heap::RootListIndex map_index = mode == MUTABLE | 4200 Heap::RootListIndex map_index = mode == MUTABLE |
| 4218 ? Heap::kMutableHeapNumberMapRootIndex | 4201 ? Heap::kMutableHeapNumberMapRootIndex |
| 4219 : Heap::kHeapNumberMapRootIndex; | 4202 : Heap::kHeapNumberMapRootIndex; |
| 4220 AssertIsRoot(heap_number_map, map_index); | 4203 AssertIsRoot(heap_number_map, map_index); |
| 4221 | 4204 |
| 4222 // Store heap number map in the allocated object. | 4205 // Store heap number map in the allocated object. |
| 4223 if (tagging_mode == TAG_RESULT) { | 4206 sw(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); |
| 4224 sw(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); | |
| 4225 } else { | |
| 4226 sw(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); | |
| 4227 } | |
| 4228 } | 4207 } |
| 4229 | 4208 |
| 4230 | 4209 |
| 4231 void MacroAssembler::AllocateHeapNumberWithValue(Register result, | 4210 void MacroAssembler::AllocateHeapNumberWithValue(Register result, |
| 4232 FPURegister value, | 4211 FPURegister value, |
| 4233 Register scratch1, | 4212 Register scratch1, |
| 4234 Register scratch2, | 4213 Register scratch2, |
| 4235 Label* gc_required) { | 4214 Label* gc_required) { |
| 4236 LoadRoot(t8, Heap::kHeapNumberMapRootIndex); | 4215 LoadRoot(t8, Heap::kHeapNumberMapRootIndex); |
| 4237 AllocateHeapNumber(result, scratch1, scratch2, t8, gc_required); | 4216 AllocateHeapNumber(result, scratch1, scratch2, t8, gc_required); |
| 4238 sdc1(value, FieldMemOperand(result, HeapNumber::kValueOffset)); | 4217 sdc1(value, FieldMemOperand(result, HeapNumber::kValueOffset)); |
| 4239 } | 4218 } |
| 4240 | 4219 |
| 4241 | 4220 |
| 4242 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 4221 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
| 4243 Register value, Register scratch1, | 4222 Register value, Register scratch1, |
| 4244 Register scratch2, Label* gc_required) { | 4223 Register scratch2, Label* gc_required) { |
| 4245 DCHECK(!result.is(constructor)); | 4224 DCHECK(!result.is(constructor)); |
| 4246 DCHECK(!result.is(scratch1)); | 4225 DCHECK(!result.is(scratch1)); |
| 4247 DCHECK(!result.is(scratch2)); | 4226 DCHECK(!result.is(scratch2)); |
| 4248 DCHECK(!result.is(value)); | 4227 DCHECK(!result.is(value)); |
| 4249 | 4228 |
| 4250 // Allocate JSValue in new space. | 4229 // Allocate JSValue in new space. |
| 4251 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, TAG_OBJECT); | 4230 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, |
| 4231 NO_ALLOCATION_FLAGS); |
| 4252 | 4232 |
| 4253 // Initialize the JSValue. | 4233 // Initialize the JSValue. |
| 4254 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); | 4234 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); |
| 4255 sw(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); | 4235 sw(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); |
| 4256 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); | 4236 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); |
| 4257 sw(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); | 4237 sw(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); |
| 4258 sw(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); | 4238 sw(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); |
| 4259 sw(value, FieldMemOperand(result, JSValue::kValueOffset)); | 4239 sw(value, FieldMemOperand(result, JSValue::kValueOffset)); |
| 4260 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 4240 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
| 4261 } | 4241 } |
| (...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6529 if (mag.shift > 0) sra(result, result, mag.shift); | 6509 if (mag.shift > 0) sra(result, result, mag.shift); |
| 6530 srl(at, dividend, 31); | 6510 srl(at, dividend, 31); |
| 6531 Addu(result, result, Operand(at)); | 6511 Addu(result, result, Operand(at)); |
| 6532 } | 6512 } |
| 6533 | 6513 |
| 6534 | 6514 |
| 6535 } // namespace internal | 6515 } // namespace internal |
| 6536 } // namespace v8 | 6516 } // namespace v8 |
| 6537 | 6517 |
| 6538 #endif // V8_TARGET_ARCH_MIPS | 6518 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |