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