Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Side by Side Diff: src/mips/macro-assembler-mips.cc

Issue 2028633002: Provide a tagged allocation top pointer. Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: WIP: adding a few tests. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips64/code-stubs-mips64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 4124 matching lines...) Expand 10 before | Expand all | Expand 10 after
4135 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit)); 4135 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit));
4136 } 4136 }
4137 // Load allocation limit. Result already contains allocation top. 4137 // Load allocation limit. Result already contains allocation top.
4138 lw(alloc_limit, MemOperand(top_address, limit - top)); 4138 lw(alloc_limit, MemOperand(top_address, limit - top));
4139 } 4139 }
4140 4140
4141 if ((flags & DOUBLE_ALIGNMENT) != 0) { 4141 if ((flags & DOUBLE_ALIGNMENT) != 0) {
4142 // Align the next allocation. Storing the filler map without checking top is 4142 // Align the next allocation. Storing the filler map without checking top is
4143 // safe in new-space because the limit of the heap is aligned there. 4143 // safe in new-space because the limit of the heap is aligned there.
4144 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4144 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
4145 And(result_end, result, Operand(kDoubleAlignmentMask)); 4145 And(result_end, result, Operand(kDoubleAlignmentMaskTagged));
4146 Label aligned; 4146 Label aligned;
4147 Branch(&aligned, eq, result_end, Operand(zero_reg)); 4147 Branch(&aligned, eq, result_end, Operand(zero_reg));
4148 if ((flags & PRETENURE) != 0) { 4148 if ((flags & PRETENURE) != 0) {
4149 Branch(gc_required, Ugreater_equal, result, Operand(alloc_limit)); 4149 Branch(gc_required, Ugreater_equal, result, Operand(alloc_limit));
4150 } 4150 }
4151 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); 4151 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
4152 sw(result_end, MemOperand(result)); 4152 sw(result_end, FieldMemOperand(result, 0));
4153 Addu(result, result, Operand(kDoubleSize / 2)); 4153 Addu(result, result, Operand(kDoubleSize / 2));
4154 bind(&aligned); 4154 bind(&aligned);
4155 } 4155 }
4156 4156
4157 // Calculate new top and bail out if new space is exhausted. Use result 4157 // Calculate new top and bail out if new space is exhausted. Use result
4158 // to calculate the new top. 4158 // to calculate the new top.
4159 Addu(result_end, result, Operand(object_size)); 4159 Addu(result_end, result, Operand(object_size));
4160 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); 4160 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit));
4161 4161
4162 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 4162 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
4163 // The top pointer is not updated for allocation folding dominators. 4163 // The top pointer is not updated for allocation folding dominators.
4164 sw(result_end, MemOperand(top_address)); 4164 sw(result_end, MemOperand(top_address));
4165 } 4165 }
4166
4167 // Tag object.
4168 Addu(result, result, Operand(kHeapObjectTag));
4169 } 4166 }
4170 4167
4171 4168
4172 void MacroAssembler::Allocate(Register object_size, Register result, 4169 void MacroAssembler::Allocate(Register object_size, Register result,
4173 Register result_end, Register scratch, 4170 Register result_end, Register scratch,
4174 Label* gc_required, AllocationFlags flags) { 4171 Label* gc_required, AllocationFlags flags) {
4175 DCHECK((flags & ALLOCATION_FOLDED) == 0); 4172 DCHECK((flags & ALLOCATION_FOLDED) == 0);
4176 if (!FLAG_inline_new) { 4173 if (!FLAG_inline_new) {
4177 if (emit_debug_code()) { 4174 if (emit_debug_code()) {
4178 // Trash the registers to simulate an allocation failure. 4175 // Trash the registers to simulate an allocation failure.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4218 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit)); 4215 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit));
4219 } 4216 }
4220 // Load allocation limit. Result already contains allocation top. 4217 // Load allocation limit. Result already contains allocation top.
4221 lw(alloc_limit, MemOperand(top_address, limit - top)); 4218 lw(alloc_limit, MemOperand(top_address, limit - top));
4222 } 4219 }
4223 4220
4224 if ((flags & DOUBLE_ALIGNMENT) != 0) { 4221 if ((flags & DOUBLE_ALIGNMENT) != 0) {
4225 // Align the next allocation. Storing the filler map without checking top is 4222 // Align the next allocation. Storing the filler map without checking top is
4226 // safe in new-space because the limit of the heap is aligned there. 4223 // safe in new-space because the limit of the heap is aligned there.
4227 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4224 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
4228 And(result_end, result, Operand(kDoubleAlignmentMask)); 4225 And(result_end, result, Operand(kDoubleAlignmentMaskTagged));
4229 Label aligned; 4226 Label aligned;
4230 Branch(&aligned, eq, result_end, Operand(zero_reg)); 4227 Branch(&aligned, eq, result_end, Operand(zero_reg));
4231 if ((flags & PRETENURE) != 0) { 4228 if ((flags & PRETENURE) != 0) {
4232 Branch(gc_required, Ugreater_equal, result, Operand(alloc_limit)); 4229 Branch(gc_required, Ugreater_equal, result, Operand(alloc_limit));
4233 } 4230 }
4234 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); 4231 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
4235 sw(result_end, MemOperand(result)); 4232 sw(result_end, FieldMemOperand(result, 0));
4236 Addu(result, result, Operand(kDoubleSize / 2)); 4233 Addu(result, result, Operand(kDoubleSize / 2));
4237 bind(&aligned); 4234 bind(&aligned);
4238 } 4235 }
4239 4236
4240 // Calculate new top and bail out if new space is exhausted. Use result 4237 // Calculate new top and bail out if new space is exhausted. Use result
4241 // to calculate the new top. Object size may be in words so a shift is 4238 // to calculate the new top. Object size may be in words so a shift is
4242 // required to get the number of bytes. 4239 // required to get the number of bytes.
4243 if ((flags & SIZE_IN_WORDS) != 0) { 4240 if ((flags & SIZE_IN_WORDS) != 0) {
4244 Lsa(result_end, result, object_size, kPointerSizeLog2); 4241 Lsa(result_end, result, object_size, kPointerSizeLog2);
4245 } else { 4242 } else {
4246 Addu(result_end, result, Operand(object_size)); 4243 Addu(result_end, result, Operand(object_size));
4247 } 4244 }
4248 4245
4249 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); 4246 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit));
4250 4247
4251 // Update allocation top. result temporarily holds the new top. 4248 // Update allocation top. result temporarily holds the new top.
4252 if (emit_debug_code()) { 4249 if (emit_debug_code()) {
4253 And(alloc_limit, result_end, Operand(kObjectAlignmentMask)); 4250 And(alloc_limit, result_end, Operand(kObjectAlignmentMask));
4254 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg)); 4251 Check(ne, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg));
4255 } 4252 }
4256 4253
4257 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 4254 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
4258 // The top pointer is not updated for allocation folding dominators. 4255 // The top pointer is not updated for allocation folding dominators.
4259 sw(result_end, MemOperand(top_address)); 4256 sw(result_end, MemOperand(top_address));
4260 } 4257 }
4261
4262 // Tag object.
4263 Addu(result, result, Operand(kHeapObjectTag));
4264 } 4258 }
4265 4259
4266 void MacroAssembler::FastAllocate(int object_size, Register result, 4260 void MacroAssembler::FastAllocate(int object_size, Register result,
4267 Register scratch1, Register scratch2, 4261 Register scratch1, Register scratch2,
4268 AllocationFlags flags) { 4262 AllocationFlags flags) {
4269 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 4263 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
4270 DCHECK(!AreAliased(result, scratch1, scratch2, t9, at)); 4264 DCHECK(!AreAliased(result, scratch1, scratch2, t9, at));
4271 4265
4272 // Make object size into bytes. 4266 // Make object size into bytes.
4273 if ((flags & SIZE_IN_WORDS) != 0) { 4267 if ((flags & SIZE_IN_WORDS) != 0) {
4274 object_size *= kPointerSize; 4268 object_size *= kPointerSize;
4275 } 4269 }
4276 DCHECK_EQ(0, object_size & kObjectAlignmentMask); 4270 DCHECK_EQ(0, object_size & kObjectAlignmentMask);
4277 4271
4278 ExternalReference allocation_top = 4272 ExternalReference allocation_top =
4279 AllocationUtils::GetAllocationTopReference(isolate(), flags); 4273 AllocationUtils::GetAllocationTopReference(isolate(), flags);
4280 4274
4281 // Set up allocation top address and allocation limit registers. 4275 // Set up allocation top address and allocation limit registers.
4282 Register top_address = scratch1; 4276 Register top_address = scratch1;
4283 // This code stores a temporary value in t9. 4277 // This code stores a temporary value in t9.
4284 Register result_end = scratch2; 4278 Register result_end = scratch2;
4285 li(top_address, Operand(allocation_top)); 4279 li(top_address, Operand(allocation_top));
4286 lw(result, MemOperand(top_address)); 4280 lw(result, MemOperand(top_address));
4287 4281
4288 if ((flags & DOUBLE_ALIGNMENT) != 0) { 4282 if ((flags & DOUBLE_ALIGNMENT) != 0) {
4289 // Align the next allocation. Storing the filler map without checking top is 4283 // Align the next allocation. Storing the filler map without checking top is
4290 // safe in new-space because the limit of the heap is aligned there. 4284 // safe in new-space because the limit of the heap is aligned there.
4291 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4285 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
4292 And(result_end, result, Operand(kDoubleAlignmentMask)); 4286 And(result_end, result, Operand(kDoubleAlignmentMaskTagged));
4293 Label aligned; 4287 Label aligned;
4294 Branch(&aligned, eq, result_end, Operand(zero_reg)); 4288 Branch(&aligned, eq, result_end, Operand(zero_reg));
4295 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); 4289 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
4296 sw(result_end, MemOperand(result)); 4290 sw(result_end, FieldMemOperand(result, 0));
4297 Addu(result, result, Operand(kDoubleSize / 2)); 4291 Addu(result, result, Operand(kDoubleSize / 2));
4298 bind(&aligned); 4292 bind(&aligned);
4299 } 4293 }
4300 4294
4301 Addu(result_end, result, Operand(object_size)); 4295 Addu(result_end, result, Operand(object_size));
4302 4296
4303 // The top pointer is not updated for allocation folding dominators. 4297 // The top pointer is not updated for allocation folding dominators.
4304 sw(result_end, MemOperand(top_address)); 4298 sw(result_end, MemOperand(top_address));
4305
4306 Addu(result, result, Operand(kHeapObjectTag));
4307 } 4299 }
4308 4300
4309 void MacroAssembler::FastAllocate(Register object_size, Register result, 4301 void MacroAssembler::FastAllocate(Register object_size, Register result,
4310 Register result_end, Register scratch, 4302 Register result_end, Register scratch,
4311 AllocationFlags flags) { 4303 AllocationFlags flags) {
4312 // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag 4304 // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
4313 // is not specified. Other registers must not overlap. 4305 // is not specified. Other registers must not overlap.
4314 DCHECK(!AreAliased(object_size, result, scratch, t9, at)); 4306 DCHECK(!AreAliased(object_size, result, scratch, t9, at));
4315 DCHECK(!AreAliased(result_end, result, scratch, t9, at)); 4307 DCHECK(!AreAliased(result_end, result, scratch, t9, at));
4316 DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end)); 4308 DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
4317 4309
4318 ExternalReference allocation_top = 4310 ExternalReference allocation_top =
4319 AllocationUtils::GetAllocationTopReference(isolate(), flags); 4311 AllocationUtils::GetAllocationTopReference(isolate(), flags);
4320 4312
4321 // Set up allocation top address and allocation limit registers. 4313 // Set up allocation top address and allocation limit registers.
4322 Register top_address = scratch; 4314 Register top_address = scratch;
4323 // This code stores a temporary value in t9. 4315 // This code stores a temporary value in t9.
4324 li(top_address, Operand(allocation_top)); 4316 li(top_address, Operand(allocation_top));
4325 lw(result, MemOperand(top_address)); 4317 lw(result, MemOperand(top_address));
4326 4318
4327 if ((flags & DOUBLE_ALIGNMENT) != 0) { 4319 if ((flags & DOUBLE_ALIGNMENT) != 0) {
4328 // Align the next allocation. Storing the filler map without checking top is 4320 // Align the next allocation. Storing the filler map without checking top is
4329 // safe in new-space because the limit of the heap is aligned there. 4321 // safe in new-space because the limit of the heap is aligned there.
4330 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4322 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
4331 And(result_end, result, Operand(kDoubleAlignmentMask)); 4323 And(result_end, result, Operand(kDoubleAlignmentMaskTagged));
4332 Label aligned; 4324 Label aligned;
4333 Branch(&aligned, eq, result_end, Operand(zero_reg)); 4325 Branch(&aligned, eq, result_end, Operand(zero_reg));
4334 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); 4326 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
4335 sw(result_end, MemOperand(result)); 4327 sw(result_end, FieldMemOperand(result, 0));
4336 Addu(result, result, Operand(kDoubleSize / 2)); 4328 Addu(result, result, Operand(kDoubleSize / 2));
4337 bind(&aligned); 4329 bind(&aligned);
4338 } 4330 }
4339 4331
4340 // Calculate new top and bail out if new space is exhausted. Use result 4332 // Calculate new top and bail out if new space is exhausted. Use result
4341 // to calculate the new top. Object size may be in words so a shift is 4333 // to calculate the new top. Object size may be in words so a shift is
4342 // required to get the number of bytes. 4334 // required to get the number of bytes.
4343 if ((flags & SIZE_IN_WORDS) != 0) { 4335 if ((flags & SIZE_IN_WORDS) != 0) {
4344 Lsa(result_end, result, object_size, kPointerSizeLog2); 4336 Lsa(result_end, result, object_size, kPointerSizeLog2);
4345 } else { 4337 } else {
4346 Addu(result_end, result, Operand(object_size)); 4338 Addu(result_end, result, Operand(object_size));
4347 } 4339 }
4348 4340
4349 // The top pointer is not updated for allocation folding dominators. 4341 // The top pointer is not updated for allocation folding dominators.
4350 sw(result_end, MemOperand(top_address)); 4342 sw(result_end, MemOperand(top_address));
4351
4352 Addu(result, result, Operand(kHeapObjectTag));
4353 } 4343 }
4354 4344
4355 void MacroAssembler::AllocateTwoByteString(Register result, 4345 void MacroAssembler::AllocateTwoByteString(Register result,
4356 Register length, 4346 Register length,
4357 Register scratch1, 4347 Register scratch1,
4358 Register scratch2, 4348 Register scratch2,
4359 Register scratch3, 4349 Register scratch3,
4360 Label* gc_required) { 4350 Label* gc_required) {
4361 // Calculate the number of bytes needed for the characters in the string while 4351 // Calculate the number of bytes needed for the characters in the string while
4362 // observing object alignment. 4352 // observing object alignment.
(...skipping 2432 matching lines...) Expand 10 before | Expand all | Expand 10 after
6795 if (mag.shift > 0) sra(result, result, mag.shift); 6785 if (mag.shift > 0) sra(result, result, mag.shift);
6796 srl(at, dividend, 31); 6786 srl(at, dividend, 31);
6797 Addu(result, result, Operand(at)); 6787 Addu(result, result, Operand(at));
6798 } 6788 }
6799 6789
6800 6790
6801 } // namespace internal 6791 } // namespace internal
6802 } // namespace v8 6792 } // namespace v8
6803 6793
6804 #endif // V8_TARGET_ARCH_MIPS 6794 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips64/code-stubs-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698