Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/code-stub-assembler.cc

Issue 2321993002: [stubs] CSA::CopyFixedArrayElements() is now able to convert elements' kind while copying. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 StoreNoWriteBarrier(MachineType::PointerRepresentation(), current.value(), 1505 StoreNoWriteBarrier(MachineType::PointerRepresentation(), current.value(),
1506 IntPtrConstant(first_element_offset), value); 1506 IntPtrConstant(first_element_offset), value);
1507 } 1507 }
1508 Node* compare = WordNotEqual(current.value(), limit); 1508 Node* compare = WordNotEqual(current.value(), limit);
1509 Branch(compare, &decrement, &done); 1509 Branch(compare, &decrement, &done);
1510 1510
1511 Bind(&done); 1511 Bind(&done);
1512 } 1512 }
1513 } 1513 }
1514 1514
1515 void CodeStubAssembler::CopyFixedArrayElements(ElementsKind kind, 1515 void CodeStubAssembler::CopyFixedArrayElements(
1516 compiler::Node* from_array, 1516 ElementsKind from_kind, Node* from_array, ElementsKind to_kind,
1517 compiler::Node* to_array, 1517 Node* to_array, Node* element_count, Node* capacity,
1518 compiler::Node* element_count, 1518 WriteBarrierMode barrier_mode, ParameterMode mode) {
1519 WriteBarrierMode barrier_mode, 1519 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
1520 ParameterMode mode) { 1520 const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag;
1521 Label test(this); 1521 Comment("[ CopyFixedArrayElements");
1522
1523 // Typed array elements are not supported.
1524 DCHECK(!IsFixedTypedArrayElementsKind(from_kind));
1525 DCHECK(!IsFixedTypedArrayElementsKind(to_kind));
1526
1522 Label done(this); 1527 Label done(this);
1523 bool double_elements = IsFastDoubleElementsKind(kind); 1528 bool from_double_elements = IsFastDoubleElementsKind(from_kind);
1529 bool to_double_elements = IsFastDoubleElementsKind(to_kind);
1530 bool element_size_matches =
1531 Is64() ||
1532 IsFastDoubleElementsKind(from_kind) == IsFastDoubleElementsKind(to_kind);
1533 bool doubles_to_objects_conversion =
1534 IsFastDoubleElementsKind(from_kind) && IsFastObjectElementsKind(to_kind);
1524 bool needs_write_barrier = 1535 bool needs_write_barrier =
1525 barrier_mode == UPDATE_WRITE_BARRIER && !IsFastObjectElementsKind(kind); 1536 doubles_to_objects_conversion || (barrier_mode == UPDATE_WRITE_BARRIER &&
1526 Node* limit_offset = 1537 IsFastObjectElementsKind(to_kind));
1527 ElementOffsetFromIndex(IntPtrOrSmiConstant(0, mode), kind, mode, 1538 Node* double_hole =
1528 FixedArray::kHeaderSize - kHeapObjectTag); 1539 Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32);
1529 Variable current_offset(this, MachineType::PointerRepresentation());
1530 current_offset.Bind(ElementOffsetFromIndex(
1531 element_count, kind, mode, FixedArray::kHeaderSize - kHeapObjectTag));
1532 Label decrement(this, &current_offset);
1533 1540
1534 Branch(WordEqual(current_offset.value(), limit_offset), &done, &decrement); 1541 if (doubles_to_objects_conversion) {
1542 // If the copy might trigger a GC, make sure that the FixedArray is
1543 // pre-initialized with holes to make sure that it's always in a
1544 // consistent state.
1545 FillFixedArrayWithValue(to_kind, to_array, IntPtrOrSmiConstant(0, mode),
1546 capacity, Heap::kTheHoleValueRootIndex, mode);
1547 } else if (element_count != capacity) {
1548 FillFixedArrayWithValue(to_kind, to_array, element_count, capacity,
1549 Heap::kTheHoleValueRootIndex, mode);
1550 }
1551
1552 Node* limit_offset = ElementOffsetFromIndex(
1553 IntPtrOrSmiConstant(0, mode), from_kind, mode, first_element_offset);
1554 Variable var_from_offset(this, MachineType::PointerRepresentation());
1555 var_from_offset.Bind(ElementOffsetFromIndex(element_count, from_kind, mode,
1556 first_element_offset));
1557 // This second variable is used only when the element sizes of source and
1558 // destination arrays do not match.
1559 Variable var_to_offset(this, MachineType::PointerRepresentation());
1560 if (element_size_matches) {
1561 var_to_offset.Bind(var_from_offset.value());
1562 } else {
1563 var_to_offset.Bind(ElementOffsetFromIndex(element_count, to_kind, mode,
1564 first_element_offset));
1565 }
1566
1567 Variable* vars[] = {&var_from_offset, &var_to_offset};
1568 Label decrement(this, 2, vars);
1569
1570 Branch(WordEqual(var_from_offset.value(), limit_offset), &done, &decrement);
1535 1571
1536 Bind(&decrement); 1572 Bind(&decrement);
1537 { 1573 {
1538 current_offset.Bind(IntPtrSub( 1574 Node* from_offset = IntPtrSub(
1539 current_offset.value(), 1575 var_from_offset.value(),
1540 IntPtrConstant(double_elements ? kDoubleSize : kPointerSize))); 1576 IntPtrConstant(from_double_elements ? kDoubleSize : kPointerSize));
1577 var_from_offset.Bind(from_offset);
1541 1578
1542 Node* value = 1579 Node* to_offset;
1543 Load(double_elements ? MachineType::Float64() : MachineType::Pointer(), 1580 if (element_size_matches) {
1544 from_array, current_offset.value()); 1581 to_offset = from_offset;
1582 } else {
1583 to_offset = IntPtrSub(
1584 var_to_offset.value(),
1585 IntPtrConstant(to_double_elements ? kDoubleSize : kPointerSize));
1586 var_to_offset.Bind(to_offset);
1587 }
1588
1589 Label next_iter(this), store_double_hole(this);
1590 Label* if_hole;
1591 if (doubles_to_objects_conversion) {
1592 // The target elements array is already preinitialized with holes, so we
1593 // can just proceed with the next iteration.
1594 if_hole = &next_iter;
1595 } else if (IsFastDoubleElementsKind(to_kind)) {
1596 if_hole = &store_double_hole;
1597 } else {
1598 // In all the other cases don't check for holes and copy the data as is.
1599 if_hole = nullptr;
1600 }
1601
1602 Node* value = LoadElementAndPrepareForStore(
1603 from_array, var_from_offset.value(), from_kind, to_kind, if_hole);
1604
1545 if (needs_write_barrier) { 1605 if (needs_write_barrier) {
1546 Store(MachineType::PointerRepresentation(), to_array, 1606 Store(MachineRepresentation::kTagged, to_array, to_offset, value);
1547 current_offset.value(), value); 1607 } else if (to_double_elements) {
1548 } else if (double_elements) { 1608 StoreNoWriteBarrier(MachineRepresentation::kFloat64, to_array, to_offset,
1549 StoreNoWriteBarrier(MachineRepresentation::kFloat64, to_array, 1609 value);
1550 current_offset.value(), value);
1551 } else { 1610 } else {
1552 StoreNoWriteBarrier(MachineType::PointerRepresentation(), to_array, 1611 StoreNoWriteBarrier(MachineType::PointerRepresentation(), to_array,
1553 current_offset.value(), value); 1612 to_offset, value);
1554 } 1613 }
1555 Node* compare = WordNotEqual(current_offset.value(), limit_offset); 1614 Goto(&next_iter);
1615
1616 if (if_hole == &store_double_hole) {
1617 Bind(&store_double_hole);
1618 // Don't use doubles to store the hole double, since manipulating the
1619 // signaling NaN used for the hole in C++, e.g. with bit_cast, will
1620 // change its value on ia32 (the x87 stack is used to return values
1621 // and stores to the stack silently clear the signalling bit).
1622 //
1623 // TODO(danno): When we have a Float32/Float64 wrapper class that
1624 // preserves double bits during manipulation, remove this code/change
1625 // this to an indexed Float64 store.
1626 if (Is64()) {
1627 StoreNoWriteBarrier(MachineRepresentation::kWord64, to_array, to_offset,
1628 double_hole);
1629 } else {
1630 StoreNoWriteBarrier(MachineRepresentation::kWord32, to_array, to_offset,
1631 double_hole);
1632 StoreNoWriteBarrier(MachineRepresentation::kWord32, to_array,
1633 IntPtrAdd(to_offset, IntPtrConstant(kPointerSize)),
1634 double_hole);
1635 }
1636 Goto(&next_iter);
1637 }
1638
1639 Bind(&next_iter);
1640 Node* compare = WordNotEqual(from_offset, limit_offset);
1556 Branch(compare, &decrement, &done); 1641 Branch(compare, &decrement, &done);
1557 } 1642 }
1558 1643
1559 Bind(&done); 1644 Bind(&done);
1645 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1);
1646 Comment("] CopyFixedArrayElements");
1647 }
1648
1649 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array,
1650 Node* offset,
1651 ElementsKind from_kind,
1652 ElementsKind to_kind,
1653 Label* if_hole) {
1654 if (IsFastDoubleElementsKind(from_kind)) {
1655 Node* value =
1656 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64());
1657 if (!IsFastDoubleElementsKind(to_kind)) {
1658 value = AllocateHeapNumberWithValue(value);
1659 }
1660 return value;
1661
1662 } else {
1663 Node* value = Load(MachineType::Pointer(), array, offset);
1664 if (if_hole) {
1665 GotoIf(WordEqual(value, TheHoleConstant()), if_hole);
1666 }
1667 if (IsFastDoubleElementsKind(to_kind)) {
1668 if (IsFastSmiElementsKind(from_kind)) {
1669 value = SmiToFloat64(value);
1670 } else {
1671 value = LoadHeapNumberValue(value);
1672 }
1673 }
1674 return value;
1675 }
1560 } 1676 }
1561 1677
1562 Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity, 1678 Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity,
1563 ParameterMode mode) { 1679 ParameterMode mode) {
1564 Node* half_old_capacity = WordShr(old_capacity, IntPtrConstant(1)); 1680 Node* half_old_capacity = WordShr(old_capacity, IntPtrConstant(1));
1565 Node* new_capacity = IntPtrAdd(half_old_capacity, old_capacity); 1681 Node* new_capacity = IntPtrAdd(half_old_capacity, old_capacity);
1566 Node* unconditioned_result = 1682 Node* unconditioned_result =
1567 IntPtrAdd(new_capacity, IntPtrOrSmiConstant(16, mode)); 1683 IntPtrAdd(new_capacity, IntPtrOrSmiConstant(16, mode));
1568 if (mode == INTEGER_PARAMETERS || mode == INTPTR_PARAMETERS) { 1684 if (mode == INTEGER_PARAMETERS || mode == INTPTR_PARAMETERS) {
1569 return unconditioned_result; 1685 return unconditioned_result;
(...skipping 2635 matching lines...) Expand 10 before | Expand all | Expand 10 after
4205 Heap::kTheHoleValueRootIndex); 4321 Heap::kTheHoleValueRootIndex);
4206 4322
4207 // Store the WeakCell in the feedback vector. 4323 // Store the WeakCell in the feedback vector.
4208 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 4324 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
4209 CodeStubAssembler::SMI_PARAMETERS); 4325 CodeStubAssembler::SMI_PARAMETERS);
4210 return cell; 4326 return cell;
4211 } 4327 }
4212 4328
4213 } // namespace internal 4329 } // namespace internal
4214 } // namespace v8 4330 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698