OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1462 | 1462 |
1463 | 1463 |
1464 void MacroAssembler::Allocate(int object_size, | 1464 void MacroAssembler::Allocate(int object_size, |
1465 Register result, | 1465 Register result, |
1466 Register result_end, | 1466 Register result_end, |
1467 Register scratch, | 1467 Register scratch, |
1468 Label* gc_required, | 1468 Label* gc_required, |
1469 AllocationFlags flags) { | 1469 AllocationFlags flags) { |
1470 DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); | 1470 DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); |
1471 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 1471 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
1472 DCHECK((flags & ALLOCATION_FOLDED) == 0); | |
1472 if (!FLAG_inline_new) { | 1473 if (!FLAG_inline_new) { |
1473 if (emit_debug_code()) { | 1474 if (emit_debug_code()) { |
1474 // Trash the registers to simulate an allocation failure. | 1475 // Trash the registers to simulate an allocation failure. |
1475 mov(result, Immediate(0x7091)); | 1476 mov(result, Immediate(0x7091)); |
1476 if (result_end.is_valid()) { | 1477 if (result_end.is_valid()) { |
1477 mov(result_end, Immediate(0x7191)); | 1478 mov(result_end, Immediate(0x7191)); |
1478 } | 1479 } |
1479 if (scratch.is_valid()) { | 1480 if (scratch.is_valid()) { |
1480 mov(scratch, Immediate(0x7291)); | 1481 mov(scratch, Immediate(0x7291)); |
1481 } | 1482 } |
(...skipping 21 matching lines...) Expand all Loading... | |
1503 j(above_equal, gc_required); | 1504 j(above_equal, gc_required); |
1504 } | 1505 } |
1505 mov(Operand(result, 0), | 1506 mov(Operand(result, 0), |
1506 Immediate(isolate()->factory()->one_pointer_filler_map())); | 1507 Immediate(isolate()->factory()->one_pointer_filler_map())); |
1507 add(result, Immediate(kDoubleSize / 2)); | 1508 add(result, Immediate(kDoubleSize / 2)); |
1508 bind(&aligned); | 1509 bind(&aligned); |
1509 } | 1510 } |
1510 | 1511 |
1511 // Calculate new top and bail out if space is exhausted. | 1512 // Calculate new top and bail out if space is exhausted. |
1512 Register top_reg = result_end.is_valid() ? result_end : result; | 1513 Register top_reg = result_end.is_valid() ? result_end : result; |
1514 | |
1513 if (!top_reg.is(result)) { | 1515 if (!top_reg.is(result)) { |
1514 mov(top_reg, result); | 1516 mov(top_reg, result); |
1515 } | 1517 } |
1516 add(top_reg, Immediate(object_size)); | 1518 add(top_reg, Immediate(object_size)); |
1517 cmp(top_reg, Operand::StaticVariable(allocation_limit)); | 1519 cmp(top_reg, Operand::StaticVariable(allocation_limit)); |
1518 j(above, gc_required); | 1520 j(above, gc_required); |
1519 | 1521 |
1520 // Update allocation top. | 1522 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
1521 UpdateAllocationTopHelper(top_reg, scratch, flags); | 1523 // The top pointer is not updated for allocation folding dominators. |
1524 UpdateAllocationTopHelper(top_reg, scratch, flags); | |
1525 } | |
1522 | 1526 |
1523 if (top_reg.is(result)) { | 1527 if (top_reg.is(result)) { |
1524 sub(result, Immediate(object_size - kHeapObjectTag)); | 1528 sub(result, Immediate(object_size - kHeapObjectTag)); |
1525 } else { | 1529 } else { |
1526 // Tag the result. | 1530 // Tag the result. |
1527 DCHECK(kHeapObjectTag == 1); | 1531 DCHECK(kHeapObjectTag == 1); |
1528 inc(result); | 1532 inc(result); |
1529 } | 1533 } |
1530 } | 1534 } |
1531 | 1535 |
1532 | 1536 |
1533 void MacroAssembler::Allocate(int header_size, | 1537 void MacroAssembler::Allocate(int header_size, |
1534 ScaleFactor element_size, | 1538 ScaleFactor element_size, |
1535 Register element_count, | 1539 Register element_count, |
1536 RegisterValueType element_count_type, | 1540 RegisterValueType element_count_type, |
1537 Register result, | 1541 Register result, |
1538 Register result_end, | 1542 Register result_end, |
1539 Register scratch, | 1543 Register scratch, |
1540 Label* gc_required, | 1544 Label* gc_required, |
1541 AllocationFlags flags) { | 1545 AllocationFlags flags) { |
1542 DCHECK((flags & SIZE_IN_WORDS) == 0); | 1546 DCHECK((flags & SIZE_IN_WORDS) == 0); |
1547 DCHECK((flags & ALLOCATION_FOLDING_DOMINATOR) == 0); | |
1548 DCHECK((flags & ALLOCATION_FOLDED) == 0); | |
1543 if (!FLAG_inline_new) { | 1549 if (!FLAG_inline_new) { |
1544 if (emit_debug_code()) { | 1550 if (emit_debug_code()) { |
1545 // Trash the registers to simulate an allocation failure. | 1551 // Trash the registers to simulate an allocation failure. |
1546 mov(result, Immediate(0x7091)); | 1552 mov(result, Immediate(0x7091)); |
1547 mov(result_end, Immediate(0x7191)); | 1553 mov(result_end, Immediate(0x7191)); |
1548 if (scratch.is_valid()) { | 1554 if (scratch.is_valid()) { |
1549 mov(scratch, Immediate(0x7291)); | 1555 mov(scratch, Immediate(0x7291)); |
1550 } | 1556 } |
1551 // Register element_count is not modified by the function. | 1557 // Register element_count is not modified by the function. |
1552 } | 1558 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1598 j(above, gc_required); | 1604 j(above, gc_required); |
1599 | 1605 |
1600 // Tag result. | 1606 // Tag result. |
1601 DCHECK(kHeapObjectTag == 1); | 1607 DCHECK(kHeapObjectTag == 1); |
1602 inc(result); | 1608 inc(result); |
1603 | 1609 |
1604 // Update allocation top. | 1610 // Update allocation top. |
1605 UpdateAllocationTopHelper(result_end, scratch, flags); | 1611 UpdateAllocationTopHelper(result_end, scratch, flags); |
1606 } | 1612 } |
1607 | 1613 |
1608 | |
1609 void MacroAssembler::Allocate(Register object_size, | 1614 void MacroAssembler::Allocate(Register object_size, |
1610 Register result, | 1615 Register result, |
1611 Register result_end, | 1616 Register result_end, |
1612 Register scratch, | 1617 Register scratch, |
1613 Label* gc_required, | 1618 Label* gc_required, |
1614 AllocationFlags flags) { | 1619 AllocationFlags flags) { |
1615 DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); | 1620 DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); |
1621 DCHECK((flags & ALLOCATION_FOLDED) == 0); | |
1616 if (!FLAG_inline_new) { | 1622 if (!FLAG_inline_new) { |
1617 if (emit_debug_code()) { | 1623 if (emit_debug_code()) { |
1618 // Trash the registers to simulate an allocation failure. | 1624 // Trash the registers to simulate an allocation failure. |
1619 mov(result, Immediate(0x7091)); | 1625 mov(result, Immediate(0x7091)); |
1620 mov(result_end, Immediate(0x7191)); | 1626 mov(result_end, Immediate(0x7191)); |
1621 if (scratch.is_valid()) { | 1627 if (scratch.is_valid()) { |
1622 mov(scratch, Immediate(0x7291)); | 1628 mov(scratch, Immediate(0x7291)); |
1623 } | 1629 } |
1624 // object_size is left unchanged by this function. | 1630 // object_size is left unchanged by this function. |
1625 } | 1631 } |
1626 jmp(gc_required); | 1632 jmp(gc_required); |
1627 return; | 1633 return; |
1628 } | 1634 } |
1629 DCHECK(!result.is(result_end)); | 1635 DCHECK(!result.is(result_end)); |
1630 | 1636 |
1631 // Load address of new object into result. | 1637 // Load address of new object into result. |
1632 LoadAllocationTopHelper(result, scratch, flags); | 1638 LoadAllocationTopHelper(result, scratch, flags); |
1633 | 1639 |
1634 ExternalReference allocation_limit = | 1640 ExternalReference allocation_limit = |
1635 AllocationUtils::GetAllocationLimitReference(isolate(), flags); | 1641 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
1636 | 1642 |
1637 // Align the next allocation. Storing the filler map without checking top is | 1643 // Align the next allocation. Storing the filler map without checking top is |
1638 // safe in new-space because the limit of the heap is aligned there. | 1644 // safe in new-space because the limit of the heap is aligned there. |
1639 if ((flags & DOUBLE_ALIGNMENT) != 0) { | 1645 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
1640 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); | 1646 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); |
1641 Label aligned; | 1647 Label aligned; |
1642 test(result, Immediate(kDoubleAlignmentMask)); | 1648 test(result, Immediate(kDoubleAlignmentMask)); |
1643 j(zero, &aligned, Label::kNear); | 1649 j(zero, &aligned, Label::kNear); |
1644 if ((flags & PRETENURE) != 0) { | 1650 if (((flags & ALLOCATION_FOLDED) == 0) && ((flags & PRETENURE) != 0)) { |
Michael Lippautz
2016/05/10 09:04:10
Same as w/ other platforms: Remove ALLOCATION_FOLD
Hannes Payer (out of office)
2016/05/10 09:10:59
Done.
| |
1645 cmp(result, Operand::StaticVariable(allocation_limit)); | 1651 cmp(result, Operand::StaticVariable(allocation_limit)); |
1646 j(above_equal, gc_required); | 1652 j(above_equal, gc_required); |
1647 } | 1653 } |
1648 mov(Operand(result, 0), | 1654 mov(Operand(result, 0), |
1649 Immediate(isolate()->factory()->one_pointer_filler_map())); | 1655 Immediate(isolate()->factory()->one_pointer_filler_map())); |
1650 add(result, Immediate(kDoubleSize / 2)); | 1656 add(result, Immediate(kDoubleSize / 2)); |
1651 bind(&aligned); | 1657 bind(&aligned); |
1652 } | 1658 } |
1653 | 1659 |
1654 // Calculate new top and bail out if space is exhausted. | 1660 // Calculate new top and bail out if space is exhausted. |
1655 if (!object_size.is(result_end)) { | 1661 if (!object_size.is(result_end)) { |
1656 mov(result_end, object_size); | 1662 mov(result_end, object_size); |
1657 } | 1663 } |
1658 add(result_end, result); | 1664 add(result_end, result); |
1659 j(carry, gc_required); | |
1660 cmp(result_end, Operand::StaticVariable(allocation_limit)); | 1665 cmp(result_end, Operand::StaticVariable(allocation_limit)); |
1661 j(above, gc_required); | 1666 j(above, gc_required); |
1662 | 1667 |
1663 // Tag result. | 1668 // Tag result. |
1664 DCHECK(kHeapObjectTag == 1); | 1669 DCHECK(kHeapObjectTag == 1); |
1665 inc(result); | 1670 inc(result); |
1666 | 1671 |
1667 // Update allocation top. | 1672 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { |
1668 UpdateAllocationTopHelper(result_end, scratch, flags); | 1673 // The top pointer is not updated for allocation folding dominators. |
1674 UpdateAllocationTopHelper(result_end, scratch, flags); | |
1675 } | |
1669 } | 1676 } |
1670 | 1677 |
1678 void MacroAssembler::FastAllocate(int object_size, Register result, | |
1679 Register result_end, AllocationFlags flags) { | |
1680 DCHECK(!result.is(result_end)); | |
1681 // Load address of new object into result. | |
1682 LoadAllocationTopHelper(result, no_reg, flags); | |
1683 | |
1684 if ((flags & DOUBLE_ALIGNMENT) != 0) { | |
1685 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); | |
1686 Label aligned; | |
1687 test(result, Immediate(kDoubleAlignmentMask)); | |
1688 j(zero, &aligned, Label::kNear); | |
1689 mov(Operand(result, 0), | |
1690 Immediate(isolate()->factory()->one_pointer_filler_map())); | |
1691 add(result, Immediate(kDoubleSize / 2)); | |
1692 bind(&aligned); | |
1693 } | |
1694 | |
1695 lea(result_end, Operand(result, object_size)); | |
1696 UpdateAllocationTopHelper(result_end, no_reg, flags); | |
1697 | |
1698 DCHECK(kHeapObjectTag == 1); | |
1699 inc(result); | |
1700 } | |
1701 | |
1702 void MacroAssembler::FastAllocate(Register object_size, Register result, | |
1703 Register result_end, AllocationFlags flags) { | |
1704 DCHECK(!result.is(result_end)); | |
1705 // Load address of new object into result. | |
1706 LoadAllocationTopHelper(result, no_reg, flags); | |
1707 | |
1708 if ((flags & DOUBLE_ALIGNMENT) != 0) { | |
1709 DCHECK(kPointerAlignment * 2 == kDoubleAlignment); | |
1710 Label aligned; | |
1711 test(result, Immediate(kDoubleAlignmentMask)); | |
1712 j(zero, &aligned, Label::kNear); | |
1713 mov(Operand(result, 0), | |
1714 Immediate(isolate()->factory()->one_pointer_filler_map())); | |
1715 add(result, Immediate(kDoubleSize / 2)); | |
1716 bind(&aligned); | |
1717 } | |
1718 | |
1719 lea(result_end, Operand(result, object_size, times_1, 0)); | |
1720 UpdateAllocationTopHelper(result_end, no_reg, flags); | |
1721 | |
1722 DCHECK(kHeapObjectTag == 1); | |
1723 inc(result); | |
1724 } | |
1671 | 1725 |
1672 void MacroAssembler::AllocateHeapNumber(Register result, | 1726 void MacroAssembler::AllocateHeapNumber(Register result, |
1673 Register scratch1, | 1727 Register scratch1, |
1674 Register scratch2, | 1728 Register scratch2, |
1675 Label* gc_required, | 1729 Label* gc_required, |
1676 MutableMode mode) { | 1730 MutableMode mode) { |
1677 // Allocate heap number in new space. | 1731 // Allocate heap number in new space. |
1678 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, | 1732 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, |
1679 NO_ALLOCATION_FLAGS); | 1733 NO_ALLOCATION_FLAGS); |
1680 | 1734 |
(...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3248 mov(eax, dividend); | 3302 mov(eax, dividend); |
3249 shr(eax, 31); | 3303 shr(eax, 31); |
3250 add(edx, eax); | 3304 add(edx, eax); |
3251 } | 3305 } |
3252 | 3306 |
3253 | 3307 |
3254 } // namespace internal | 3308 } // namespace internal |
3255 } // namespace v8 | 3309 } // namespace v8 |
3256 | 3310 |
3257 #endif // V8_TARGET_ARCH_X87 | 3311 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |