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 |