OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include <assert.h> // For assert | 5 #include <assert.h> // For assert |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_PPC | 8 #if V8_TARGET_ARCH_PPC |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1503 StoreP(scratch2, MemOperand(topaddr)); | 1503 StoreP(scratch2, MemOperand(topaddr)); |
1504 | 1504 |
1505 // Tag object if requested. | 1505 // Tag object if requested. |
1506 if ((flags & TAG_OBJECT) != 0) { | 1506 if ((flags & TAG_OBJECT) != 0) { |
1507 addi(result, result, Operand(kHeapObjectTag)); | 1507 addi(result, result, Operand(kHeapObjectTag)); |
1508 } | 1508 } |
1509 } | 1509 } |
1510 | 1510 |
1511 | 1511 |
1512 void MacroAssembler::Allocate(Register object_size, Register result, | 1512 void MacroAssembler::Allocate(Register object_size, Register result, |
1513 Register scratch1, Register scratch2, | 1513 Register result_end, Register scratch, |
1514 Label* gc_required, AllocationFlags flags) { | 1514 Label* gc_required, AllocationFlags flags) { |
1515 if (!FLAG_inline_new) { | 1515 if (!FLAG_inline_new) { |
1516 if (emit_debug_code()) { | 1516 if (emit_debug_code()) { |
1517 // Trash the registers to simulate an allocation failure. | 1517 // Trash the registers to simulate an allocation failure. |
1518 li(result, Operand(0x7091)); | 1518 li(result, Operand(0x7091)); |
1519 li(scratch1, Operand(0x7191)); | 1519 li(scratch, Operand(0x7191)); |
1520 li(scratch2, Operand(0x7291)); | 1520 li(result_end, Operand(0x7291)); |
1521 } | 1521 } |
1522 b(gc_required); | 1522 b(gc_required); |
1523 return; | 1523 return; |
1524 } | 1524 } |
1525 | 1525 |
1526 // Assert that the register arguments are different and that none of | 1526 // Assert that the register arguments are different and that none of |
1527 // them are ip. ip is used explicitly in the code generated below. | 1527 // them are ip. ip is used explicitly in the code generated below. |
1528 DCHECK(!result.is(scratch1)); | 1528 DCHECK(!result.is(scratch)); |
1529 DCHECK(!result.is(scratch2)); | 1529 DCHECK(!result.is(result_end)); |
1530 DCHECK(!scratch1.is(scratch2)); | 1530 DCHECK(!scratch.is(result_end)); |
1531 DCHECK(!object_size.is(ip)); | 1531 DCHECK(!object_size.is(ip)); |
1532 DCHECK(!result.is(ip)); | 1532 DCHECK(!result.is(ip)); |
1533 DCHECK(!scratch1.is(ip)); | 1533 DCHECK(!scratch.is(ip)); |
1534 DCHECK(!scratch2.is(ip)); | 1534 DCHECK(!result_end.is(ip)); |
1535 | 1535 |
1536 // Check relative positions of allocation top and limit addresses. | 1536 // Check relative positions of allocation top and limit addresses. |
1537 ExternalReference allocation_top = | 1537 ExternalReference allocation_top = |
1538 AllocationUtils::GetAllocationTopReference(isolate(), flags); | 1538 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
1539 ExternalReference allocation_limit = | 1539 ExternalReference allocation_limit = |
1540 AllocationUtils::GetAllocationLimitReference(isolate(), flags); | 1540 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
1541 intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address()); | 1541 intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address()); |
1542 intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address()); | 1542 intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address()); |
1543 DCHECK((limit - top) == kPointerSize); | 1543 DCHECK((limit - top) == kPointerSize); |
1544 | 1544 |
1545 // Set up allocation top address. | 1545 // Set up allocation top address. |
1546 Register topaddr = scratch1; | 1546 Register topaddr = scratch; |
1547 mov(topaddr, Operand(allocation_top)); | 1547 mov(topaddr, Operand(allocation_top)); |
1548 | 1548 |
1549 // This code stores a temporary value in ip. This is OK, as the code below | 1549 // This code stores a temporary value in ip. This is OK, as the code below |
1550 // does not need ip for implicit literal generation. | 1550 // does not need ip for implicit literal generation. |
1551 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 1551 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
1552 // Load allocation top into result and allocation limit into ip. | 1552 // Load allocation top into result and allocation limit into ip. |
1553 LoadP(result, MemOperand(topaddr)); | 1553 LoadP(result, MemOperand(topaddr)); |
1554 LoadP(ip, MemOperand(topaddr, kPointerSize)); | 1554 LoadP(ip, MemOperand(topaddr, kPointerSize)); |
1555 } else { | 1555 } else { |
1556 if (emit_debug_code()) { | 1556 if (emit_debug_code()) { |
1557 // Assert that result actually contains top on entry. ip is used | 1557 // Assert that result actually contains top on entry. ip is used |
1558 // immediately below so this use of ip does not cause difference with | 1558 // immediately below so this use of ip does not cause difference with |
1559 // respect to register content between debug and release mode. | 1559 // respect to register content between debug and release mode. |
1560 LoadP(ip, MemOperand(topaddr)); | 1560 LoadP(ip, MemOperand(topaddr)); |
1561 cmp(result, ip); | 1561 cmp(result, ip); |
1562 Check(eq, kUnexpectedAllocationTop); | 1562 Check(eq, kUnexpectedAllocationTop); |
1563 } | 1563 } |
1564 // Load allocation limit into ip. Result already contains allocation top. | 1564 // Load allocation limit into ip. Result already contains allocation top. |
1565 LoadP(ip, MemOperand(topaddr, limit - top)); | 1565 LoadP(ip, MemOperand(topaddr, limit - top)); |
1566 } | 1566 } |
1567 | 1567 |
1568 if ((flags & DOUBLE_ALIGNMENT) != 0) { | 1568 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
1569 // Align the next allocation. Storing the filler map without checking top is | 1569 // Align the next allocation. Storing the filler map without checking top is |
1570 // safe in new-space because the limit of the heap is aligned there. | 1570 // safe in new-space because the limit of the heap is aligned there. |
1571 #if V8_TARGET_ARCH_PPC64 | 1571 #if V8_TARGET_ARCH_PPC64 |
1572 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); | 1572 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); |
1573 #else | 1573 #else |
1574 STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment); | 1574 STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment); |
1575 andi(scratch2, result, Operand(kDoubleAlignmentMask)); | 1575 andi(result_end, result, Operand(kDoubleAlignmentMask)); |
1576 Label aligned; | 1576 Label aligned; |
1577 beq(&aligned, cr0); | 1577 beq(&aligned, cr0); |
1578 if ((flags & PRETENURE) != 0) { | 1578 if ((flags & PRETENURE) != 0) { |
1579 cmpl(result, ip); | 1579 cmpl(result, ip); |
1580 bge(gc_required); | 1580 bge(gc_required); |
1581 } | 1581 } |
1582 mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); | 1582 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); |
1583 stw(scratch2, MemOperand(result)); | 1583 stw(result_end, MemOperand(result)); |
1584 addi(result, result, Operand(kDoubleSize / 2)); | 1584 addi(result, result, Operand(kDoubleSize / 2)); |
1585 bind(&aligned); | 1585 bind(&aligned); |
1586 #endif | 1586 #endif |
1587 } | 1587 } |
1588 | 1588 |
1589 // Calculate new top and bail out if new space is exhausted. Use result | 1589 // Calculate new top and bail out if new space is exhausted. Use result |
1590 // to calculate the new top. Object size may be in words so a shift is | 1590 // to calculate the new top. Object size may be in words so a shift is |
1591 // required to get the number of bytes. | 1591 // required to get the number of bytes. |
1592 sub(r0, ip, result); | 1592 sub(r0, ip, result); |
1593 if ((flags & SIZE_IN_WORDS) != 0) { | 1593 if ((flags & SIZE_IN_WORDS) != 0) { |
1594 ShiftLeftImm(scratch2, object_size, Operand(kPointerSizeLog2)); | 1594 ShiftLeftImm(result_end, object_size, Operand(kPointerSizeLog2)); |
1595 cmp(r0, scratch2); | 1595 cmp(r0, result_end); |
1596 blt(gc_required); | 1596 blt(gc_required); |
1597 add(scratch2, result, scratch2); | 1597 add(result_end, result, result_end); |
1598 } else { | 1598 } else { |
1599 cmp(r0, object_size); | 1599 cmp(r0, object_size); |
1600 blt(gc_required); | 1600 blt(gc_required); |
1601 add(scratch2, result, object_size); | 1601 add(result_end, result, object_size); |
1602 } | 1602 } |
1603 | 1603 |
1604 // Update allocation top. result temporarily holds the new top. | 1604 // Update allocation top. result temporarily holds the new top. |
1605 if (emit_debug_code()) { | 1605 if (emit_debug_code()) { |
1606 andi(r0, scratch2, Operand(kObjectAlignmentMask)); | 1606 andi(r0, result_end, Operand(kObjectAlignmentMask)); |
1607 Check(eq, kUnalignedAllocationInNewSpace, cr0); | 1607 Check(eq, kUnalignedAllocationInNewSpace, cr0); |
1608 } | 1608 } |
1609 StoreP(scratch2, MemOperand(topaddr)); | 1609 StoreP(result_end, MemOperand(topaddr)); |
1610 | 1610 |
1611 // Tag object if requested. | 1611 // Tag object if requested. |
1612 if ((flags & TAG_OBJECT) != 0) { | 1612 if ((flags & TAG_OBJECT) != 0) { |
1613 addi(result, result, Operand(kHeapObjectTag)); | 1613 addi(result, result, Operand(kHeapObjectTag)); |
1614 } | 1614 } |
1615 } | 1615 } |
1616 | 1616 |
1617 | 1617 |
1618 void MacroAssembler::AllocateTwoByteString(Register result, Register length, | 1618 void MacroAssembler::AllocateTwoByteString(Register result, Register length, |
1619 Register scratch1, Register scratch2, | 1619 Register scratch1, Register scratch2, |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2864 lbz(scratch, MemOperand(src)); | 2864 lbz(scratch, MemOperand(src)); |
2865 addi(src, src, Operand(1)); | 2865 addi(src, src, Operand(1)); |
2866 stb(scratch, MemOperand(dst)); | 2866 stb(scratch, MemOperand(dst)); |
2867 addi(dst, dst, Operand(1)); | 2867 addi(dst, dst, Operand(1)); |
2868 bdnz(&byte_loop_1); | 2868 bdnz(&byte_loop_1); |
2869 | 2869 |
2870 bind(&done); | 2870 bind(&done); |
2871 } | 2871 } |
2872 | 2872 |
2873 | 2873 |
2874 void MacroAssembler::InitializeNFieldsWithFiller(Register start_offset, | 2874 void MacroAssembler::InitializeNFieldsWithFiller(Register current_address, |
2875 Register count, | 2875 Register count, |
2876 Register filler) { | 2876 Register filler) { |
2877 Label loop; | 2877 Label loop; |
2878 mtctr(count); | 2878 mtctr(count); |
2879 bind(&loop); | 2879 bind(&loop); |
2880 StoreP(filler, MemOperand(start_offset)); | 2880 StoreP(filler, MemOperand(current_address)); |
2881 addi(start_offset, start_offset, Operand(kPointerSize)); | 2881 addi(current_address, current_address, Operand(kPointerSize)); |
2882 bdnz(&loop); | 2882 bdnz(&loop); |
2883 } | 2883 } |
2884 | 2884 |
2885 void MacroAssembler::InitializeFieldsWithFiller(Register start_offset, | 2885 void MacroAssembler::InitializeFieldsWithFiller(Register current_address, |
2886 Register end_offset, | 2886 Register end_address, |
2887 Register filler) { | 2887 Register filler) { |
2888 Label done; | 2888 Label done; |
2889 sub(r0, end_offset, start_offset, LeaveOE, SetRC); | 2889 sub(r0, end_address, current_address, LeaveOE, SetRC); |
2890 beq(&done, cr0); | 2890 beq(&done, cr0); |
2891 ShiftRightImm(r0, r0, Operand(kPointerSizeLog2)); | 2891 ShiftRightImm(r0, r0, Operand(kPointerSizeLog2)); |
2892 InitializeNFieldsWithFiller(start_offset, r0, filler); | 2892 InitializeNFieldsWithFiller(current_address, r0, filler); |
Igor Sheludko
2015/11/23 07:57:34
Does it make sense to rewrite InitializeFieldsWith
| |
2893 bind(&done); | 2893 bind(&done); |
2894 } | 2894 } |
2895 | 2895 |
2896 | 2896 |
2897 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( | 2897 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
2898 Register first, Register second, Register scratch1, Register scratch2, | 2898 Register first, Register second, Register scratch1, Register scratch2, |
2899 Label* failure) { | 2899 Label* failure) { |
2900 const int kFlatOneByteStringMask = | 2900 const int kFlatOneByteStringMask = |
2901 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 2901 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
2902 const int kFlatOneByteStringTag = | 2902 const int kFlatOneByteStringTag = |
(...skipping 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4412 } | 4412 } |
4413 if (mag.shift > 0) srawi(result, result, mag.shift); | 4413 if (mag.shift > 0) srawi(result, result, mag.shift); |
4414 ExtractBit(r0, dividend, 31); | 4414 ExtractBit(r0, dividend, 31); |
4415 add(result, result, r0); | 4415 add(result, result, r0); |
4416 } | 4416 } |
4417 | 4417 |
4418 } // namespace internal | 4418 } // namespace internal |
4419 } // namespace v8 | 4419 } // namespace v8 |
4420 | 4420 |
4421 #endif // V8_TARGET_ARCH_PPC | 4421 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |