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

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

Issue 1468073004: Reshuffle registers in JSConstructStub to avoid trashing costructor and new.target on fast path (so… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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/builtins-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 1
2 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Copyright 2012 the V8 project authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be 3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file. 4 // found in the LICENSE file.
5 5
6 #include <limits.h> // For LONG_MIN, LONG_MAX. 6 #include <limits.h> // For LONG_MIN, LONG_MAX.
7 7
8 #if V8_TARGET_ARCH_MIPS 8 #if V8_TARGET_ARCH_MIPS
9 9
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 3252 matching lines...) Expand 10 before | Expand all | Expand 10 after
3263 if (emit_debug_code()) { 3263 if (emit_debug_code()) {
3264 // Trash the registers to simulate an allocation failure. 3264 // Trash the registers to simulate an allocation failure.
3265 li(result, 0x7091); 3265 li(result, 0x7091);
3266 li(scratch1, 0x7191); 3266 li(scratch1, 0x7191);
3267 li(scratch2, 0x7291); 3267 li(scratch2, 0x7291);
3268 } 3268 }
3269 jmp(gc_required); 3269 jmp(gc_required);
3270 return; 3270 return;
3271 } 3271 }
3272 3272
3273 DCHECK(!result.is(scratch1)); 3273 DCHECK(!AreAliased(result, scratch1, scratch2, t9));
3274 DCHECK(!result.is(scratch2));
3275 DCHECK(!scratch1.is(scratch2));
3276 DCHECK(!scratch1.is(t9));
3277 DCHECK(!scratch2.is(t9));
3278 DCHECK(!result.is(t9));
3279 3274
3280 // Make object size into bytes. 3275 // Make object size into bytes.
3281 if ((flags & SIZE_IN_WORDS) != 0) { 3276 if ((flags & SIZE_IN_WORDS) != 0) {
3282 object_size *= kPointerSize; 3277 object_size *= kPointerSize;
3283 } 3278 }
3284 DCHECK_EQ(0, object_size & kObjectAlignmentMask); 3279 DCHECK_EQ(0, object_size & kObjectAlignmentMask);
3285 3280
3286 // Check relative positions of allocation top and limit addresses. 3281 // Check relative positions of allocation top and limit addresses.
3287 // ARM adds additional checks to make sure the ldm instruction can be 3282 // ARM adds additional checks to make sure the ldm instruction can be
3288 // used. On MIPS we don't have ldm so we don't need additional checks either. 3283 // used. On MIPS we don't have ldm so we don't need additional checks either.
3289 ExternalReference allocation_top = 3284 ExternalReference allocation_top =
3290 AllocationUtils::GetAllocationTopReference(isolate(), flags); 3285 AllocationUtils::GetAllocationTopReference(isolate(), flags);
3291 ExternalReference allocation_limit = 3286 ExternalReference allocation_limit =
3292 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 3287 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3293 3288
3294 intptr_t top = 3289 intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
3295 reinterpret_cast<intptr_t>(allocation_top.address()); 3290 intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
3296 intptr_t limit =
3297 reinterpret_cast<intptr_t>(allocation_limit.address());
3298 DCHECK((limit - top) == kPointerSize); 3291 DCHECK((limit - top) == kPointerSize);
3299 3292
3300 // Set up allocation top address and object size registers. 3293 // Set up allocation top address and allocation limit registers.
3301 Register topaddr = scratch1; 3294 Register top_address = scratch1;
3302 li(topaddr, Operand(allocation_top)); 3295 // This code stores a temporary value in t9.
3296 Register alloc_limit = t9;
3297 Register result_end = scratch2;
3298 li(top_address, Operand(allocation_top));
3303 3299
3304 // This code stores a temporary value in t9.
3305 if ((flags & RESULT_CONTAINS_TOP) == 0) { 3300 if ((flags & RESULT_CONTAINS_TOP) == 0) {
3306 // Load allocation top into result and allocation limit into t9. 3301 // Load allocation top into result and allocation limit into alloc_limit.
3307 lw(result, MemOperand(topaddr)); 3302 lw(result, MemOperand(top_address));
3308 lw(t9, MemOperand(topaddr, kPointerSize)); 3303 lw(alloc_limit, MemOperand(top_address, kPointerSize));
3309 } else { 3304 } else {
3310 if (emit_debug_code()) { 3305 if (emit_debug_code()) {
3311 // Assert that result actually contains top on entry. t9 is used 3306 // Assert that result actually contains top on entry.
3312 // immediately below so this use of t9 does not cause difference with 3307 lw(alloc_limit, MemOperand(top_address));
3313 // respect to register content between debug and release mode. 3308 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit));
3314 lw(t9, MemOperand(topaddr));
3315 Check(eq, kUnexpectedAllocationTop, result, Operand(t9));
3316 } 3309 }
3317 // Load allocation limit into t9. Result already contains allocation top. 3310 // Load allocation limit. Result already contains allocation top.
3318 lw(t9, MemOperand(topaddr, limit - top)); 3311 lw(alloc_limit, MemOperand(top_address, limit - top));
3319 } 3312 }
3320 3313
3321 if ((flags & DOUBLE_ALIGNMENT) != 0) { 3314 if ((flags & DOUBLE_ALIGNMENT) != 0) {
3322 // Align the next allocation. Storing the filler map without checking top is 3315 // Align the next allocation. Storing the filler map without checking top is
3323 // safe in new-space because the limit of the heap is aligned there. 3316 // safe in new-space because the limit of the heap is aligned there.
3324 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 3317 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
3325 And(scratch2, result, Operand(kDoubleAlignmentMask)); 3318 And(result_end, result, Operand(kDoubleAlignmentMask));
3326 Label aligned; 3319 Label aligned;
3327 Branch(&aligned, eq, scratch2, Operand(zero_reg)); 3320 Branch(&aligned, eq, result_end, Operand(zero_reg));
3328 if ((flags & PRETENURE) != 0) { 3321 if ((flags & PRETENURE) != 0) {
3329 Branch(gc_required, Ugreater_equal, result, Operand(t9)); 3322 Branch(gc_required, Ugreater_equal, result, Operand(alloc_limit));
3330 } 3323 }
3331 li(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); 3324 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
3332 sw(scratch2, MemOperand(result)); 3325 sw(result_end, MemOperand(result));
3333 Addu(result, result, Operand(kDoubleSize / 2)); 3326 Addu(result, result, Operand(kDoubleSize / 2));
3334 bind(&aligned); 3327 bind(&aligned);
3335 } 3328 }
3336 3329
3337 // Calculate new top and bail out if new space is exhausted. Use result 3330 // Calculate new top and bail out if new space is exhausted. Use result
3338 // to calculate the new top. 3331 // to calculate the new top.
3339 Addu(scratch2, result, Operand(object_size)); 3332 Addu(result_end, result, Operand(object_size));
3340 Branch(gc_required, Ugreater, scratch2, Operand(t9)); 3333 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit));
3341 sw(scratch2, MemOperand(topaddr)); 3334 sw(result_end, MemOperand(top_address));
3342 3335
3343 // Tag object if requested. 3336 // Tag object if requested.
3344 if ((flags & TAG_OBJECT) != 0) { 3337 if ((flags & TAG_OBJECT) != 0) {
3345 Addu(result, result, Operand(kHeapObjectTag)); 3338 Addu(result, result, Operand(kHeapObjectTag));
3346 } 3339 }
3347 } 3340 }
3348 3341
3349 3342
3350 void MacroAssembler::Allocate(Register object_size, Register result, 3343 void MacroAssembler::Allocate(Register object_size, Register result,
3351 Register result_end, Register scratch1, 3344 Register result_end, Register scratch,
3352 Label* gc_required, AllocationFlags flags) { 3345 Label* gc_required, AllocationFlags flags) {
3353 if (!FLAG_inline_new) { 3346 if (!FLAG_inline_new) {
3354 if (emit_debug_code()) { 3347 if (emit_debug_code()) {
3355 // Trash the registers to simulate an allocation failure. 3348 // Trash the registers to simulate an allocation failure.
3356 li(result, 0x7091); 3349 li(result, 0x7091);
3357 li(scratch1, 0x7191); 3350 li(scratch, 0x7191);
3358 li(result_end, 0x7291); 3351 li(result_end, 0x7291);
3359 } 3352 }
3360 jmp(gc_required); 3353 jmp(gc_required);
3361 return; 3354 return;
3362 } 3355 }
3363 3356
3364 DCHECK(!result.is(scratch1)); 3357 // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
3365 DCHECK(!result.is(result_end)); 3358 // is not specified. Other registers must not overlap.
3366 DCHECK(!scratch1.is(result_end)); 3359 DCHECK(!AreAliased(object_size, result, scratch, t9));
3367 DCHECK(!object_size.is(t9)); 3360 DCHECK(!AreAliased(result_end, result, scratch, t9));
3368 DCHECK(!scratch1.is(t9) && !result_end.is(t9) && !result.is(t9)); 3361 DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
3369 3362
3370 // Check relative positions of allocation top and limit addresses. 3363 // Check relative positions of allocation top and limit addresses.
3371 // ARM adds additional checks to make sure the ldm instruction can be 3364 // ARM adds additional checks to make sure the ldm instruction can be
3372 // used. On MIPS we don't have ldm so we don't need additional checks either. 3365 // used. On MIPS we don't have ldm so we don't need additional checks either.
3373 ExternalReference allocation_top = 3366 ExternalReference allocation_top =
3374 AllocationUtils::GetAllocationTopReference(isolate(), flags); 3367 AllocationUtils::GetAllocationTopReference(isolate(), flags);
3375 ExternalReference allocation_limit = 3368 ExternalReference allocation_limit =
3376 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 3369 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3377 intptr_t top = 3370 intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
3378 reinterpret_cast<intptr_t>(allocation_top.address()); 3371 intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
3379 intptr_t limit =
3380 reinterpret_cast<intptr_t>(allocation_limit.address());
3381 DCHECK((limit - top) == kPointerSize); 3372 DCHECK((limit - top) == kPointerSize);
3382 3373
3383 // Set up allocation top address and object size registers. 3374 // Set up allocation top address and allocation limit registers.
3384 Register topaddr = scratch1; 3375 Register top_address = scratch;
3385 li(topaddr, Operand(allocation_top)); 3376 // This code stores a temporary value in t9.
3377 Register alloc_limit = t9;
3378 li(top_address, Operand(allocation_top));
3386 3379
3387 // This code stores a temporary value in t9.
3388 if ((flags & RESULT_CONTAINS_TOP) == 0) { 3380 if ((flags & RESULT_CONTAINS_TOP) == 0) {
3389 // Load allocation top into result and allocation limit into t9. 3381 // Load allocation top into result and allocation limit into alloc_limit.
3390 lw(result, MemOperand(topaddr)); 3382 lw(result, MemOperand(top_address));
3391 lw(t9, MemOperand(topaddr, kPointerSize)); 3383 lw(alloc_limit, MemOperand(top_address, kPointerSize));
3392 } else { 3384 } else {
3393 if (emit_debug_code()) { 3385 if (emit_debug_code()) {
3394 // Assert that result actually contains top on entry. t9 is used 3386 // Assert that result actually contains top on entry.
3395 // immediately below so this use of t9 does not cause difference with 3387 lw(alloc_limit, MemOperand(top_address));
3396 // respect to register content between debug and release mode. 3388 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit));
3397 lw(t9, MemOperand(topaddr));
3398 Check(eq, kUnexpectedAllocationTop, result, Operand(t9));
3399 } 3389 }
3400 // Load allocation limit into t9. Result already contains allocation top. 3390 // Load allocation limit. Result already contains allocation top.
3401 lw(t9, MemOperand(topaddr, limit - top)); 3391 lw(alloc_limit, MemOperand(top_address, limit - top));
3402 } 3392 }
3403 3393
3404 if ((flags & DOUBLE_ALIGNMENT) != 0) { 3394 if ((flags & DOUBLE_ALIGNMENT) != 0) {
3405 // Align the next allocation. Storing the filler map without checking top is 3395 // Align the next allocation. Storing the filler map without checking top is
3406 // safe in new-space because the limit of the heap is aligned there. 3396 // safe in new-space because the limit of the heap is aligned there.
3407 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 3397 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
3408 And(result_end, result, Operand(kDoubleAlignmentMask)); 3398 And(result_end, result, Operand(kDoubleAlignmentMask));
3409 Label aligned; 3399 Label aligned;
3410 Branch(&aligned, eq, result_end, Operand(zero_reg)); 3400 Branch(&aligned, eq, result_end, Operand(zero_reg));
3411 if ((flags & PRETENURE) != 0) { 3401 if ((flags & PRETENURE) != 0) {
3412 Branch(gc_required, Ugreater_equal, result, Operand(t9)); 3402 Branch(gc_required, Ugreater_equal, result, Operand(alloc_limit));
3413 } 3403 }
3414 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); 3404 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
3415 sw(result_end, MemOperand(result)); 3405 sw(result_end, MemOperand(result));
3416 Addu(result, result, Operand(kDoubleSize / 2)); 3406 Addu(result, result, Operand(kDoubleSize / 2));
3417 bind(&aligned); 3407 bind(&aligned);
3418 } 3408 }
3419 3409
3420 // Calculate new top and bail out if new space is exhausted. Use result 3410 // Calculate new top and bail out if new space is exhausted. Use result
3421 // to calculate the new top. Object size may be in words so a shift is 3411 // to calculate the new top. Object size may be in words so a shift is
3422 // required to get the number of bytes. 3412 // required to get the number of bytes.
3423 if ((flags & SIZE_IN_WORDS) != 0) { 3413 if ((flags & SIZE_IN_WORDS) != 0) {
3424 sll(result_end, object_size, kPointerSizeLog2); 3414 sll(result_end, object_size, kPointerSizeLog2);
3425 Addu(result_end, result, result_end); 3415 Addu(result_end, result, result_end);
3426 } else { 3416 } else {
3427 Addu(result_end, result, Operand(object_size)); 3417 Addu(result_end, result, Operand(object_size));
3428 } 3418 }
3429 Branch(gc_required, Ugreater, result_end, Operand(t9)); 3419 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit));
3430 3420
3431 // Update allocation top. result temporarily holds the new top. 3421 // Update allocation top. result temporarily holds the new top.
3432 if (emit_debug_code()) { 3422 if (emit_debug_code()) {
3433 And(t9, result_end, Operand(kObjectAlignmentMask)); 3423 And(alloc_limit, result_end, Operand(kObjectAlignmentMask));
3434 Check(eq, kUnalignedAllocationInNewSpace, t9, Operand(zero_reg)); 3424 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg));
3435 } 3425 }
3436 sw(result_end, MemOperand(topaddr)); 3426 sw(result_end, MemOperand(top_address));
3437 3427
3438 // Tag object if requested. 3428 // Tag object if requested.
3439 if ((flags & TAG_OBJECT) != 0) { 3429 if ((flags & TAG_OBJECT) != 0) {
3440 Addu(result, result, Operand(kHeapObjectTag)); 3430 Addu(result, result, Operand(kHeapObjectTag));
3441 } 3431 }
3442 } 3432 }
3443 3433
3444 3434
3445 void MacroAssembler::AllocateTwoByteString(Register result, 3435 void MacroAssembler::AllocateTwoByteString(Register result,
3446 Register length, 3436 Register length,
(...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after
5845 if (mag.shift > 0) sra(result, result, mag.shift); 5835 if (mag.shift > 0) sra(result, result, mag.shift);
5846 srl(at, dividend, 31); 5836 srl(at, dividend, 31);
5847 Addu(result, result, Operand(at)); 5837 Addu(result, result, Operand(at));
5848 } 5838 }
5849 5839
5850 5840
5851 } // namespace internal 5841 } // namespace internal
5852 } // namespace v8 5842 } // namespace v8
5853 5843
5854 #endif // V8_TARGET_ARCH_MIPS 5844 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips64/builtins-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698