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