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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 7992003: Porting r9392 to x64 (smi-only arrays). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: save one memory access. Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); 1435 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
1436 __ addl(rax, Immediate(argc)); 1436 __ addl(rax, Immediate(argc));
1437 1437
1438 // Get the element's length into rcx. 1438 // Get the element's length into rcx.
1439 __ SmiToInteger32(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); 1439 __ SmiToInteger32(rcx, FieldOperand(rbx, FixedArray::kLengthOffset));
1440 1440
1441 // Check if we could survive without allocation. 1441 // Check if we could survive without allocation.
1442 __ cmpl(rax, rcx); 1442 __ cmpl(rax, rcx);
1443 __ j(greater, &attempt_to_grow_elements); 1443 __ j(greater, &attempt_to_grow_elements);
1444 1444
1445 // Check if value is a smi.
1446 __ movq(rcx, Operand(rsp, argc * kPointerSize));
1447 __ JumpIfNotSmi(rcx, &with_write_barrier);
1448
1445 // Save new length. 1449 // Save new length.
1446 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1450 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1447 1451
1448 // Push the element. 1452 // Push the element.
1449 __ movq(rcx, Operand(rsp, argc * kPointerSize));
1450 __ lea(rdx, FieldOperand(rbx, 1453 __ lea(rdx, FieldOperand(rbx,
1451 rax, times_pointer_size, 1454 rax, times_pointer_size,
1452 FixedArray::kHeaderSize - argc * kPointerSize)); 1455 FixedArray::kHeaderSize - argc * kPointerSize));
1453 __ movq(Operand(rdx, 0), rcx); 1456 __ movq(Operand(rdx, 0), rcx);
1454 1457
1455 // Check if value is a smi.
1456 __ Integer32ToSmi(rax, rax); // Return new length as smi. 1458 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1457
1458 __ JumpIfNotSmi(rcx, &with_write_barrier);
1459
1460 __ ret((argc + 1) * kPointerSize); 1459 __ ret((argc + 1) * kPointerSize);
1461 1460
1462 __ bind(&with_write_barrier); 1461 __ bind(&with_write_barrier);
1463 1462
1463 if (FLAG_smi_only_arrays) {
1464 __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset));
1465 __ CheckFastObjectElements(rdi, &call_builtin);
1466 }
1467
1468 // Save new length.
1469 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1470
1471 // Push the element.
1472 __ lea(rdx, FieldOperand(rbx,
1473 rax, times_pointer_size,
1474 FixedArray::kHeaderSize - argc * kPointerSize));
1475 __ movq(Operand(rdx, 0), rcx);
1476
1464 __ RecordWrite( 1477 __ RecordWrite(
1465 rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 1478 rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
1466 1479
1480 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1467 __ ret((argc + 1) * kPointerSize); 1481 __ ret((argc + 1) * kPointerSize);
1468 1482
1469 __ bind(&attempt_to_grow_elements); 1483 __ bind(&attempt_to_grow_elements);
1470 if (!FLAG_inline_new) { 1484 if (!FLAG_inline_new) {
1471 __ jmp(&call_builtin); 1485 __ jmp(&call_builtin);
1472 } 1486 }
1473 1487
1488 __ movq(rdi, Operand(rsp, argc * kPointerSize));
1489 if (FLAG_smi_only_arrays) {
1490 // Growing elements that are SMI-only requires special handling in case
1491 // the new element is non-Smi. For now, delegate to the builtin.
1492 Label no_fast_elements_check;
1493 __ JumpIfSmi(rdi, &no_fast_elements_check);
1494 __ movq(rsi, FieldOperand(rdx, HeapObject::kMapOffset));
1495 __ CheckFastObjectElements(rsi, &call_builtin, Label::kFar);
1496 __ bind(&no_fast_elements_check);
1497 }
1498
1474 ExternalReference new_space_allocation_top = 1499 ExternalReference new_space_allocation_top =
1475 ExternalReference::new_space_allocation_top_address(isolate()); 1500 ExternalReference::new_space_allocation_top_address(isolate());
1476 ExternalReference new_space_allocation_limit = 1501 ExternalReference new_space_allocation_limit =
1477 ExternalReference::new_space_allocation_limit_address(isolate()); 1502 ExternalReference::new_space_allocation_limit_address(isolate());
1478 1503
1479 const int kAllocationDelta = 4; 1504 const int kAllocationDelta = 4;
1480 // Load top. 1505 // Load top.
1481 __ Load(rcx, new_space_allocation_top); 1506 __ Load(rcx, new_space_allocation_top);
1482 1507
1483 // Check if it's the end of elements. 1508 // Check if it's the end of elements.
1484 __ lea(rdx, FieldOperand(rbx, 1509 __ lea(rdx, FieldOperand(rbx,
1485 rax, times_pointer_size, 1510 rax, times_pointer_size,
1486 FixedArray::kHeaderSize - argc * kPointerSize)); 1511 FixedArray::kHeaderSize - argc * kPointerSize));
1487 __ cmpq(rdx, rcx); 1512 __ cmpq(rdx, rcx);
1488 __ j(not_equal, &call_builtin); 1513 __ j(not_equal, &call_builtin);
1489 __ addq(rcx, Immediate(kAllocationDelta * kPointerSize)); 1514 __ addq(rcx, Immediate(kAllocationDelta * kPointerSize));
1490 Operand limit_operand = 1515 Operand limit_operand =
1491 masm()->ExternalOperand(new_space_allocation_limit); 1516 masm()->ExternalOperand(new_space_allocation_limit);
1492 __ cmpq(rcx, limit_operand); 1517 __ cmpq(rcx, limit_operand);
1493 __ j(above, &call_builtin); 1518 __ j(above, &call_builtin);
1494 1519
1495 // We fit and could grow elements. 1520 // We fit and could grow elements.
1496 __ Store(new_space_allocation_top, rcx); 1521 __ Store(new_space_allocation_top, rcx);
1497 __ movq(rcx, Operand(rsp, argc * kPointerSize)); 1522 __ movq(rcx, Operand(rsp, argc * kPointerSize));
William Hesse 2011/09/23 13:25:22 Is this move to rcx now a dead value? If so, remo
Yang 2011/09/23 14:19:12 Done.
1498 1523
1499 // Push the argument... 1524 // Push the argument...
1500 __ movq(Operand(rdx, 0), rcx); 1525 __ movq(Operand(rdx, 0), rdi);
1501 // ... and fill the rest with holes. 1526 // ... and fill the rest with holes.
1502 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 1527 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
1503 for (int i = 1; i < kAllocationDelta; i++) { 1528 for (int i = 1; i < kAllocationDelta; i++) {
1504 __ movq(Operand(rdx, i * kPointerSize), kScratchRegister); 1529 __ movq(Operand(rdx, i * kPointerSize), kScratchRegister);
1505 } 1530 }
1506 1531
1507 // We know the elements array is in new space so we don't need the 1532 // We know the elements array is in new space so we don't need the
1508 // remembered set, but we just pushed a value onto it so we may have to 1533 // remembered set, but we just pushed a value onto it so we may have to
1509 // tell the incremental marker to rescan the object that we just grew. We 1534 // tell the incremental marker to rescan the object that we just grew. We
1510 // don't need to worry about the holes because they are in old space and 1535 // don't need to worry about the holes because they are in old space and
1511 // already marked black. 1536 // already marked black.
1512 __ RecordWrite(rbx, rdx, rcx, kDontSaveFPRegs, OMIT_REMEMBERED_SET); 1537 __ RecordWrite(rbx, rdx, rdi, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
1513 1538
1514 // Restore receiver to rdx as finish sequence assumes it's here. 1539 // Restore receiver to rdx as finish sequence assumes it's here.
1515 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1540 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1516 1541
1517 // Increment element's and array's sizes. 1542 // Increment element's and array's sizes.
1518 __ SmiAddConstant(FieldOperand(rbx, FixedArray::kLengthOffset), 1543 __ SmiAddConstant(FieldOperand(rbx, FixedArray::kLengthOffset),
1519 Smi::FromInt(kAllocationDelta)); 1544 Smi::FromInt(kAllocationDelta));
1520 1545
1521 // Make new length a smi before returning it. 1546 // Make new length a smi before returning it.
1522 __ Integer32ToSmi(rax, rax); 1547 __ Integer32ToSmi(rax, rax);
(...skipping 2169 matching lines...) Expand 10 before | Expand all | Expand 10 after
3692 if (is_js_array) { 3717 if (is_js_array) {
3693 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); 3718 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset));
3694 __ j(above_equal, &miss_force_generic); 3719 __ j(above_equal, &miss_force_generic);
3695 } else { 3720 } else {
3696 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 3721 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
3697 __ j(above_equal, &miss_force_generic); 3722 __ j(above_equal, &miss_force_generic);
3698 } 3723 }
3699 3724
3700 // Do the store and update the write barrier. 3725 // Do the store and update the write barrier.
3701 __ SmiToInteger32(rcx, rcx); 3726 __ SmiToInteger32(rcx, rcx);
3702 __ lea(rcx, 3727 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3703 FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize)); 3728 __ JumpIfNotSmi(rax, &miss_force_generic);
3704 __ movq(Operand(rcx, 0), rax); 3729 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize),
3705 // Make sure to preserve the value in register rax. 3730 rax);
3706 __ movq(rdx, rax); 3731 } else {
3707 ASSERT(elements_kind == FAST_ELEMENTS); 3732 ASSERT(elements_kind == FAST_ELEMENTS);
3708 __ RecordWrite(rdi, rcx, rdx, kDontSaveFPRegs); 3733 __ lea(rcx,
3734 FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize));
3735 __ movq(Operand(rcx, 0), rax);
3736 // Make sure to preserve the value in register rax.
3737 __ movq(rdx, rax);
3738 __ RecordWrite(rdi, rcx, rdx, kDontSaveFPRegs);
3739 }
3709 3740
3710 // Done. 3741 // Done.
3711 __ ret(0); 3742 __ ret(0);
3712 3743
3713 // Handle store cache miss. 3744 // Handle store cache miss.
3714 __ bind(&miss_force_generic); 3745 __ bind(&miss_force_generic);
3715 Handle<Code> ic_force_generic = 3746 Handle<Code> ic_force_generic =
3716 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3747 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3717 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3748 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3718 } 3749 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3801 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3832 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3802 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3833 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3803 } 3834 }
3804 3835
3805 3836
3806 #undef __ 3837 #undef __
3807 3838
3808 } } // namespace v8::internal 3839 } } // namespace v8::internal
3809 3840
3810 #endif // V8_TARGET_ARCH_X64 3841 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698