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

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

Issue 2775503006: [builtins] Improve performance of array.prototype.filter and map (Closed)
Patch Set: Code comments 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/js/array.js » ('j') | 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 #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 6865 matching lines...) Expand 10 before | Expand all | Expand 10 after
8478 8542
8479 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); 8543 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1));
8480 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); 8544 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1));
8481 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); 8545 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1));
8482 8546
8483 // Check prototype chain if receiver does not have packed elements. 8547 // Check prototype chain if receiver does not have packed elements.
8484 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); 8548 Node* holey_elements = Word32And(elements_kind, Int32Constant(1));
8485 return Word32Equal(holey_elements, Int32Constant(1)); 8549 return Word32Equal(holey_elements, Int32Constant(1));
8486 } 8550 }
8487 8551
8552 Node* CodeStubAssembler::IsElementsKindGreaterThan(
8553 Node* target_kind, ElementsKind reference_kind) {
8554 return Int32GreaterThan(target_kind, Int32Constant(reference_kind));
8555 }
8556
8488 Node* CodeStubAssembler::IsDebugActive() { 8557 Node* CodeStubAssembler::IsDebugActive() {
8489 Node* is_debug_active = Load( 8558 Node* is_debug_active = Load(
8490 MachineType::Uint8(), 8559 MachineType::Uint8(),
8491 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); 8560 ExternalConstant(ExternalReference::debug_is_active_address(isolate())));
8492 return Word32NotEqual(is_debug_active, Int32Constant(0)); 8561 return Word32NotEqual(is_debug_active, Int32Constant(0));
8493 } 8562 }
8494 8563
8495 Node* CodeStubAssembler::IsPromiseHookEnabledOrDebugIsActive() { 8564 Node* CodeStubAssembler::IsPromiseHookEnabledOrDebugIsActive() {
8496 Node* const promise_hook_or_debug_is_active = 8565 Node* const promise_hook_or_debug_is_active =
8497 Load(MachineType::Uint8(), 8566 Load(MachineType::Uint8(),
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
8583 formatted.c_str(), TENURED); 8652 formatted.c_str(), TENURED);
8584 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), 8653 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(),
8585 HeapConstant(string)); 8654 HeapConstant(string));
8586 } 8655 }
8587 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); 8656 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value);
8588 #endif 8657 #endif
8589 } 8658 }
8590 8659
8591 } // namespace internal 8660 } // namespace internal
8592 } // namespace v8 8661 } // namespace v8
OLDNEW
« no previous file with comments | « 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