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

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

Issue 2775503006: [builtins] Improve performance of array.prototype.filter and map (Closed)
Patch Set: Comment response. Created 3 years, 8 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
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 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
7 #include "src/frames.h" 7 #include "src/frames.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( 1516 Node* CodeStubAssembler::StoreFixedDoubleArrayElement(
1517 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { 1517 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) {
1518 CSA_ASSERT(this, IsFixedDoubleArray(object)); 1518 CSA_ASSERT(this, IsFixedDoubleArray(object));
1519 Node* offset = 1519 Node* offset =
1520 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, 1520 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode,
1521 FixedArray::kHeaderSize - kHeapObjectTag); 1521 FixedArray::kHeaderSize - kHeapObjectTag);
1522 MachineRepresentation rep = MachineRepresentation::kFloat64; 1522 MachineRepresentation rep = MachineRepresentation::kFloat64;
1523 return StoreNoWriteBarrier(rep, object, offset, value); 1523 return StoreNoWriteBarrier(rep, object, offset, value);
1524 } 1524 }
1525 1525
1526 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, 1526 Node* CodeStubAssembler::EnsureArrayPushable(Node* receiver, Label* bailout) {
1527 Node* array, 1527 // Disallow pushing onto prototypes. It might be the JSArray prototype.
1528 // Disallow pushing onto non-extensible objects.
1529 Comment("Disallow pushing onto prototypes");
1530 Node* map = LoadMap(receiver);
1531 Node* bit_field2 = LoadMapBitField2(map);
1532 int mask = static_cast<int>(Map::IsPrototypeMapBits::kMask) |
1533 (1 << Map::kIsExtensible);
1534 Node* test = Word32And(bit_field2, Int32Constant(mask));
1535 GotoIf(Word32NotEqual(test, Int32Constant(1 << Map::kIsExtensible)), bailout);
1536
1537 // Disallow pushing onto arrays in dictionary named property mode. We need
1538 // to figure out whether the length property is still writable.
1539 Comment("Disallow pushing onto arrays in dictionary named property mode");
1540 GotoIf(IsDictionaryMap(map), bailout);
1541
1542 // Check whether the length property is writable. The length property is the
1543 // only default named property on arrays. It's nonconfigurable, hence is
1544 // guaranteed to stay the first property.
1545 Node* descriptors = LoadMapDescriptors(map);
1546 Node* details =
1547 LoadFixedArrayElement(descriptors, DescriptorArray::ToDetailsIndex(0));
1548 GotoIf(IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask), bailout);
1549
1550 Node* kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
1551 return kind;
1552 }
1553
1554 void CodeStubAssembler::PossiblyGrowElementsCapacity(
1555 ParameterMode mode, ElementsKind kind, Node* array, Node* length,
1556 Variable* var_elements, Node* growth, Label* bailout) {
1557 Label fits(this, var_elements);
1558 Node* capacity =
1559 TaggedToParameter(LoadFixedArrayBaseLength(var_elements->value()), mode);
1560 // length and growth nodes are already in a ParameterMode appropriate
1561 // representation.
1562 Node* new_length = IntPtrOrSmiAdd(growth, length, mode);
1563 GotoIfNot(IntPtrOrSmiGreaterThan(new_length, capacity, mode), &fits);
1564 Node* new_capacity = CalculateNewElementsCapacity(new_length, mode);
1565 var_elements->Bind(GrowElementsCapacity(array, var_elements->value(), kind,
1566 kind, capacity, new_capacity, mode,
1567 bailout));
1568 Goto(&fits);
1569 BIND(&fits);
1570 }
1571
1572 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
1528 CodeStubArguments& args, 1573 CodeStubArguments& args,
1529 Variable& arg_index, 1574 Variable& arg_index,
1530 Label* bailout) { 1575 Label* bailout) {
1531 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); 1576 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
1532 Label pre_bailout(this); 1577 Label pre_bailout(this);
1533 Label success(this); 1578 Label success(this);
1534 VARIABLE(var_tagged_length, MachineRepresentation::kTagged); 1579 VARIABLE(var_tagged_length, MachineRepresentation::kTagged);
1535 ParameterMode mode = OptimalParameterMode(); 1580 ParameterMode mode = OptimalParameterMode();
1536 VARIABLE(var_length, OptimalParameterRepresentation(), 1581 VARIABLE(var_length, OptimalParameterRepresentation(),
1537 TaggedToParameter(LoadJSArrayLength(array), mode)); 1582 TaggedToParameter(LoadJSArrayLength(array), mode));
1538 VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array)); 1583 VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array));
1539 Node* capacity =
1540 TaggedToParameter(LoadFixedArrayBaseLength(var_elements.value()), mode);
1541 1584
1542 // Resize the capacity of the fixed array if it doesn't fit. 1585 // Resize the capacity of the fixed array if it doesn't fit.
1543 Label fits(this, &var_elements);
1544 Node* first = arg_index.value(); 1586 Node* first = arg_index.value();
1545 Node* growth = IntPtrSub(args.GetLength(), first); 1587 Node* growth = WordToParameter(IntPtrSub(args.GetLength(), first), mode);
1546 Node* new_length = 1588 PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(),
1547 IntPtrOrSmiAdd(WordToParameter(growth, mode), var_length.value(), mode); 1589 &var_elements, growth, &pre_bailout);
1548 GotoIfNot(IntPtrOrSmiGreaterThan(new_length, capacity, mode), &fits);
1549 Node* new_capacity = CalculateNewElementsCapacity(new_length, mode);
1550 var_elements.Bind(GrowElementsCapacity(array, var_elements.value(), kind,
1551 kind, capacity, new_capacity, mode,
1552 &pre_bailout));
1553 Goto(&fits);
1554 BIND(&fits);
1555 Node* elements = var_elements.value();
1556 1590
1557 // Push each argument onto the end of the array now that there is enough 1591 // Push each argument onto the end of the array now that there is enough
1558 // capacity. 1592 // capacity.
1559 CodeStubAssembler::VariableList push_vars({&var_length}, zone()); 1593 CodeStubAssembler::VariableList push_vars({&var_length}, zone());
1594 Node* elements = var_elements.value();
1560 args.ForEach( 1595 args.ForEach(
1561 push_vars, 1596 push_vars,
1562 [this, kind, mode, elements, &var_length, &pre_bailout](Node* arg) { 1597 [this, kind, mode, elements, &var_length, &pre_bailout](Node* arg) {
1563 if (IsFastSmiElementsKind(kind)) { 1598 TryStoreArrayElement(kind, mode, &pre_bailout, elements,
1564 GotoIf(TaggedIsNotSmi(arg), &pre_bailout); 1599 var_length.value(), arg);
1565 } else if (IsFastDoubleElementsKind(kind)) {
1566 GotoIfNotNumber(arg, &pre_bailout);
1567 }
1568 if (IsFastDoubleElementsKind(kind)) {
1569 Node* double_value = ChangeNumberToFloat64(arg);
1570 StoreFixedDoubleArrayElement(elements, var_length.value(),
1571 Float64SilenceNaN(double_value), mode);
1572 } else {
1573 WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind)
1574 ? SKIP_WRITE_BARRIER
1575 : UPDATE_WRITE_BARRIER;
1576 StoreFixedArrayElement(elements, var_length.value(), arg,
1577 barrier_mode, 0, mode);
1578 }
1579 Increment(var_length, 1, mode); 1600 Increment(var_length, 1, mode);
1580 }, 1601 },
1581 first, nullptr); 1602 first, nullptr);
1582 { 1603 {
1583 Node* length = ParameterToTagged(var_length.value(), mode); 1604 Node* length = ParameterToTagged(var_length.value(), mode);
1584 var_tagged_length.Bind(length); 1605 var_tagged_length.Bind(length);
1585 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); 1606 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
1586 Goto(&success); 1607 Goto(&success);
1587 } 1608 }
1588 1609
1589 BIND(&pre_bailout); 1610 BIND(&pre_bailout);
1590 { 1611 {
1591 Node* length = ParameterToTagged(var_length.value(), mode); 1612 Node* length = ParameterToTagged(var_length.value(), mode);
1592 var_tagged_length.Bind(length); 1613 var_tagged_length.Bind(length);
1593 Node* diff = SmiSub(length, LoadJSArrayLength(array)); 1614 Node* diff = SmiSub(length, LoadJSArrayLength(array));
1594 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); 1615 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
1595 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff))); 1616 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff)));
1596 Goto(bailout); 1617 Goto(bailout);
1597 } 1618 }
1598 1619
1599 BIND(&success); 1620 BIND(&success);
1600 return var_tagged_length.value(); 1621 return var_tagged_length.value();
1601 } 1622 }
1602 1623
1624 void CodeStubAssembler::TryStoreArrayElement(ElementsKind kind,
1625 ParameterMode mode, Label* bailout,
1626 Node* elements, Node* index,
1627 Node* value) {
1628 if (IsFastSmiElementsKind(kind)) {
1629 GotoIf(TaggedIsNotSmi(value), bailout);
1630 } else if (IsFastDoubleElementsKind(kind)) {
1631 GotoIfNotNumber(value, bailout);
1632 }
1633 if (IsFastDoubleElementsKind(kind)) {
1634 Node* double_value = ChangeNumberToFloat64(value);
1635 StoreFixedDoubleArrayElement(elements, index,
1636 Float64SilenceNaN(double_value), mode);
1637 } else {
1638 WriteBarrierMode barrier_mode =
1639 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
1640 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode);
1641 }
1642 }
1643
1644 void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
1645 Node* value, Label* bailout) {
1646 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
1647 ParameterMode mode = OptimalParameterMode();
1648 VARIABLE(var_length, OptimalParameterRepresentation(),
1649 TaggedToParameter(LoadJSArrayLength(array), mode));
1650 VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array));
1651
1652 // Resize the capacity of the fixed array if it doesn't fit.
1653 Node* growth = IntPtrOrSmiConstant(1, mode);
1654 PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(),
1655 &var_elements, growth, bailout);
1656
1657 // Push each argument onto the end of the array now that there is enough
1658 // capacity.
1659 TryStoreArrayElement(kind, mode, bailout, var_elements.value(),
1660 var_length.value(), value);
1661 Increment(var_length, 1, mode);
1662
1663 Node* length = ParameterToTagged(var_length.value(), mode);
1664 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
1665 }
1666
1603 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { 1667 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) {
1604 Node* result = Allocate(HeapNumber::kSize, kNone); 1668 Node* result = Allocate(HeapNumber::kSize, kNone);
1605 Heap::RootListIndex heap_map_index = 1669 Heap::RootListIndex heap_map_index =
1606 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex 1670 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex
1607 : Heap::kMutableHeapNumberMapRootIndex; 1671 : Heap::kMutableHeapNumberMapRootIndex;
1608 StoreMapNoWriteBarrier(result, heap_map_index); 1672 StoreMapNoWriteBarrier(result, heap_map_index);
1609 return result; 1673 return result;
1610 } 1674 }
1611 1675
1612 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value, 1676 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value,
(...skipping 6864 matching lines...) Expand 10 before | Expand all | Expand 10 after
8477 8541
8478 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); 8542 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1));
8479 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); 8543 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1));
8480 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); 8544 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1));
8481 8545
8482 // Check prototype chain if receiver does not have packed elements. 8546 // Check prototype chain if receiver does not have packed elements.
8483 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); 8547 Node* holey_elements = Word32And(elements_kind, Int32Constant(1));
8484 return Word32Equal(holey_elements, Int32Constant(1)); 8548 return Word32Equal(holey_elements, Int32Constant(1));
8485 } 8549 }
8486 8550
8551 Node* CodeStubAssembler::IsElementsKindGreaterThan(
8552 Node* target_kind, ElementsKind reference_kind) {
8553 return Int32GreaterThan(target_kind, Int32Constant(reference_kind));
8554 }
8555
8487 Node* CodeStubAssembler::IsDebugActive() { 8556 Node* CodeStubAssembler::IsDebugActive() {
8488 Node* is_debug_active = Load( 8557 Node* is_debug_active = Load(
8489 MachineType::Uint8(), 8558 MachineType::Uint8(),
8490 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); 8559 ExternalConstant(ExternalReference::debug_is_active_address(isolate())));
8491 return Word32NotEqual(is_debug_active, Int32Constant(0)); 8560 return Word32NotEqual(is_debug_active, Int32Constant(0));
8492 } 8561 }
8493 8562
8494 Node* CodeStubAssembler::IsPromiseHookEnabledOrDebugIsActive() { 8563 Node* CodeStubAssembler::IsPromiseHookEnabledOrDebugIsActive() {
8495 Node* const promise_hook_or_debug_is_active = 8564 Node* const promise_hook_or_debug_is_active =
8496 Load(MachineType::Uint8(), 8565 Load(MachineType::Uint8(),
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
8582 formatted.c_str(), TENURED); 8651 formatted.c_str(), TENURED);
8583 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), 8652 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(),
8584 HeapConstant(string)); 8653 HeapConstant(string));
8585 } 8654 }
8586 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); 8655 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value);
8587 #endif 8656 #endif
8588 } 8657 }
8589 8658
8590 } // namespace internal 8659 } // namespace internal
8591 } // namespace v8 8660 } // namespace v8
OLDNEW
« src/code-stub-assembler.h ('K') | « src/code-stub-assembler.h ('k') | src/js/array.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698