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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4137 And(at, result, Operand(kDoubleAlignmentMask)); | 4137 And(at, result, Operand(kDoubleAlignmentMask)); |
4138 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); | 4138 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); |
4139 } | 4139 } |
4140 | 4140 |
4141 // Calculate new top and bail out if new space is exhausted. Use result | 4141 // Calculate new top and bail out if new space is exhausted. Use result |
4142 // to calculate the new top. | 4142 // to calculate the new top. |
4143 Daddu(result_end, result, Operand(object_size)); | 4143 Daddu(result_end, result, Operand(object_size)); |
4144 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); | 4144 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
4145 sd(result_end, MemOperand(top_address)); | 4145 sd(result_end, MemOperand(top_address)); |
4146 | 4146 |
4147 // Tag object if requested. | 4147 // Tag object. |
4148 if ((flags & TAG_OBJECT) != 0) { | 4148 Daddu(result, result, Operand(kHeapObjectTag)); |
4149 Daddu(result, result, Operand(kHeapObjectTag)); | |
4150 } | |
4151 } | 4149 } |
4152 | 4150 |
4153 | 4151 |
4154 void MacroAssembler::Allocate(Register object_size, Register result, | 4152 void MacroAssembler::Allocate(Register object_size, Register result, |
4155 Register result_end, Register scratch, | 4153 Register result_end, Register scratch, |
4156 Label* gc_required, AllocationFlags flags) { | 4154 Label* gc_required, AllocationFlags flags) { |
4157 if (!FLAG_inline_new) { | 4155 if (!FLAG_inline_new) { |
4158 if (emit_debug_code()) { | 4156 if (emit_debug_code()) { |
4159 // Trash the registers to simulate an allocation failure. | 4157 // Trash the registers to simulate an allocation failure. |
4160 li(result, 0x7091); | 4158 li(result, 0x7091); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4219 } | 4217 } |
4220 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); | 4218 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
4221 | 4219 |
4222 // Update allocation top. result temporarily holds the new top. | 4220 // Update allocation top. result temporarily holds the new top. |
4223 if (emit_debug_code()) { | 4221 if (emit_debug_code()) { |
4224 And(at, result_end, Operand(kObjectAlignmentMask)); | 4222 And(at, result_end, Operand(kObjectAlignmentMask)); |
4225 Check(eq, kUnalignedAllocationInNewSpace, at, Operand(zero_reg)); | 4223 Check(eq, kUnalignedAllocationInNewSpace, at, Operand(zero_reg)); |
4226 } | 4224 } |
4227 sd(result_end, MemOperand(top_address)); | 4225 sd(result_end, MemOperand(top_address)); |
4228 | 4226 |
4229 // Tag object if requested. | 4227 // Tag object if. |
4230 if ((flags & TAG_OBJECT) != 0) { | 4228 Daddu(result, result, Operand(kHeapObjectTag)); |
4231 Daddu(result, result, Operand(kHeapObjectTag)); | |
4232 } | |
4233 } | 4229 } |
4234 | 4230 |
4235 | 4231 |
4236 void MacroAssembler::AllocateTwoByteString(Register result, | 4232 void MacroAssembler::AllocateTwoByteString(Register result, |
4237 Register length, | 4233 Register length, |
4238 Register scratch1, | 4234 Register scratch1, |
4239 Register scratch2, | 4235 Register scratch2, |
4240 Register scratch3, | 4236 Register scratch3, |
4241 Label* gc_required) { | 4237 Label* gc_required) { |
4242 // Calculate the number of bytes needed for the characters in the string while | 4238 // Calculate the number of bytes needed for the characters in the string while |
4243 // observing object alignment. | 4239 // observing object alignment. |
4244 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 4240 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
4245 dsll(scratch1, length, 1); // Length in bytes, not chars. | 4241 dsll(scratch1, length, 1); // Length in bytes, not chars. |
4246 daddiu(scratch1, scratch1, | 4242 daddiu(scratch1, scratch1, |
4247 kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); | 4243 kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); |
4248 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 4244 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
4249 | 4245 |
4250 // Allocate two-byte string in new space. | 4246 // Allocate two-byte string in new space. |
4251 Allocate(scratch1, | 4247 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
4252 result, | 4248 NO_ALLOCATION_FLAGS); |
4253 scratch2, | |
4254 scratch3, | |
4255 gc_required, | |
4256 TAG_OBJECT); | |
4257 | 4249 |
4258 // Set the map, length and hash field. | 4250 // Set the map, length and hash field. |
4259 InitializeNewString(result, | 4251 InitializeNewString(result, |
4260 length, | 4252 length, |
4261 Heap::kStringMapRootIndex, | 4253 Heap::kStringMapRootIndex, |
4262 scratch1, | 4254 scratch1, |
4263 scratch2); | 4255 scratch2); |
4264 } | 4256 } |
4265 | 4257 |
4266 | 4258 |
4267 void MacroAssembler::AllocateOneByteString(Register result, Register length, | 4259 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
4268 Register scratch1, Register scratch2, | 4260 Register scratch1, Register scratch2, |
4269 Register scratch3, | 4261 Register scratch3, |
4270 Label* gc_required) { | 4262 Label* gc_required) { |
4271 // Calculate the number of bytes needed for the characters in the string | 4263 // Calculate the number of bytes needed for the characters in the string |
4272 // while observing object alignment. | 4264 // while observing object alignment. |
4273 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 4265 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
4274 DCHECK(kCharSize == 1); | 4266 DCHECK(kCharSize == 1); |
4275 daddiu(scratch1, length, | 4267 daddiu(scratch1, length, |
4276 kObjectAlignmentMask + SeqOneByteString::kHeaderSize); | 4268 kObjectAlignmentMask + SeqOneByteString::kHeaderSize); |
4277 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 4269 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
4278 | 4270 |
4279 // Allocate one-byte string in new space. | 4271 // Allocate one-byte string in new space. |
4280 Allocate(scratch1, | 4272 Allocate(scratch1, result, scratch2, scratch3, gc_required, |
4281 result, | 4273 NO_ALLOCATION_FLAGS); |
4282 scratch2, | |
4283 scratch3, | |
4284 gc_required, | |
4285 TAG_OBJECT); | |
4286 | 4274 |
4287 // Set the map, length and hash field. | 4275 // Set the map, length and hash field. |
4288 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, | 4276 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, |
4289 scratch1, scratch2); | 4277 scratch1, scratch2); |
4290 } | 4278 } |
4291 | 4279 |
4292 | 4280 |
4293 void MacroAssembler::AllocateTwoByteConsString(Register result, | 4281 void MacroAssembler::AllocateTwoByteConsString(Register result, |
4294 Register length, | 4282 Register length, |
4295 Register scratch1, | 4283 Register scratch1, |
4296 Register scratch2, | 4284 Register scratch2, |
4297 Label* gc_required) { | 4285 Label* gc_required) { |
4298 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 4286 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
4299 TAG_OBJECT); | 4287 NO_ALLOCATION_FLAGS); |
4300 InitializeNewString(result, | 4288 InitializeNewString(result, |
4301 length, | 4289 length, |
4302 Heap::kConsStringMapRootIndex, | 4290 Heap::kConsStringMapRootIndex, |
4303 scratch1, | 4291 scratch1, |
4304 scratch2); | 4292 scratch2); |
4305 } | 4293 } |
4306 | 4294 |
4307 | 4295 |
4308 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, | 4296 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, |
4309 Register scratch1, | 4297 Register scratch1, |
4310 Register scratch2, | 4298 Register scratch2, |
4311 Label* gc_required) { | 4299 Label* gc_required) { |
4312 Allocate(ConsString::kSize, | 4300 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
4313 result, | 4301 NO_ALLOCATION_FLAGS); |
4314 scratch1, | |
4315 scratch2, | |
4316 gc_required, | |
4317 TAG_OBJECT); | |
4318 | 4302 |
4319 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, | 4303 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, |
4320 scratch1, scratch2); | 4304 scratch1, scratch2); |
4321 } | 4305 } |
4322 | 4306 |
4323 | 4307 |
4324 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 4308 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
4325 Register length, | 4309 Register length, |
4326 Register scratch1, | 4310 Register scratch1, |
4327 Register scratch2, | 4311 Register scratch2, |
4328 Label* gc_required) { | 4312 Label* gc_required) { |
4329 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 4313 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
4330 TAG_OBJECT); | 4314 NO_ALLOCATION_FLAGS); |
4331 | 4315 |
4332 InitializeNewString(result, | 4316 InitializeNewString(result, |
4333 length, | 4317 length, |
4334 Heap::kSlicedStringMapRootIndex, | 4318 Heap::kSlicedStringMapRootIndex, |
4335 scratch1, | 4319 scratch1, |
4336 scratch2); | 4320 scratch2); |
4337 } | 4321 } |
4338 | 4322 |
4339 | 4323 |
4340 void MacroAssembler::AllocateOneByteSlicedString(Register result, | 4324 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
4341 Register length, | 4325 Register length, |
4342 Register scratch1, | 4326 Register scratch1, |
4343 Register scratch2, | 4327 Register scratch2, |
4344 Label* gc_required) { | 4328 Label* gc_required) { |
4345 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 4329 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
4346 TAG_OBJECT); | 4330 NO_ALLOCATION_FLAGS); |
4347 | 4331 |
4348 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, | 4332 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, |
4349 scratch1, scratch2); | 4333 scratch1, scratch2); |
4350 } | 4334 } |
4351 | 4335 |
4352 | 4336 |
4353 void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, | 4337 void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, |
4354 Label* not_unique_name) { | 4338 Label* not_unique_name) { |
4355 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); | 4339 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); |
4356 Label succeed; | 4340 Label succeed; |
4357 And(at, reg, Operand(kIsNotStringMask | kIsNotInternalizedMask)); | 4341 And(at, reg, Operand(kIsNotStringMask | kIsNotInternalizedMask)); |
4358 Branch(&succeed, eq, at, Operand(zero_reg)); | 4342 Branch(&succeed, eq, at, Operand(zero_reg)); |
4359 Branch(not_unique_name, ne, reg, Operand(SYMBOL_TYPE)); | 4343 Branch(not_unique_name, ne, reg, Operand(SYMBOL_TYPE)); |
4360 | 4344 |
4361 bind(&succeed); | 4345 bind(&succeed); |
4362 } | 4346 } |
4363 | 4347 |
4364 | 4348 |
4365 // Allocates a heap number or jumps to the label if the young space is full and | 4349 // Allocates a heap number or jumps to the label if the young space is full and |
4366 // a scavenge is needed. | 4350 // a scavenge is needed. |
4367 void MacroAssembler::AllocateHeapNumber(Register result, | 4351 void MacroAssembler::AllocateHeapNumber(Register result, |
4368 Register scratch1, | 4352 Register scratch1, |
4369 Register scratch2, | 4353 Register scratch2, |
4370 Register heap_number_map, | 4354 Register heap_number_map, |
4371 Label* need_gc, | 4355 Label* need_gc, |
4372 TaggingMode tagging_mode, | |
4373 MutableMode mode) { | 4356 MutableMode mode) { |
4374 // Allocate an object in the heap for the heap number and tag it as a heap | 4357 // Allocate an object in the heap for the heap number and tag it as a heap |
4375 // object. | 4358 // object. |
4376 Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc, | 4359 Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc, |
4377 tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS); | 4360 NO_ALLOCATION_FLAGS); |
4378 | 4361 |
4379 Heap::RootListIndex map_index = mode == MUTABLE | 4362 Heap::RootListIndex map_index = mode == MUTABLE |
4380 ? Heap::kMutableHeapNumberMapRootIndex | 4363 ? Heap::kMutableHeapNumberMapRootIndex |
4381 : Heap::kHeapNumberMapRootIndex; | 4364 : Heap::kHeapNumberMapRootIndex; |
4382 AssertIsRoot(heap_number_map, map_index); | 4365 AssertIsRoot(heap_number_map, map_index); |
4383 | 4366 |
4384 // Store heap number map in the allocated object. | 4367 // Store heap number map in the allocated object. |
4385 if (tagging_mode == TAG_RESULT) { | 4368 sd(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); |
4386 sd(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); | |
4387 } else { | |
4388 sd(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); | |
4389 } | |
4390 } | 4369 } |
4391 | 4370 |
4392 | 4371 |
4393 void MacroAssembler::AllocateHeapNumberWithValue(Register result, | 4372 void MacroAssembler::AllocateHeapNumberWithValue(Register result, |
4394 FPURegister value, | 4373 FPURegister value, |
4395 Register scratch1, | 4374 Register scratch1, |
4396 Register scratch2, | 4375 Register scratch2, |
4397 Label* gc_required) { | 4376 Label* gc_required) { |
4398 LoadRoot(t8, Heap::kHeapNumberMapRootIndex); | 4377 LoadRoot(t8, Heap::kHeapNumberMapRootIndex); |
4399 AllocateHeapNumber(result, scratch1, scratch2, t8, gc_required); | 4378 AllocateHeapNumber(result, scratch1, scratch2, t8, gc_required); |
4400 sdc1(value, FieldMemOperand(result, HeapNumber::kValueOffset)); | 4379 sdc1(value, FieldMemOperand(result, HeapNumber::kValueOffset)); |
4401 } | 4380 } |
4402 | 4381 |
4403 | 4382 |
4404 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 4383 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
4405 Register value, Register scratch1, | 4384 Register value, Register scratch1, |
4406 Register scratch2, Label* gc_required) { | 4385 Register scratch2, Label* gc_required) { |
4407 DCHECK(!result.is(constructor)); | 4386 DCHECK(!result.is(constructor)); |
4408 DCHECK(!result.is(scratch1)); | 4387 DCHECK(!result.is(scratch1)); |
4409 DCHECK(!result.is(scratch2)); | 4388 DCHECK(!result.is(scratch2)); |
4410 DCHECK(!result.is(value)); | 4389 DCHECK(!result.is(value)); |
4411 | 4390 |
4412 // Allocate JSValue in new space. | 4391 // Allocate JSValue in new space. |
4413 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, TAG_OBJECT); | 4392 Allocate(JSValue::kSize, result, scratch1, scratch2, gc_required, |
| 4393 NO_ALLOCATION_FLAGS); |
4414 | 4394 |
4415 // Initialize the JSValue. | 4395 // Initialize the JSValue. |
4416 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); | 4396 LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2); |
4417 sd(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); | 4397 sd(scratch1, FieldMemOperand(result, HeapObject::kMapOffset)); |
4418 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); | 4398 LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex); |
4419 sd(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); | 4399 sd(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset)); |
4420 sd(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); | 4400 sd(scratch1, FieldMemOperand(result, JSObject::kElementsOffset)); |
4421 sd(value, FieldMemOperand(result, JSValue::kValueOffset)); | 4401 sd(value, FieldMemOperand(result, JSValue::kValueOffset)); |
4422 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 4402 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
4423 } | 4403 } |
(...skipping 2465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6889 if (mag.shift > 0) sra(result, result, mag.shift); | 6869 if (mag.shift > 0) sra(result, result, mag.shift); |
6890 srl(at, dividend, 31); | 6870 srl(at, dividend, 31); |
6891 Addu(result, result, Operand(at)); | 6871 Addu(result, result, Operand(at)); |
6892 } | 6872 } |
6893 | 6873 |
6894 | 6874 |
6895 } // namespace internal | 6875 } // namespace internal |
6896 } // namespace v8 | 6876 } // namespace v8 |
6897 | 6877 |
6898 #endif // V8_TARGET_ARCH_MIPS64 | 6878 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |