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

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

Issue 2775503006: [builtins] Improve performance of array.prototype.filter and map (Closed)
Patch Set: fixes 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 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( 1471 Node* CodeStubAssembler::StoreFixedDoubleArrayElement(
1472 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { 1472 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) {
1473 CSA_ASSERT(this, IsFixedDoubleArray(object)); 1473 CSA_ASSERT(this, IsFixedDoubleArray(object));
1474 Node* offset = 1474 Node* offset =
1475 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, 1475 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode,
1476 FixedArray::kHeaderSize - kHeapObjectTag); 1476 FixedArray::kHeaderSize - kHeapObjectTag);
1477 MachineRepresentation rep = MachineRepresentation::kFloat64; 1477 MachineRepresentation rep = MachineRepresentation::kFloat64;
1478 return StoreNoWriteBarrier(rep, object, offset, value); 1478 return StoreNoWriteBarrier(rep, object, offset, value);
1479 } 1479 }
1480 1480
1481 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, 1481 Node* CodeStubAssembler::EnsureArrayPushable(Node* receiver, Label* bailout) {
1482 Node* array, 1482 // Disallow pushing onto prototypes. It might be the JSArray prototype.
1483 // Disallow pushing onto non-extensible objects.
1484 Comment("Disallow pushing onto prototypes");
1485 Node* map = LoadMap(receiver);
1486 Node* bit_field2 = LoadMapBitField2(map);
1487 int mask = static_cast<int>(Map::IsPrototypeMapBits::kMask) |
1488 (1 << Map::kIsExtensible);
1489 Node* test = Word32And(bit_field2, Int32Constant(mask));
1490 GotoIf(Word32NotEqual(test, Int32Constant(1 << Map::kIsExtensible)), bailout);
1491
1492 // Disallow pushing onto arrays in dictionary named property mode. We need
1493 // to figure out whether the length property is still writable.
1494 Comment("Disallow pushing onto arrays in dictionary named property mode");
1495 GotoIf(IsDictionaryMap(map), bailout);
1496
1497 // Check whether the length property is writable. The length property is the
1498 // only default named property on arrays. It's nonconfigurable, hence is
1499 // guaranteed to stay the first property.
1500 Node* descriptors = LoadMapDescriptors(map);
1501 Node* details =
1502 LoadFixedArrayElement(descriptors, DescriptorArray::ToDetailsIndex(0));
1503 GotoIf(IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask), bailout);
1504
1505 Node* kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
1506 return kind;
1507 }
1508
1509 Node* CodeStubAssembler::PossiblyGrowElementsCapacity(
1510 ParameterMode mode, ElementsKind kind, Node* array, Node* length,
1511 Node* elements, Node* growth, Label* fits, Label* bailout) {
1512 Node* capacity = TaggedToParameter(LoadFixedArrayBaseLength(elements), mode);
1513 Node* new_length =
1514 IntPtrOrSmiAdd(WordToParameter(growth, mode), length, mode);
1515 GotoIfNot(IntPtrOrSmiGreaterThan(new_length, capacity, mode), fits);
1516 Node* new_capacity = CalculateNewElementsCapacity(new_length, mode);
1517 return GrowElementsCapacity(array, elements, kind, kind, capacity,
1518 new_capacity, mode, bailout);
1519 }
1520
1521 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
1483 CodeStubArguments& args, 1522 CodeStubArguments& args,
1484 Variable& arg_index, 1523 Variable& arg_index,
1485 Label* bailout) { 1524 Label* bailout) {
1486 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); 1525 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
1487 Label pre_bailout(this); 1526 Label pre_bailout(this);
1488 Label success(this); 1527 Label success(this);
1489 Variable var_tagged_length(this, MachineRepresentation::kTagged); 1528 Variable var_tagged_length(this, MachineRepresentation::kTagged);
1490 ParameterMode mode = OptimalParameterMode(); 1529 ParameterMode mode = OptimalParameterMode();
1491 Variable var_length(this, OptimalParameterRepresentation(), 1530 Variable var_length(this, OptimalParameterRepresentation(),
1492 TaggedToParameter(LoadJSArrayLength(array), mode)); 1531 TaggedToParameter(LoadJSArrayLength(array), mode));
1493 Variable var_elements(this, MachineRepresentation::kTagged, 1532 Variable var_elements(this, MachineRepresentation::kTagged,
1494 LoadElements(array)); 1533 LoadElements(array));
1495 Node* capacity =
1496 TaggedToParameter(LoadFixedArrayBaseLength(var_elements.value()), mode);
1497 1534
1498 // Resize the capacity of the fixed array if it doesn't fit. 1535 // Resize the capacity of the fixed array if it doesn't fit.
1499 Label fits(this, &var_elements); 1536 Label fits(this, &var_elements);
1500 Node* first = arg_index.value(); 1537 Node* first = arg_index.value();
1501 Node* growth = IntPtrSub(args.GetLength(), first); 1538 Node* growth = IntPtrSub(args.GetLength(), first);
1502 Node* new_length = 1539 var_elements.Bind(PossiblyGrowElementsCapacity(
1503 IntPtrOrSmiAdd(WordToParameter(growth, mode), var_length.value(), mode); 1540 mode, kind, array, var_length.value(), var_elements.value(), growth,
1504 GotoIfNot(IntPtrOrSmiGreaterThan(new_length, capacity, mode), &fits); 1541 &fits, &pre_bailout));
1505 Node* new_capacity = CalculateNewElementsCapacity(new_length, mode);
1506 var_elements.Bind(GrowElementsCapacity(array, var_elements.value(), kind,
1507 kind, capacity, new_capacity, mode,
1508 &pre_bailout));
1509 Goto(&fits); 1542 Goto(&fits);
1510 Bind(&fits); 1543 Bind(&fits);
1511 Node* elements = var_elements.value(); 1544 Node* elements = var_elements.value();
1512 1545
1513 // Push each argument onto the end of the array now that there is enough 1546 // Push each argument onto the end of the array now that there is enough
1514 // capacity. 1547 // capacity.
1515 CodeStubAssembler::VariableList push_vars({&var_length}, zone()); 1548 CodeStubAssembler::VariableList push_vars({&var_length}, zone());
1516 args.ForEach( 1549 args.ForEach(
1517 push_vars, 1550 push_vars,
1518 [this, kind, mode, elements, &var_length, &pre_bailout](Node* arg) { 1551 [this, kind, mode, elements, &var_length, &pre_bailout](Node* arg) {
1519 if (IsFastSmiElementsKind(kind)) { 1552 TryStoreArrayElement(kind, mode, &pre_bailout, elements,
1520 GotoIf(TaggedIsNotSmi(arg), &pre_bailout); 1553 var_length.value(), arg);
1521 } else if (IsFastDoubleElementsKind(kind)) {
1522 GotoIfNotNumber(arg, &pre_bailout);
1523 }
1524 if (IsFastDoubleElementsKind(kind)) {
1525 Node* double_value = ChangeNumberToFloat64(arg);
1526 StoreFixedDoubleArrayElement(elements, var_length.value(),
1527 Float64SilenceNaN(double_value), mode);
1528 } else {
1529 WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind)
1530 ? SKIP_WRITE_BARRIER
1531 : UPDATE_WRITE_BARRIER;
1532 StoreFixedArrayElement(elements, var_length.value(), arg,
1533 barrier_mode, 0, mode);
1534 }
1535 Increment(var_length, 1, mode); 1554 Increment(var_length, 1, mode);
1536 }, 1555 },
1537 first, nullptr); 1556 first, nullptr);
1538 { 1557 {
1539 Node* length = ParameterToTagged(var_length.value(), mode); 1558 Node* length = ParameterToTagged(var_length.value(), mode);
1540 var_tagged_length.Bind(length); 1559 var_tagged_length.Bind(length);
1541 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); 1560 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
1542 Goto(&success); 1561 Goto(&success);
1543 } 1562 }
1544 1563
1545 Bind(&pre_bailout); 1564 Bind(&pre_bailout);
1546 { 1565 {
1547 Node* length = ParameterToTagged(var_length.value(), mode); 1566 Node* length = ParameterToTagged(var_length.value(), mode);
1548 var_tagged_length.Bind(length); 1567 var_tagged_length.Bind(length);
1549 Node* diff = SmiSub(length, LoadJSArrayLength(array)); 1568 Node* diff = SmiSub(length, LoadJSArrayLength(array));
1550 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); 1569 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
1551 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff))); 1570 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff)));
1552 Goto(bailout); 1571 Goto(bailout);
1553 } 1572 }
1554 1573
1555 Bind(&success); 1574 Bind(&success);
1556 return var_tagged_length.value(); 1575 return var_tagged_length.value();
1557 } 1576 }
1558 1577
1578 void CodeStubAssembler::TryStoreArrayElement(ElementsKind kind,
1579 ParameterMode mode, Label* bailout,
1580 Node* elements, Node* index,
1581 Node* value) {
1582 if (IsFastSmiElementsKind(kind)) {
1583 GotoIf(TaggedIsNotSmi(value), bailout);
1584 } else if (IsFastDoubleElementsKind(kind)) {
1585 GotoIfNotNumber(value, bailout);
1586 }
1587 if (IsFastDoubleElementsKind(kind)) {
1588 Node* double_value = ChangeNumberToFloat64(value);
1589 StoreFixedDoubleArrayElement(elements, index,
1590 Float64SilenceNaN(double_value), mode);
1591 } else {
1592 WriteBarrierMode barrier_mode =
1593 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
1594 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode);
1595 }
1596 }
1597
1598 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
1599 Node* value, Label* bailout) {
1600 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
1601 Label success(this);
1602 Variable var_tagged_length(this, MachineRepresentation::kTagged);
jgruber 2017/04/19 10:25:28 Nit: VARIABLE(var_x, ...) instead of Variable var_
mvstanton 2017/04/23 09:00:09 Done.
1603 ParameterMode mode = OptimalParameterMode();
1604 Variable var_length(this, OptimalParameterRepresentation(),
1605 TaggedToParameter(LoadJSArrayLength(array), mode));
1606 Variable var_elements(this, MachineRepresentation::kTagged,
1607 LoadElements(array));
1608
1609 // Resize the capacity of the fixed array if it doesn't fit.
1610 Label fits(this, &var_elements);
1611 Node* growth = IntPtrOrSmiConstant(1, mode);
1612 var_elements.Bind(PossiblyGrowElementsCapacity(
1613 mode, kind, array, var_length.value(), var_elements.value(), growth,
1614 &fits, bailout));
1615 /*
1616 Node* new_length = IntPtrOrSmiAdd(growth, var_length.value(), mode);
jgruber 2017/04/19 10:25:28 Nit: Leftover code?
mvstanton 2017/04/23 09:00:09 Done.
1617 GotoIfNot(IntPtrOrSmiGreaterThan(new_length, capacity, mode), &fits);
1618 Node* new_capacity = CalculateNewElementsCapacity(new_length, mode);
1619 var_elements.Bind(GrowElementsCapacity(array, var_elements.value(), kind,
1620 kind, capacity, new_capacity, mode,
1621 bailout));
1622 */
1623 Goto(&fits);
1624 Bind(&fits);
1625 Node* elements = var_elements.value();
1626
1627 // Push each argument onto the end of the array now that there is enough
1628 // capacity.
1629 TryStoreArrayElement(kind, mode, bailout, elements, var_length.value(),
1630 value);
1631 Increment(var_length, 1, mode);
1632
1633 {
1634 Node* length = ParameterToTagged(var_length.value(), mode);
1635 var_tagged_length.Bind(length);
jgruber 2017/04/19 10:25:28 Nit: var_tagged_length and the success label aren'
mvstanton 2017/04/23 09:00:09 Good idea, thanks!
1636 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
1637 Goto(&success);
1638 }
1639
1640 Bind(&success);
1641 return var_tagged_length.value();
1642 }
1643
1559 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { 1644 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) {
1560 Node* result = Allocate(HeapNumber::kSize, kNone); 1645 Node* result = Allocate(HeapNumber::kSize, kNone);
1561 Heap::RootListIndex heap_map_index = 1646 Heap::RootListIndex heap_map_index =
1562 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex 1647 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex
1563 : Heap::kMutableHeapNumberMapRootIndex; 1648 : Heap::kMutableHeapNumberMapRootIndex;
1564 StoreMapNoWriteBarrier(result, heap_map_index); 1649 StoreMapNoWriteBarrier(result, heap_map_index);
1565 return result; 1650 return result;
1566 } 1651 }
1567 1652
1568 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value, 1653 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value,
(...skipping 6793 matching lines...) Expand 10 before | Expand all | Expand 10 after
8362 8447
8363 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); 8448 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1));
8364 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); 8449 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1));
8365 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); 8450 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1));
8366 8451
8367 // Check prototype chain if receiver does not have packed elements. 8452 // Check prototype chain if receiver does not have packed elements.
8368 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); 8453 Node* holey_elements = Word32And(elements_kind, Int32Constant(1));
8369 return Word32Equal(holey_elements, Int32Constant(1)); 8454 return Word32Equal(holey_elements, Int32Constant(1));
8370 } 8455 }
8371 8456
8457 Node* CodeStubAssembler::IsElementsKindGreaterThan(
8458 Node* target_kind, ElementsKind reference_kind) {
8459 return Int32GreaterThan(target_kind, Int32Constant(reference_kind));
8460 }
8461
8372 Node* CodeStubAssembler::IsDebugActive() { 8462 Node* CodeStubAssembler::IsDebugActive() {
8373 Node* is_debug_active = Load( 8463 Node* is_debug_active = Load(
8374 MachineType::Uint8(), 8464 MachineType::Uint8(),
8375 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); 8465 ExternalConstant(ExternalReference::debug_is_active_address(isolate())));
8376 return Word32NotEqual(is_debug_active, Int32Constant(0)); 8466 return Word32NotEqual(is_debug_active, Int32Constant(0));
8377 } 8467 }
8378 8468
8379 Node* CodeStubAssembler::IsPromiseHookEnabledOrDebugIsActive() { 8469 Node* CodeStubAssembler::IsPromiseHookEnabledOrDebugIsActive() {
8380 Node* const promise_hook_or_debug_is_active = 8470 Node* const promise_hook_or_debug_is_active =
8381 Load(MachineType::Uint8(), 8471 Load(MachineType::Uint8(),
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
8467 formatted.c_str(), TENURED); 8557 formatted.c_str(), TENURED);
8468 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), 8558 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(),
8469 HeapConstant(string)); 8559 HeapConstant(string));
8470 } 8560 }
8471 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); 8561 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value);
8472 #endif 8562 #endif
8473 } 8563 }
8474 8564
8475 } // namespace internal 8565 } // namespace internal
8476 } // namespace v8 8566 } // 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