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

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

Issue 2916063002: [turbofan] Optimize Function.prototype.bind for the common case. (Closed)
Patch Set: Address feedback. 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 // Value inputs to the {node} are as follows:
1258 //
1259 // - target, which is Function.prototype.bind JSFunction
1260 // - receiver, which is the [[BoundTargetFunction]]
1261 // - bound_this (optional), which is the [[BoundThis]]
1262 // - and all the remaining value inouts are [[BoundArguments]]
1263 Node* receiver = NodeProperties::GetValueInput(node, 1);
1264 Type* receiver_type = NodeProperties::GetType(receiver);
1265 Node* bound_this = (node->op()->ValueInputCount() < 3)
1266 ? jsgraph()->UndefinedConstant()
1267 : NodeProperties::GetValueInput(node, 2);
1268 Node* effect = NodeProperties::GetEffectInput(node);
1269 Node* control = NodeProperties::GetControlInput(node);
1270 if (receiver_type->IsHeapConstant() &&
1271 receiver_type->AsHeapConstant()->Value()->IsJSFunction()) {
1272 Handle<JSFunction> target_function =
1273 Handle<JSFunction>::cast(receiver_type->AsHeapConstant()->Value());
1274
1275 // Check that the "length" property on the {target_function} is the
1276 // default JSFunction accessor.
1277 LookupIterator length_lookup(target_function, factory()->length_string(),
1278 target_function, LookupIterator::OWN);
1279 if (length_lookup.state() != LookupIterator::ACCESSOR ||
1280 !length_lookup.GetAccessors()->IsAccessorInfo()) {
1281 return NoChange();
1282 }
1283
1284 // Check that the "name" property on the {target_function} is the
1285 // default JSFunction accessor.
1286 LookupIterator name_lookup(target_function, factory()->name_string(),
1287 target_function, LookupIterator::OWN);
1288 if (name_lookup.state() != LookupIterator::ACCESSOR ||
1289 !name_lookup.GetAccessors()->IsAccessorInfo()) {
1290 return NoChange();
1291 }
1292
1293 // Determine the prototype of the {target_function}.
1294 Handle<Object> prototype(target_function->map()->prototype(), isolate());
1295
1296 // Setup the map for the JSBoundFunction instance.
1297 Handle<Map> map = target_function->IsConstructor()
1298 ? isolate()->bound_function_with_constructor_map()
1299 : isolate()->bound_function_without_constructor_map();
1300 if (map->prototype() != *prototype) {
1301 map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE);
1302 }
1303 DCHECK_EQ(target_function->IsConstructor(), map->is_constructor());
1304
1305 // Create the [[BoundArguments]] for the result.
1306 Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
1307 if (node->op()->ValueInputCount() > 3) {
1308 int const length = node->op()->ValueInputCount() - 3;
1309 effect = graph()->NewNode(
1310 common()->BeginRegion(RegionObservability::kNotObservable), effect);
1311 bound_arguments = effect = graph()->NewNode(
1312 simplified()->Allocate(Type::OtherInternal(), NOT_TENURED),
1313 jsgraph()->Constant(FixedArray::SizeFor(length)), effect, control);
1314 effect = graph()->NewNode(
1315 simplified()->StoreField(AccessBuilder::ForMap()), bound_arguments,
1316 jsgraph()->FixedArrayMapConstant(), effect, control);
1317 effect = graph()->NewNode(
1318 simplified()->StoreField(AccessBuilder::ForFixedArrayLength()),
1319 bound_arguments, jsgraph()->Constant(length), effect, control);
1320 for (int i = 0; i < length; ++i) {
1321 effect = graph()->NewNode(
1322 simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)),
1323 bound_arguments, NodeProperties::GetValueInput(node, 3 + i), effect,
1324 control);
1325 }
1326 bound_arguments = effect =
1327 graph()->NewNode(common()->FinishRegion(), bound_arguments, effect);
1328 }
1329
1330 // Create the JSBoundFunction result.
1331 effect = graph()->NewNode(
1332 common()->BeginRegion(RegionObservability::kNotObservable), effect);
1333 Node* value = effect = graph()->NewNode(
1334 simplified()->Allocate(Type::BoundFunction(), NOT_TENURED),
1335 jsgraph()->Constant(JSBoundFunction::kSize), effect, control);
1336 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
1337 value, jsgraph()->Constant(map), effect, control);
1338 effect = graph()->NewNode(
1339 simplified()->StoreField(AccessBuilder::ForJSObjectProperties()), value,
1340 jsgraph()->EmptyFixedArrayConstant(), effect, control);
1341 effect = graph()->NewNode(
1342 simplified()->StoreField(AccessBuilder::ForJSObjectElements()), value,
1343 jsgraph()->EmptyFixedArrayConstant(), effect, control);
1344 effect = graph()->NewNode(
1345 simplified()->StoreField(
1346 AccessBuilder::ForJSBoundFunctionBoundTargetFunction()),
1347 value, receiver, effect, control);
1348 effect = graph()->NewNode(
1349 simplified()->StoreField(AccessBuilder::ForJSBoundFunctionBoundThis()),
1350 value, bound_this, effect, control);
1351 effect =
1352 graph()->NewNode(simplified()->StoreField(
1353 AccessBuilder::ForJSBoundFunctionBoundArguments()),
1354 value, bound_arguments, effect, control);
1355 value = effect = graph()->NewNode(common()->FinishRegion(), value, effect);
1356
1357 ReplaceWithValue(node, value, effect, control);
1358 return Replace(value);
1359 }
1360 return NoChange();
1361 }
1362
1255 // ES6 section 18.2.2 isFinite ( number ) 1363 // ES6 section 18.2.2 isFinite ( number )
1256 Reduction JSBuiltinReducer::ReduceGlobalIsFinite(Node* node) { 1364 Reduction JSBuiltinReducer::ReduceGlobalIsFinite(Node* node) {
1257 JSCallReduction r(node); 1365 JSCallReduction r(node);
1258 if (r.InputsMatchOne(Type::PlainPrimitive())) { 1366 if (r.InputsMatchOne(Type::PlainPrimitive())) {
1259 // isFinite(a:plain-primitive) -> NumberEqual(a', a') 1367 // isFinite(a:plain-primitive) -> NumberEqual(a', a')
1260 // where a' = NumberSubtract(ToNumber(a), ToNumber(a)) 1368 // where a' = NumberSubtract(ToNumber(a), ToNumber(a))
1261 Node* input = ToNumber(r.GetJSCallInput(0)); 1369 Node* input = ToNumber(r.GetJSCallInput(0));
1262 Node* diff = graph()->NewNode(simplified()->NumberSubtract(), input, input); 1370 Node* diff = graph()->NewNode(simplified()->NumberSubtract(), input, input);
1263 Node* value = graph()->NewNode(simplified()->NumberEqual(), diff, diff); 1371 Node* value = graph()->NewNode(simplified()->NumberEqual(), diff, diff);
1264 return Replace(value); 1372 return Replace(value);
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
2319 case kArrayPop: 2427 case kArrayPop:
2320 return ReduceArrayPop(node); 2428 return ReduceArrayPop(node);
2321 case kArrayPush: 2429 case kArrayPush:
2322 return ReduceArrayPush(node); 2430 return ReduceArrayPush(node);
2323 case kArrayShift: 2431 case kArrayShift:
2324 return ReduceArrayShift(node); 2432 return ReduceArrayShift(node);
2325 case kDateNow: 2433 case kDateNow:
2326 return ReduceDateNow(node); 2434 return ReduceDateNow(node);
2327 case kDateGetTime: 2435 case kDateGetTime:
2328 return ReduceDateGetTime(node); 2436 return ReduceDateGetTime(node);
2437 case kFunctionBind:
2438 return ReduceFunctionBind(node);
2329 case kGlobalIsFinite: 2439 case kGlobalIsFinite:
2330 reduction = ReduceGlobalIsFinite(node); 2440 reduction = ReduceGlobalIsFinite(node);
2331 break; 2441 break;
2332 case kGlobalIsNaN: 2442 case kGlobalIsNaN:
2333 reduction = ReduceGlobalIsNaN(node); 2443 reduction = ReduceGlobalIsNaN(node);
2334 break; 2444 break;
2335 case kMathAbs: 2445 case kMathAbs:
2336 reduction = ReduceMathAbs(node); 2446 reduction = ReduceMathAbs(node);
2337 break; 2447 break;
2338 case kMathAcos: 2448 case kMathAcos:
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2529 return jsgraph()->simplified(); 2639 return jsgraph()->simplified();
2530 } 2640 }
2531 2641
2532 JSOperatorBuilder* JSBuiltinReducer::javascript() const { 2642 JSOperatorBuilder* JSBuiltinReducer::javascript() const {
2533 return jsgraph()->javascript(); 2643 return jsgraph()->javascript();
2534 } 2644 }
2535 2645
2536 } // namespace compiler 2646 } // namespace compiler
2537 } // namespace internal 2647 } // namespace internal
2538 } // namespace v8 2648 } // 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