 Chromium Code Reviews
 Chromium Code Reviews Issue 7992003:
  Porting r9392 to x64 (smi-only arrays).  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 7992003:
  Porting r9392 to x64 (smi-only arrays).  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| OLD | NEW | 
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 | 
| OLD | NEW |