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 1562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1573 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | 1573 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
1574 | 1574 |
1575 // Check that the elements are in fast mode and writable. | 1575 // Check that the elements are in fast mode and writable. |
1576 __ CheckMap(elements, | 1576 __ CheckMap(elements, |
1577 r0, | 1577 r0, |
1578 Heap::kFixedArrayMapRootIndex, | 1578 Heap::kFixedArrayMapRootIndex, |
1579 &call_builtin, | 1579 &call_builtin, |
1580 DONT_DO_SMI_CHECK); | 1580 DONT_DO_SMI_CHECK); |
1581 | 1581 |
1582 if (argc == 1) { // Otherwise fall through to call the builtin. | 1582 if (argc == 1) { // Otherwise fall through to call the builtin. |
1583 Label exit, attempt_to_grow_elements; | 1583 Label attempt_to_grow_elements; |
1584 | 1584 |
1585 // Get the array's length into r0 and calculate new length. | 1585 // Get the array's length into r0 and calculate new length. |
1586 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1586 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1587 STATIC_ASSERT(kSmiTagSize == 1); | 1587 STATIC_ASSERT(kSmiTagSize == 1); |
1588 STATIC_ASSERT(kSmiTag == 0); | 1588 STATIC_ASSERT(kSmiTag == 0); |
1589 __ add(r0, r0, Operand(Smi::FromInt(argc))); | 1589 __ add(r0, r0, Operand(Smi::FromInt(argc))); |
1590 | 1590 |
1591 // Get the element's length. | 1591 // Get the element's length. |
1592 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1592 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
1593 | 1593 |
1594 // Check if we could survive without allocation. | 1594 // Check if we could survive without allocation. |
1595 __ cmp(r0, r4); | 1595 __ cmp(r0, r4); |
1596 __ b(gt, &attempt_to_grow_elements); | 1596 __ b(gt, &attempt_to_grow_elements); |
1597 | 1597 |
1598 // Check if value is a smi. | |
1599 Label with_write_barrier; | |
1600 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); | |
1601 __ JumpIfNotSmi(r4, &with_write_barrier); | |
1602 | |
1598 // Save new length. | 1603 // Save new length. |
1599 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1604 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1600 | 1605 |
1601 // Push the element. | 1606 // Push the element. |
1602 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); | |
1603 // We may need a register containing the address end_elements below, | 1607 // We may need a register containing the address end_elements below, |
1604 // so write back the value in end_elements. | 1608 // so write back the value in end_elements. |
1605 __ add(end_elements, elements, | 1609 __ add(end_elements, elements, |
1606 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1610 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
1607 const int kEndElementsOffset = | 1611 const int kEndElementsOffset = |
1608 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; | 1612 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; |
1609 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); | 1613 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); |
1610 | 1614 |
1611 // Check for a smi. | 1615 // Check for a smi. |
1612 Label with_write_barrier; | |
1613 __ JumpIfNotSmi(r4, &with_write_barrier); | |
1614 __ bind(&exit); | |
1615 __ Drop(argc + 1); | 1616 __ Drop(argc + 1); |
1616 __ Ret(); | 1617 __ Ret(); |
1617 | 1618 |
1618 __ bind(&with_write_barrier); | 1619 __ bind(&with_write_barrier); |
1620 | |
1621 if (FLAG_smi_only_arrays) { | |
1622 __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset)); | |
1623 __ CheckFastSmiOnlyElements(r6, r6, &call_builtin); | |
1624 } | |
1625 | |
1626 // Save new length. | |
1627 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | |
1628 | |
1629 // Push the element. | |
1630 // We may need a register containing the address end_elements below, | |
1631 // so write back the value in end_elements. | |
1632 __ add(end_elements, elements, | |
1633 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
1634 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); | |
1635 | |
1619 __ RecordWrite(elements, | 1636 __ RecordWrite(elements, |
1620 end_elements, | 1637 end_elements, |
1621 r4, | 1638 r4, |
1622 kLRHasNotBeenSaved, | 1639 kLRHasNotBeenSaved, |
1623 kDontSaveFPRegs, | 1640 kDontSaveFPRegs, |
1624 EMIT_REMEMBERED_SET, | 1641 EMIT_REMEMBERED_SET, |
1625 OMIT_SMI_CHECK); | 1642 OMIT_SMI_CHECK); |
1626 __ Drop(argc + 1); | 1643 __ Drop(argc + 1); |
1627 __ Ret(); | 1644 __ Ret(); |
1628 | 1645 |
1629 __ bind(&attempt_to_grow_elements); | 1646 __ bind(&attempt_to_grow_elements); |
1630 // r0: array's length + 1. | 1647 // r0: array's length + 1. |
1631 // r4: elements' length. | 1648 // r4: elements' length. |
1632 | 1649 |
1633 if (!FLAG_inline_new) { | 1650 if (!FLAG_inline_new) { |
1634 __ b(&call_builtin); | 1651 __ b(&call_builtin); |
1635 } | 1652 } |
1636 | 1653 |
1654 __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize)); | |
1655 if (FLAG_smi_only_arrays) { | |
1656 // Growing elements that are SMI-only requires special handling in case | |
1657 // the new element is non-Smi. For now, delegate to the builtin. | |
1658 Label no_fast_elements_check; | |
1659 __ JumpIfSmi(r2, &no_fast_elements_check); | |
1660 __ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset)); | |
1661 __ CheckFastObjectElements(r7, r7, &call_builtin); | |
1662 __ bind(&no_fast_elements_check); | |
1663 } | |
1664 | |
1637 Isolate* isolate = masm()->isolate(); | 1665 Isolate* isolate = masm()->isolate(); |
1638 ExternalReference new_space_allocation_top = | 1666 ExternalReference new_space_allocation_top = |
1639 ExternalReference::new_space_allocation_top_address(isolate); | 1667 ExternalReference::new_space_allocation_top_address(isolate); |
1640 ExternalReference new_space_allocation_limit = | 1668 ExternalReference new_space_allocation_limit = |
1641 ExternalReference::new_space_allocation_limit_address(isolate); | 1669 ExternalReference::new_space_allocation_limit_address(isolate); |
1642 | 1670 |
1643 const int kAllocationDelta = 4; | 1671 const int kAllocationDelta = 4; |
1644 // Load top and check if it is the end of elements. | 1672 // Load top and check if it is the end of elements. |
1645 __ add(end_elements, elements, | 1673 __ add(end_elements, elements, |
1646 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1674 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
1647 __ add(end_elements, end_elements, Operand(kEndElementsOffset)); | 1675 __ add(end_elements, end_elements, Operand(kEndElementsOffset)); |
1648 __ mov(r7, Operand(new_space_allocation_top)); | 1676 __ mov(r7, Operand(new_space_allocation_top)); |
1649 __ ldr(r6, MemOperand(r7)); | 1677 __ ldr(r6, MemOperand(r7)); |
1650 __ cmp(end_elements, r6); | 1678 __ cmp(end_elements, r6); |
1651 __ b(ne, &call_builtin); | 1679 __ b(ne, &call_builtin); |
1652 | 1680 |
1653 __ mov(r9, Operand(new_space_allocation_limit)); | 1681 __ mov(r9, Operand(new_space_allocation_limit)); |
1654 __ ldr(r9, MemOperand(r9)); | 1682 __ ldr(r9, MemOperand(r9)); |
1655 __ add(r6, r6, Operand(kAllocationDelta * kPointerSize)); | 1683 __ add(r6, r6, Operand(kAllocationDelta * kPointerSize)); |
1656 __ cmp(r6, r9); | 1684 __ cmp(r6, r9); |
1657 __ b(hi, &call_builtin); | 1685 __ b(hi, &call_builtin); |
1658 | 1686 |
1659 // We fit and could grow elements. | 1687 // We fit and could grow elements. |
1660 // Update new_space_allocation_top. | 1688 // Update new_space_allocation_top. |
1661 __ str(r6, MemOperand(r7)); | 1689 __ str(r6, MemOperand(r7)); |
1662 // Push the argument. | 1690 // Push the argument. |
1663 __ ldr(r6, MemOperand(sp, (argc - 1) * kPointerSize)); | 1691 __ str(r2, MemOperand(end_elements)); |
1664 __ str(r6, MemOperand(end_elements)); | |
1665 // Fill the rest with holes. | 1692 // Fill the rest with holes. |
1666 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex); | 1693 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex); |
1667 for (int i = 1; i < kAllocationDelta; i++) { | 1694 for (int i = 1; i < kAllocationDelta; i++) { |
1668 __ str(r6, MemOperand(end_elements, i * kPointerSize)); | 1695 __ str(r6, MemOperand(end_elements, i * kPointerSize)); |
1669 } | 1696 } |
1670 | 1697 |
1671 // Update elements' and array's sizes. | 1698 // Update elements' and array's sizes. |
1672 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1699 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1673 __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta))); | 1700 __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta))); |
1674 __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1701 __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
(...skipping 2641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4316 // Check that the key is within bounds. | 4343 // Check that the key is within bounds. |
4317 if (is_js_array) { | 4344 if (is_js_array) { |
4318 __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | 4345 __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
4319 } else { | 4346 } else { |
4320 __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 4347 __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
4321 } | 4348 } |
4322 // Compare smis. | 4349 // Compare smis. |
4323 __ cmp(key_reg, scratch); | 4350 __ cmp(key_reg, scratch); |
4324 __ b(hs, &miss_force_generic); | 4351 __ b(hs, &miss_force_generic); |
4325 | 4352 |
4326 __ add(scratch, | 4353 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
4327 elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 4354 __ JumpIfNotSmi(value_reg, &miss_force_generic); |
4328 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); | 4355 __ add(scratch, |
4329 __ add(scratch, | 4356 elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
4330 scratch, | 4357 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
4331 Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize)); | 4358 __ add(scratch, |
4332 __ str(value_reg, MemOperand(scratch)); | 4359 scratch, |
4333 __ mov(receiver_reg, value_reg); | 4360 Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize)); |
4334 ASSERT(elements_kind == FAST_ELEMENTS); | 4361 __ str(value_reg, MemOperand(scratch)); |
4335 __ RecordWrite(elements_reg, // Object. | 4362 } else { |
4336 scratch, // Address. | 4363 ASSERT(elements_kind == FAST_ELEMENTS); |
4337 receiver_reg, // Value. | 4364 __ add(scratch, |
4338 kLRHasNotBeenSaved, | 4365 elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
Rico
2011/09/22 17:06:07
Nit: move last argument to next line
| |
4339 kDontSaveFPRegs); | 4366 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
4340 | 4367 __ add(scratch, |
4368 scratch, | |
4369 Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
4370 __ str(value_reg, MemOperand(scratch)); | |
4371 __ mov(receiver_reg, value_reg); | |
4372 __ RecordWrite(elements_reg, // Object. | |
4373 scratch, // Address. | |
4374 receiver_reg, // Value. | |
4375 kLRHasNotBeenSaved, | |
4376 kDontSaveFPRegs); | |
4377 } | |
4341 // value_reg (r0) is preserved. | 4378 // value_reg (r0) is preserved. |
4342 // Done. | 4379 // Done. |
4343 __ Ret(); | 4380 __ Ret(); |
4344 | 4381 |
4345 __ bind(&miss_force_generic); | 4382 __ bind(&miss_force_generic); |
4346 Handle<Code> ic = | 4383 Handle<Code> ic = |
4347 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4384 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
4348 __ Jump(ic, RelocInfo::CODE_TARGET); | 4385 __ Jump(ic, RelocInfo::CODE_TARGET); |
4349 } | 4386 } |
4350 | 4387 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4473 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4510 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
4474 __ Jump(ic, RelocInfo::CODE_TARGET); | 4511 __ Jump(ic, RelocInfo::CODE_TARGET); |
4475 } | 4512 } |
4476 | 4513 |
4477 | 4514 |
4478 #undef __ | 4515 #undef __ |
4479 | 4516 |
4480 } } // namespace v8::internal | 4517 } } // namespace v8::internal |
4481 | 4518 |
4482 #endif // V8_TARGET_ARCH_ARM | 4519 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |