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/compiler/js-builtin-reducer.cc

Issue 2638393002: [builtins] Add String.prototype.indexOf fast path in TF (Closed)
Patch Set: fix return statement Created 3 years, 11 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/compiler/js-builtin-reducer.h ('k') | src/interface-descriptors.h » ('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 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 "src/compiler/js-builtin-reducer.h" 5 #include "src/compiler/js-builtin-reducer.h"
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/code-factory.h"
8 #include "src/compilation-dependencies.h" 9 #include "src/compilation-dependencies.h"
9 #include "src/compiler/access-builder.h" 10 #include "src/compiler/access-builder.h"
10 #include "src/compiler/js-graph.h" 11 #include "src/compiler/js-graph.h"
12 #include "src/compiler/linkage.h"
11 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/node-matchers.h"
12 #include "src/compiler/node-properties.h" 14 #include "src/compiler/node-properties.h"
13 #include "src/compiler/simplified-operator.h" 15 #include "src/compiler/simplified-operator.h"
14 #include "src/compiler/type-cache.h" 16 #include "src/compiler/type-cache.h"
15 #include "src/compiler/types.h" 17 #include "src/compiler/types.h"
16 #include "src/objects-inl.h" 18 #include "src/objects-inl.h"
17 19
18 namespace v8 { 20 namespace v8 {
19 namespace internal { 21 namespace internal {
20 namespace compiler { 22 namespace compiler {
(...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 if (r.InputsMatchOne(Type::PlainPrimitive())) { 1593 if (r.InputsMatchOne(Type::PlainPrimitive())) {
1592 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a) 1594 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a)
1593 Node* input = ToNumber(r.GetJSCallInput(0)); 1595 Node* input = ToNumber(r.GetJSCallInput(0));
1594 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input); 1596 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input);
1595 return Replace(value); 1597 return Replace(value);
1596 } 1598 }
1597 return NoChange(); 1599 return NoChange();
1598 } 1600 }
1599 1601
1600 namespace { 1602 namespace {
1601 1603 Node* GetInputStringWitness(Node* node, int input_index) {
Benedikt Meurer 2017/01/24 18:12:26 Please undo this change as well, since you only ch
1602 Node* GetStringWitness(Node* node) { 1604 Node* input = NodeProperties::GetValueInput(node, input_index);
1603 Node* receiver = NodeProperties::GetValueInput(node, 1); 1605 Type* input_type = NodeProperties::GetType(input);
1604 Type* receiver_type = NodeProperties::GetType(receiver);
1605 Node* effect = NodeProperties::GetEffectInput(node); 1606 Node* effect = NodeProperties::GetEffectInput(node);
1606 if (receiver_type->Is(Type::String())) return receiver; 1607 if (input_type->Is(Type::String())) return input;
1607 // Check if the {node} is dominated by a CheckString renaming for 1608 // Check if the {node} is dominated by a CheckString renaming for
1608 // it's {receiver}, and if so use that renaming as {receiver} for 1609 // it's {receiver}, and if so use that renaming as {receiver} for
1609 // the lowering below. 1610 // the lowering below.
1610 for (Node* dominator = effect;;) { 1611 for (Node* dominator = effect;;) {
1611 if (dominator->opcode() == IrOpcode::kCheckString && 1612 if (dominator->opcode() == IrOpcode::kCheckString &&
1612 NodeProperties::IsSame(dominator->InputAt(0), receiver)) { 1613 NodeProperties::IsSame(dominator->InputAt(0), input)) {
1613 return dominator; 1614 return dominator;
1614 } 1615 }
1615 if (dominator->op()->EffectInputCount() != 1) { 1616 if (dominator->op()->EffectInputCount() != 1) {
1616 // Didn't find any appropriate CheckString node. 1617 // Didn't find any appropriate CheckString node.
1617 return nullptr; 1618 return nullptr;
1618 } 1619 }
1619 dominator = NodeProperties::GetEffectInput(dominator); 1620 dominator = NodeProperties::GetEffectInput(dominator);
1620 } 1621 }
1621 } 1622 }
1622 1623
1624 Node* GetStringWitness(Node* node) { return GetInputStringWitness(node, 1); }
1623 } // namespace 1625 } // namespace
1624 1626
1625 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) 1627 // ES6 section 21.1.3.1 String.prototype.charAt ( pos )
1626 Reduction JSBuiltinReducer::ReduceStringCharAt(Node* node) { 1628 Reduction JSBuiltinReducer::ReduceStringCharAt(Node* node) {
1627 // We need at least target, receiver and index parameters. 1629 // We need at least target, receiver and index parameters.
1628 if (node->op()->ValueInputCount() >= 3) { 1630 if (node->op()->ValueInputCount() >= 3) {
1629 Node* index = NodeProperties::GetValueInput(node, 2); 1631 Node* index = NodeProperties::GetValueInput(node, 2);
1630 Type* index_type = NodeProperties::GetType(index); 1632 Type* index_type = NodeProperties::GetType(index);
1631 Node* effect = NodeProperties::GetEffectInput(node); 1633 Node* effect = NodeProperties::GetEffectInput(node);
1632 Node* control = NodeProperties::GetControlInput(node); 1634 Node* control = NodeProperties::GetControlInput(node);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 1725
1724 ReplaceWithValue(node, value, effect, control); 1726 ReplaceWithValue(node, value, effect, control);
1725 return Replace(value); 1727 return Replace(value);
1726 } 1728 }
1727 } 1729 }
1728 } 1730 }
1729 1731
1730 return NoChange(); 1732 return NoChange();
1731 } 1733 }
1732 1734
1735 // ES6 String.prototype.indexOf(searchString [, position])
1736 // #sec-string.prototype.indexof
1737 Reduction JSBuiltinReducer::ReduceStringIndexOf(Node* node) {
1738 int arg_count = node->op()->ValueInputCount();
1739 if (arg_count != 3 && arg_count != 4) return NoChange();
1740 Node* receiver;
1741 if (!(receiver = GetStringWitness(node))) return NoChange();
1742 Node* search_string = NodeProperties::GetValueInput(node, 2);
1743 if (!NodeProperties::GetType(search_string)->Is(Type::String())) {
1744 return NoChange();
1745 }
1746 // Replace the current JSFunctionCall to String.prototype.indexOf with a
1747 // simple Call to the unchecked StringIndexOf builtin.
1748 Callable callable = CodeFactory::StringIndexOf(isolate());
1749 const CallInterfaceDescriptor& descriptor = callable.descriptor();
1750 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1751 isolate(), graph()->zone(), descriptor,
1752 descriptor.GetStackParameterCount(), CallDescriptor::kNoFlags,
1753 Operator::kEliminatable);
Benedikt Meurer 2017/01/24 18:12:26 This should even be pure, since Strings are immuta
Camillo Bruni 2017/01/25 23:11:40 done.
1754 Node* stub_code = jsgraph()->HeapConstant(callable.code());
1755 RelaxControls(node);
1756 // Remove framestate since StringIndexOf cannot deopt.
1757 node->RemoveInput(arg_count + 1);
1758 // Remove the control input.
1759 node->RemoveInput(arg_count + 2);
1760 // Replace the JSFunction from the JSFunctionCall node with the CodeStub.
1761 node->ReplaceInput(0, stub_code);
1762 if (arg_count == 3) {
1763 // Insert the missing position argument.
1764 node->InsertInput(graph()->zone(), 3, jsgraph()->ZeroConstant());
1765 }
1766 NodeProperties::ChangeOp(node, common()->Call(desc));
1767 return Changed(node);
1768 }
1769
1733 Reduction JSBuiltinReducer::ReduceStringIterator(Node* node) { 1770 Reduction JSBuiltinReducer::ReduceStringIterator(Node* node) {
1734 if (Node* receiver = GetStringWitness(node)) { 1771 if (Node* receiver = GetStringWitness(node)) {
1735 Node* effect = NodeProperties::GetEffectInput(node); 1772 Node* effect = NodeProperties::GetEffectInput(node);
1736 Node* control = NodeProperties::GetControlInput(node); 1773 Node* control = NodeProperties::GetControlInput(node);
1737 1774
1738 Node* map = jsgraph()->HeapConstant( 1775 Node* map = jsgraph()->HeapConstant(
1739 handle(native_context()->string_iterator_map(), isolate())); 1776 handle(native_context()->string_iterator_map(), isolate()));
1740 1777
1741 // allocate new iterator 1778 // allocate new iterator
1742 effect = graph()->NewNode( 1779 effect = graph()->NewNode(
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
2094 case kObjectCreate: 2131 case kObjectCreate:
2095 reduction = ReduceObjectCreate(node); 2132 reduction = ReduceObjectCreate(node);
2096 break; 2133 break;
2097 case kStringFromCharCode: 2134 case kStringFromCharCode:
2098 reduction = ReduceStringFromCharCode(node); 2135 reduction = ReduceStringFromCharCode(node);
2099 break; 2136 break;
2100 case kStringCharAt: 2137 case kStringCharAt:
2101 return ReduceStringCharAt(node); 2138 return ReduceStringCharAt(node);
2102 case kStringCharCodeAt: 2139 case kStringCharCodeAt:
2103 return ReduceStringCharCodeAt(node); 2140 return ReduceStringCharCodeAt(node);
2141 case kStringIndexOf:
2142 return ReduceStringIndexOf(node);
2104 case kStringIterator: 2143 case kStringIterator:
2105 return ReduceStringIterator(node); 2144 return ReduceStringIterator(node);
2106 case kStringIteratorNext: 2145 case kStringIteratorNext:
2107 return ReduceStringIteratorNext(node); 2146 return ReduceStringIteratorNext(node);
2108 case kDataViewByteLength: 2147 case kDataViewByteLength:
2109 return ReduceArrayBufferViewAccessor( 2148 return ReduceArrayBufferViewAccessor(
2110 node, JS_DATA_VIEW_TYPE, 2149 node, JS_DATA_VIEW_TYPE,
2111 AccessBuilder::ForJSArrayBufferViewByteLength()); 2150 AccessBuilder::ForJSArrayBufferViewByteLength());
2112 case kDataViewByteOffset: 2151 case kDataViewByteOffset:
2113 return ReduceArrayBufferViewAccessor( 2152 return ReduceArrayBufferViewAccessor(
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 return jsgraph()->simplified(); 2209 return jsgraph()->simplified();
2171 } 2210 }
2172 2211
2173 JSOperatorBuilder* JSBuiltinReducer::javascript() const { 2212 JSOperatorBuilder* JSBuiltinReducer::javascript() const {
2174 return jsgraph()->javascript(); 2213 return jsgraph()->javascript();
2175 } 2214 }
2176 2215
2177 } // namespace compiler 2216 } // namespace compiler
2178 } // namespace internal 2217 } // namespace internal
2179 } // namespace v8 2218 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-builtin-reducer.h ('k') | src/interface-descriptors.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698