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

Side by Side Diff: src/compiler/js-builtin-reducer.cc

Issue 2638393002: [builtins] Add String.prototype.indexOf fast path in TF (Closed)
Patch Set: update comments 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
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 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 if (r.InputsMatchOne(Type::PlainPrimitive())) { 1605 if (r.InputsMatchOne(Type::PlainPrimitive())) {
1604 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a) 1606 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a)
1605 Node* input = ToNumber(r.GetJSCallInput(0)); 1607 Node* input = ToNumber(r.GetJSCallInput(0));
1606 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input); 1608 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input);
1607 return Replace(value); 1609 return Replace(value);
1608 } 1610 }
1609 return NoChange(); 1611 return NoChange();
1610 } 1612 }
1611 1613
1612 namespace { 1614 namespace {
1613 1615 Node* GetInputStringWitness(Node* node, int input_index) {
1614 Node* GetStringWitness(Node* node) { 1616 Node* input = NodeProperties::GetValueInput(node, input_index);
1615 Node* receiver = NodeProperties::GetValueInput(node, 1); 1617 Type* input_type = NodeProperties::GetType(input);
1616 Type* receiver_type = NodeProperties::GetType(receiver);
1617 Node* effect = NodeProperties::GetEffectInput(node); 1618 Node* effect = NodeProperties::GetEffectInput(node);
1618 if (receiver_type->Is(Type::String())) return receiver; 1619 if (input_type->Is(Type::String())) return input;
1619 // Check if the {node} is dominated by a CheckString renaming for 1620 // Check if the {node} is dominated by a CheckString renaming for
1620 // it's {receiver}, and if so use that renaming as {receiver} for 1621 // it's {input}, and if so use that renaming as {input} for
1621 // the lowering below. 1622 // the lowering below.
1622 for (Node* dominator = effect;;) { 1623 for (Node* dominator = effect;;) {
1623 if (dominator->opcode() == IrOpcode::kCheckString && 1624 if (dominator->opcode() == IrOpcode::kCheckString &&
1624 IsSame(dominator->InputAt(0), receiver)) { 1625 IsSame(dominator->InputAt(0), input)) {
1625 return dominator; 1626 return dominator;
1626 } 1627 }
1627 if (dominator->op()->EffectInputCount() != 1) { 1628 if (dominator->op()->EffectInputCount() != 1) {
1628 // Didn't find any appropriate CheckString node. 1629 // Didn't find any appropriate CheckString node.
1629 return nullptr; 1630 return nullptr;
1630 } 1631 }
1631 dominator = NodeProperties::GetEffectInput(dominator); 1632 dominator = NodeProperties::GetEffectInput(dominator);
1632 } 1633 }
1633 } 1634 }
1634 1635
1636 Node* GetStringWitness(Node* node) { return GetInputStringWitness(node, 1); }
1635 } // namespace 1637 } // namespace
1636 1638
1637 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) 1639 // ES6 section 21.1.3.1 String.prototype.charAt ( pos )
1638 Reduction JSBuiltinReducer::ReduceStringCharAt(Node* node) { 1640 Reduction JSBuiltinReducer::ReduceStringCharAt(Node* node) {
1639 // We need at least target, receiver and index parameters. 1641 // We need at least target, receiver and index parameters.
1640 if (node->op()->ValueInputCount() >= 3) { 1642 if (node->op()->ValueInputCount() >= 3) {
1641 Node* index = NodeProperties::GetValueInput(node, 2); 1643 Node* index = NodeProperties::GetValueInput(node, 2);
1642 Type* index_type = NodeProperties::GetType(index); 1644 Type* index_type = NodeProperties::GetType(index);
1643 Node* effect = NodeProperties::GetEffectInput(node); 1645 Node* effect = NodeProperties::GetEffectInput(node);
1644 Node* control = NodeProperties::GetControlInput(node); 1646 Node* control = NodeProperties::GetControlInput(node);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1735 1737
1736 ReplaceWithValue(node, value, effect, control); 1738 ReplaceWithValue(node, value, effect, control);
1737 return Replace(value); 1739 return Replace(value);
1738 } 1740 }
1739 } 1741 }
1740 } 1742 }
1741 1743
1742 return NoChange(); 1744 return NoChange();
1743 } 1745 }
1744 1746
1747 // ES6 String.prototype.indexOf(searchString [, position])
1748 // #sec-string.prototype.indexof
1749 Reduction JSBuiltinReducer::ReduceStringIndexOf(Node* node) {
1750 int arg_count = node->op()->ValueInputCount();
1751 if (arg_count != 3 && arg_count != 4) return NoChange();
1752 Node* receiver;
1753 if (!(receiver = GetStringWitness(node))) return NoChange();
1754 Node* search_string;
1755 if (!(search_string = GetInputStringWitness(node, 2))) return NoChange();
Benedikt Meurer 2017/01/18 18:10:40 I'm not convinced this is beneficial; can we limit
Camillo Bruni 2017/01/24 15:51:43 ack. replaced by simple type check,
1756 // Replace the current JSFunctionCall to String.prototype.indexOf with a
1757 // simple Call to the unchecked StringIndexOf builtin.
1758 Callable callable = CodeFactory::StringIndexOf(isolate());
1759 const CallInterfaceDescriptor& descriptor = callable.descriptor();
1760 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
Benedikt Meurer 2017/01/18 18:10:40 StringIndexOf builtin cannot deopt, so you don't n
Camillo Bruni 2017/01/24 15:51:43 done.
1761 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1762 isolate(), graph()->zone(), descriptor,
1763 descriptor.GetStackParameterCount(), flags, node->op()->properties());
Benedikt Meurer 2017/01/18 18:10:40 Also it doesn't have a side effect, so it should u
Camillo Bruni 2017/01/24 15:51:43 done.
1764 Node* stub_code = jsgraph()->HeapConstant(callable.code());
1765 // Replace the JSFunction from the JSFunctionCall node with the CodeStub.
1766 node->ReplaceInput(0, stub_code);
1767 if (arg_count == 3) {
1768 // Insert the missing position argument.
1769 node->InsertInput(graph()->zone(), 3, jsgraph()->ZeroConstant());
1770 }
1771 NodeProperties::ChangeOp(node, common()->Call(desc));
1772 return Changed(node);
1773 }
1774
1745 Reduction JSBuiltinReducer::ReduceStringIterator(Node* node) { 1775 Reduction JSBuiltinReducer::ReduceStringIterator(Node* node) {
1746 if (Node* receiver = GetStringWitness(node)) { 1776 if (Node* receiver = GetStringWitness(node)) {
1747 Node* effect = NodeProperties::GetEffectInput(node); 1777 Node* effect = NodeProperties::GetEffectInput(node);
1748 Node* control = NodeProperties::GetControlInput(node); 1778 Node* control = NodeProperties::GetControlInput(node);
1749 1779
1750 Node* map = jsgraph()->HeapConstant( 1780 Node* map = jsgraph()->HeapConstant(
1751 handle(native_context()->string_iterator_map(), isolate())); 1781 handle(native_context()->string_iterator_map(), isolate()));
1752 1782
1753 // allocate new iterator 1783 // allocate new iterator
1754 effect = graph()->NewNode( 1784 effect = graph()->NewNode(
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2105 case kObjectCreate: 2135 case kObjectCreate:
2106 reduction = ReduceObjectCreate(node); 2136 reduction = ReduceObjectCreate(node);
2107 break; 2137 break;
2108 case kStringFromCharCode: 2138 case kStringFromCharCode:
2109 reduction = ReduceStringFromCharCode(node); 2139 reduction = ReduceStringFromCharCode(node);
2110 break; 2140 break;
2111 case kStringCharAt: 2141 case kStringCharAt:
2112 return ReduceStringCharAt(node); 2142 return ReduceStringCharAt(node);
2113 case kStringCharCodeAt: 2143 case kStringCharCodeAt:
2114 return ReduceStringCharCodeAt(node); 2144 return ReduceStringCharCodeAt(node);
2145 case kStringIndexOf:
2146 return ReduceStringIndexOf(node);
2115 case kStringIterator: 2147 case kStringIterator:
2116 return ReduceStringIterator(node); 2148 return ReduceStringIterator(node);
2117 case kStringIteratorNext: 2149 case kStringIteratorNext:
2118 return ReduceStringIteratorNext(node); 2150 return ReduceStringIteratorNext(node);
2119 case kDataViewByteLength: 2151 case kDataViewByteLength:
2120 return ReduceArrayBufferViewAccessor( 2152 return ReduceArrayBufferViewAccessor(
2121 node, JS_DATA_VIEW_TYPE, 2153 node, JS_DATA_VIEW_TYPE,
2122 AccessBuilder::ForJSArrayBufferViewByteLength()); 2154 AccessBuilder::ForJSArrayBufferViewByteLength());
2123 case kDataViewByteOffset: 2155 case kDataViewByteOffset:
2124 return ReduceArrayBufferViewAccessor( 2156 return ReduceArrayBufferViewAccessor(
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2181 return jsgraph()->simplified(); 2213 return jsgraph()->simplified();
2182 } 2214 }
2183 2215
2184 JSOperatorBuilder* JSBuiltinReducer::javascript() const { 2216 JSOperatorBuilder* JSBuiltinReducer::javascript() const {
2185 return jsgraph()->javascript(); 2217 return jsgraph()->javascript();
2186 } 2218 }
2187 2219
2188 } // namespace compiler 2220 } // namespace compiler
2189 } // namespace internal 2221 } // namespace internal
2190 } // namespace v8 2222 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698