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

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

Issue 2916063002: [turbofan] Optimize Function.prototype.bind for the common case. (Closed)
Patch Set: Created 3 years, 6 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/compiler/typer.cc » ('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/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils.h"
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/compilation-dependencies.h" 10 #include "src/compilation-dependencies.h"
(...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 if (HasInstanceTypeWitness(receiver, effect, JS_DATE_TYPE)) { 1245 if (HasInstanceTypeWitness(receiver, effect, JS_DATE_TYPE)) {
1246 Node* value = effect = graph()->NewNode( 1246 Node* value = effect = graph()->NewNode(
1247 simplified()->LoadField(AccessBuilder::ForJSDateValue()), receiver, 1247 simplified()->LoadField(AccessBuilder::ForJSDateValue()), receiver,
1248 effect, control); 1248 effect, control);
1249 ReplaceWithValue(node, value, effect, control); 1249 ReplaceWithValue(node, value, effect, control);
1250 return Replace(value); 1250 return Replace(value);
1251 } 1251 }
1252 return NoChange(); 1252 return NoChange();
1253 } 1253 }
1254 1254
1255 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args )
1256 Reduction JSBuiltinReducer::ReduceFunctionBind(Node* node) {
1257 Node* receiver = NodeProperties::GetValueInput(node, 1);
1258 Type* receiver_type = NodeProperties::GetType(receiver);
1259 Node* bound_this = (node->op()->ValueInputCount() < 3)
1260 ? jsgraph()->UndefinedConstant()
1261 : NodeProperties::GetValueInput(node, 2);
Jarin 2017/06/02 08:07:42 Please describe in a comment what is the layout of
Benedikt Meurer 2017/06/02 11:58:43 Done.
1262 Node* effect = NodeProperties::GetEffectInput(node);
1263 Node* control = NodeProperties::GetControlInput(node);
1264 if (receiver_type->IsHeapConstant() &&
1265 receiver_type->AsHeapConstant()->Value()->IsJSFunction()) {
1266 Handle<JSFunction> target_function =
1267 Handle<JSFunction>::cast(receiver_type->AsHeapConstant()->Value());
1268
1269 // Check that the "length" property on the {target_function} is the
1270 // default JSFunction accessor.
1271 LookupIterator length_lookup(target_function, factory()->length_string(),
1272 target_function, LookupIterator::OWN);
1273 if (length_lookup.state() != LookupIterator::ACCESSOR ||
1274 !length_lookup.GetAccessors()->IsAccessorInfo()) {
1275 return NoChange();
1276 }
1277
1278 // Check that the "name" property on the {target_function} is the
1279 // default JSFunction accessor.
1280 LookupIterator name_lookup(target_function, factory()->name_string(),
1281 target_function, LookupIterator::OWN);
1282 if (name_lookup.state() != LookupIterator::ACCESSOR ||
1283 !name_lookup.GetAccessors()->IsAccessorInfo()) {
1284 return NoChange();
1285 }
1286
1287 // Determine the prototype of the {target_function}.
1288 Handle<Object> prototype(target_function->map()->prototype(), isolate());
1289
1290 // Setup the map for the JSBoundFunction instance.
1291 Handle<Map> map = target_function->IsConstructor()
1292 ? isolate()->bound_function_with_constructor_map()
1293 : isolate()->bound_function_without_constructor_map();
1294 if (map->prototype() != *prototype) {
1295 map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
1296 }
1297 DCHECK_EQ(target_function->IsConstructor(), map->is_constructor());
1298
1299 // Create the [[BoundArguments]] for the result.
1300 Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
1301 if (node->op()->ValueInputCount() > 3) {
1302 int const length = node->op()->ValueInputCount() - 3;
1303 effect = graph()->NewNode(
1304 common()->BeginRegion(RegionObservability::kNotObservable), effect);
1305 bound_arguments = effect = graph()->NewNode(
1306 simplified()->Allocate(Type::OtherInternal(), NOT_TENURED),
1307 jsgraph()->Constant(FixedArray::SizeFor(length)), effect, control);
1308 effect = graph()->NewNode(
1309 simplified()->StoreField(AccessBuilder::ForMap()), bound_arguments,
1310 jsgraph()->FixedArrayMapConstant(), effect, control);
1311 effect = graph()->NewNode(
1312 simplified()->StoreField(AccessBuilder::ForFixedArrayLength()),
1313 bound_arguments, jsgraph()->Constant(length), effect, control);
1314 for (int i = 0; i < length; ++i) {
1315 effect = graph()->NewNode(
1316 simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)),
1317 bound_arguments, NodeProperties::GetValueInput(node, 3 + i), effect,
1318 control);
1319 }
1320 bound_arguments = effect =
1321 graph()->NewNode(common()->FinishRegion(), bound_arguments, effect);
1322 }
1323
1324 // Create the JSBoundFunction result.
1325 effect = graph()->NewNode(
1326 common()->BeginRegion(RegionObservability::kNotObservable), effect);
1327 Node* value = effect = graph()->NewNode(
1328 simplified()->Allocate(Type::BoundFunction(), NOT_TENURED),
1329 jsgraph()->Constant(JSBoundFunction::kSize), effect, control);
1330 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
1331 value, jsgraph()->Constant(map), effect, control);
1332 effect = graph()->NewNode(
1333 simplified()->StoreField(AccessBuilder::ForJSObjectProperties()), value,
1334 jsgraph()->EmptyFixedArrayConstant(), effect, control);
1335 effect = graph()->NewNode(
1336 simplified()->StoreField(AccessBuilder::ForJSObjectElements()), value,
1337 jsgraph()->EmptyFixedArrayConstant(), effect, control);
1338 effect = graph()->NewNode(
1339 simplified()->StoreField(
1340 AccessBuilder::ForJSBoundFunctionBoundTargetFunction()),
1341 value, receiver, effect, control);
1342 effect = graph()->NewNode(
1343 simplified()->StoreField(AccessBuilder::ForJSBoundFunctionBoundThis()),
1344 value, bound_this, effect, control);
1345 effect =
1346 graph()->NewNode(simplified()->StoreField(
1347 AccessBuilder::ForJSBoundFunctionBoundArguments()),
1348 value, bound_arguments, effect, control);
1349 value = effect = graph()->NewNode(common()->FinishRegion(), value, effect);
1350
1351 ReplaceWithValue(node, value, effect, control);
1352 return Replace(value);
1353 }
1354 return NoChange();
1355 }
1356
1255 // ES6 section 18.2.2 isFinite ( number ) 1357 // ES6 section 18.2.2 isFinite ( number )
1256 Reduction JSBuiltinReducer::ReduceGlobalIsFinite(Node* node) { 1358 Reduction JSBuiltinReducer::ReduceGlobalIsFinite(Node* node) {
1257 JSCallReduction r(node); 1359 JSCallReduction r(node);
1258 if (r.InputsMatchOne(Type::PlainPrimitive())) { 1360 if (r.InputsMatchOne(Type::PlainPrimitive())) {
1259 // isFinite(a:plain-primitive) -> NumberEqual(a', a') 1361 // isFinite(a:plain-primitive) -> NumberEqual(a', a')
1260 // where a' = NumberSubtract(ToNumber(a), ToNumber(a)) 1362 // where a' = NumberSubtract(ToNumber(a), ToNumber(a))
1261 Node* input = ToNumber(r.GetJSCallInput(0)); 1363 Node* input = ToNumber(r.GetJSCallInput(0));
1262 Node* diff = graph()->NewNode(simplified()->NumberSubtract(), input, input); 1364 Node* diff = graph()->NewNode(simplified()->NumberSubtract(), input, input);
1263 Node* value = graph()->NewNode(simplified()->NumberEqual(), diff, diff); 1365 Node* value = graph()->NewNode(simplified()->NumberEqual(), diff, diff);
1264 return Replace(value); 1366 return Replace(value);
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
2319 case kArrayPop: 2421 case kArrayPop:
2320 return ReduceArrayPop(node); 2422 return ReduceArrayPop(node);
2321 case kArrayPush: 2423 case kArrayPush:
2322 return ReduceArrayPush(node); 2424 return ReduceArrayPush(node);
2323 case kArrayShift: 2425 case kArrayShift:
2324 return ReduceArrayShift(node); 2426 return ReduceArrayShift(node);
2325 case kDateNow: 2427 case kDateNow:
2326 return ReduceDateNow(node); 2428 return ReduceDateNow(node);
2327 case kDateGetTime: 2429 case kDateGetTime:
2328 return ReduceDateGetTime(node); 2430 return ReduceDateGetTime(node);
2431 case kFunctionBind:
2432 return ReduceFunctionBind(node);
2329 case kGlobalIsFinite: 2433 case kGlobalIsFinite:
2330 reduction = ReduceGlobalIsFinite(node); 2434 reduction = ReduceGlobalIsFinite(node);
2331 break; 2435 break;
2332 case kGlobalIsNaN: 2436 case kGlobalIsNaN:
2333 reduction = ReduceGlobalIsNaN(node); 2437 reduction = ReduceGlobalIsNaN(node);
2334 break; 2438 break;
2335 case kMathAbs: 2439 case kMathAbs:
2336 reduction = ReduceMathAbs(node); 2440 reduction = ReduceMathAbs(node);
2337 break; 2441 break;
2338 case kMathAcos: 2442 case kMathAcos:
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2529 return jsgraph()->simplified(); 2633 return jsgraph()->simplified();
2530 } 2634 }
2531 2635
2532 JSOperatorBuilder* JSBuiltinReducer::javascript() const { 2636 JSOperatorBuilder* JSBuiltinReducer::javascript() const {
2533 return jsgraph()->javascript(); 2637 return jsgraph()->javascript();
2534 } 2638 }
2535 2639
2536 } // namespace compiler 2640 } // namespace compiler
2537 } // namespace internal 2641 } // namespace internal
2538 } // namespace v8 2642 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-builtin-reducer.h ('k') | src/compiler/typer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698