Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library cps_ir.optimization.inline; | 5 library cps_ir.optimization.inline; |
| 6 | 6 |
| 7 import 'cps_fragment.dart'; | 7 import 'cps_fragment.dart'; |
| 8 import 'cps_ir_builder.dart' show ThisParameterLocal; | 8 import 'cps_ir_builder.dart' show ThisParameterLocal; |
| 9 import 'cps_ir_nodes.dart'; | 9 import 'cps_ir_nodes.dart'; |
| 10 import 'optimizers.dart'; | 10 import 'optimizers.dart'; |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 // Positive inlining result in the cache. | 372 // Positive inlining result in the cache. |
| 373 if (cachedResult is FunctionDefinition) { | 373 if (cachedResult is FunctionDefinition) { |
| 374 FunctionDefinition function = cachedResult; | 374 FunctionDefinition function = cachedResult; |
| 375 _fragment = new CpsFragment(invoke.sourceInformation); | 375 _fragment = new CpsFragment(invoke.sourceInformation); |
| 376 Primitive receiver = invoke.receiver?.definition; | 376 Primitive receiver = invoke.receiver?.definition; |
| 377 List<Primitive> arguments = | 377 List<Primitive> arguments = |
| 378 invoke.arguments.map((Reference ref) => ref.definition).toList(); | 378 invoke.arguments.map((Reference ref) => ref.definition).toList(); |
| 379 // Add a null check to the inlined function body if necessary. The | 379 // Add a null check to the inlined function body if necessary. The |
| 380 // cached function body does not contain the null check. | 380 // cached function body does not contain the null check. |
| 381 if (dartReceiver != null && abstractReceiver.isNullable) { | 381 if (dartReceiver != null && abstractReceiver.isNullable) { |
| 382 Primitive check = | 382 Primitive check = nullReceiverGuard( |
| 383 _fragment.letPrim(new NullCheck(dartReceiver.definition, | 383 invoke, _fragment, dartReceiver.definition, abstractReceiver); |
| 384 invoke.sourceInformation)); | |
| 385 check.type = abstractReceiver.nonNullable(); | |
| 386 if (invoke.callingConvention == CallingConvention.Intercepted) { | 384 if (invoke.callingConvention == CallingConvention.Intercepted) { |
| 387 arguments[0] = check; | 385 arguments[0] = check; |
| 388 } else { | 386 } else { |
| 389 receiver = check; | 387 receiver = check; |
| 390 } | 388 } |
| 391 } | 389 } |
| 392 return _fragment.inlineFunction(function, receiver, arguments, | 390 return _fragment.inlineFunction(function, receiver, arguments, |
| 393 hint: invoke.hint); | 391 hint: invoke.hint); |
| 394 } | 392 } |
| 395 | 393 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 if (invoke.callingConvention == CallingConvention.Intercepted) { | 446 if (invoke.callingConvention == CallingConvention.Intercepted) { |
| 449 arguments[0] = check; | 447 arguments[0] = check; |
| 450 } else { | 448 } else { |
| 451 receiver = check; | 449 receiver = check; |
| 452 } | 450 } |
| 453 } | 451 } |
| 454 return _fragment.inlineFunction(function, receiver, arguments, | 452 return _fragment.inlineFunction(function, receiver, arguments, |
| 455 hint: invoke.hint); | 453 hint: invoke.hint); |
| 456 } | 454 } |
| 457 | 455 |
| 456 Primitive nullReceiverGuard(InvocationPrimitive invoke, | |
| 457 CpsFragment fragment, | |
| 458 Primitive dartReceiver, | |
| 459 TypeMask abstractReceiver) { | |
| 460 Selector selector = invoke is InvokeMethod ? invoke.selector : null; | |
|
Harry Terkelsen
2015/12/28 19:30:41
maybe move inside the "if" since that is the only
| |
| 461 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) { | |
| 462 Primitive condition = _fragment.letPrim( | |
| 463 new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber, | |
| 464 <Primitive>[dartReceiver], | |
| 465 invoke.sourceInformation)); | |
| 466 condition.type = typeSystem.boolType; | |
| 467 Primitive check = _fragment.letPrim( | |
| 468 new NullCheck.guarded( | |
| 469 condition, dartReceiver, selector, invoke.sourceInformation)); | |
| 470 check.type = abstractReceiver.nonNullable(); | |
| 471 return check; | |
| 472 } | |
| 473 | |
| 474 Primitive check = _fragment.letPrim( | |
| 475 new NullCheck(dartReceiver, invoke.sourceInformation)); | |
| 476 check.type = abstractReceiver.nonNullable(); | |
| 477 return check; | |
| 478 } | |
| 479 | |
| 480 | |
| 458 @override | 481 @override |
| 459 Primitive visitInvokeStatic(InvokeStatic node) { | 482 Primitive visitInvokeStatic(InvokeStatic node) { |
| 460 return tryInlining(node, node.target, null); | 483 return tryInlining(node, node.target, null); |
| 461 } | 484 } |
| 462 | 485 |
| 463 @override | 486 @override |
| 464 Primitive visitInvokeMethod(InvokeMethod node) { | 487 Primitive visitInvokeMethod(InvokeMethod node) { |
| 465 Primitive receiver = node.dartReceiver; | 488 Primitive receiver = node.dartReceiver; |
| 466 Element element = world.locateSingleElement(node.selector, receiver.type); | 489 Element element = world.locateSingleElement(node.selector, receiver.type); |
| 467 if (element == null || element is! FunctionElement) return null; | 490 if (element == null || element is! FunctionElement) return null; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 486 // We cannot inline a constructor invocation containing type arguments | 509 // We cannot inline a constructor invocation containing type arguments |
| 487 // because CreateInstance in the body does not know the type arguments. | 510 // because CreateInstance in the body does not know the type arguments. |
| 488 // We would incorrectly instantiate a class like A instead of A<B>. | 511 // We would incorrectly instantiate a class like A instead of A<B>. |
| 489 // TODO(kmillikin): try to fix this. | 512 // TODO(kmillikin): try to fix this. |
| 490 GenericType generic = node.dartType; | 513 GenericType generic = node.dartType; |
| 491 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; | 514 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; |
| 492 } | 515 } |
| 493 return tryInlining(node, node.target, null); | 516 return tryInlining(node, node.target, null); |
| 494 } | 517 } |
| 495 } | 518 } |
| OLD | NEW |