Chromium Code Reviews| 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 |