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 |