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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/inline.dart

Issue 1561953005: Fix null receiver guard an uncached site. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 dartReceiver == null ? null : abstractType(dartReceiver); 373 dartReceiver == null ? null : abstractType(dartReceiver);
374 List<TypeMask> abstractArguments = 374 List<TypeMask> abstractArguments =
375 invoke.arguments.map(abstractType).toList(); 375 invoke.arguments.map(abstractType).toList();
376 var cachedResult = _inliner.cache.get(target, callStructure, 376 var cachedResult = _inliner.cache.get(target, callStructure,
377 abstractReceiver, 377 abstractReceiver,
378 abstractArguments); 378 abstractArguments);
379 379
380 // Negative inlining result in the cache. 380 // Negative inlining result in the cache.
381 if (cachedResult == InliningCache.NO_INLINE) return null; 381 if (cachedResult == InliningCache.NO_INLINE) return null;
382 382
383 // Positive inlining result in the cache. 383 Primitive finish(FunctionDefinition function) {
384 if (cachedResult is FunctionDefinition) {
385 FunctionDefinition function = cachedResult;
386 _fragment = new CpsFragment(invoke.sourceInformation); 384 _fragment = new CpsFragment(invoke.sourceInformation);
387 Primitive receiver = invoke.receiver?.definition; 385 Primitive receiver = invoke.receiver?.definition;
386 Reference<Primitive> dartReceiver = invoke.dartReceiverReference;
Kevin Millikin (Google) 2016/01/07 18:15:08 This is already in scope, isn't it?
sra1 2016/01/07 18:23:14 Yes, thanks.
388 List<Primitive> arguments = 387 List<Primitive> arguments =
389 invoke.arguments.map((Reference ref) => ref.definition).toList(); 388 invoke.arguments.map((Reference ref) => ref.definition).toList();
390 // Add a null check to the inlined function body if necessary. The 389 // Add a null check to the inlined function body if necessary. The
391 // cached function body does not contain the null check. 390 // cached function body does not contain the null check.
392 if (dartReceiver != null && abstractReceiver.isNullable) { 391 if (dartReceiver != null && abstractReceiver.isNullable) {
393 Primitive check = nullReceiverGuard( 392 Primitive check = nullReceiverGuard(
394 invoke, _fragment, dartReceiver.definition, abstractReceiver); 393 invoke, _fragment, dartReceiver.definition, abstractReceiver);
395 if (invoke.callingConvention == CallingConvention.Intercepted) { 394 if (invoke.callingConvention == CallingConvention.Intercepted) {
396 arguments[0] = check; 395 arguments[0] = check;
397 } else { 396 } else {
398 receiver = check; 397 receiver = check;
399 } 398 }
400 } 399 }
401 return _fragment.inlineFunction(function, receiver, arguments, 400 return _fragment.inlineFunction(function, receiver, arguments,
402 hint: invoke.hint); 401 hint: invoke.hint);
403 } 402 }
404 403
404 // Positive inlining result in the cache.
405 if (cachedResult is FunctionDefinition) {
406 return finish(cachedResult);
407 }
408
405 // We have not seen this combination of target and abstract arguments 409 // We have not seen this combination of target and abstract arguments
406 // before. Make an inlining decision. 410 // before. Make an inlining decision.
407 assert(cachedResult == InliningCache.ABSENT); 411 assert(cachedResult == InliningCache.ABSENT);
408 Primitive doNotInline() { 412 Primitive doNotInline() {
409 _inliner.cache.putNegative(target, callStructure, abstractReceiver, 413 _inliner.cache.putNegative(target, callStructure, abstractReceiver,
410 abstractArguments); 414 abstractArguments);
411 return null; 415 return null;
412 } 416 }
413 if (backend.annotations.noInline(target)) return doNotInline(); 417 if (backend.annotations.noInline(target)) return doNotInline();
414 if (isRecursive(target, callStructure)) return doNotInline(); 418 if (isRecursive(target, callStructure)) return doNotInline();
(...skipping 23 matching lines...) Expand all
438 // Inline calls in the body. 442 // Inline calls in the body.
439 _inliner.rewrite(function, callStructure); 443 _inliner.rewrite(function, callStructure);
440 444
441 // Compute the size. 445 // Compute the size.
442 // TODO(kmillikin): Tune the size bound. 446 // TODO(kmillikin): Tune the size bound.
443 int size = SizeVisitor.sizeOf(invoke, function); 447 int size = SizeVisitor.sizeOf(invoke, function);
444 if (!_inliner.isCalledOnce(target) && size > 11) return doNotInline(); 448 if (!_inliner.isCalledOnce(target) && size > 11) return doNotInline();
445 449
446 _inliner.cache.putPositive(target, callStructure, abstractReceiver, 450 _inliner.cache.putPositive(target, callStructure, abstractReceiver,
447 abstractArguments, function); 451 abstractArguments, function);
448 _fragment = new CpsFragment(invoke.sourceInformation); 452 return finish(function);
449 Primitive receiver = invoke.receiver?.definition;
450 List<Primitive> arguments =
451 invoke.arguments.map((Reference ref) => ref.definition).toList();
452 if (dartReceiver != null && abstractReceiver.isNullable) {
453 Primitive check =
454 _fragment.letPrim(new NullCheck(dartReceiver.definition,
455 invoke.sourceInformation));
456 check.type = abstractReceiver.nonNullable();
457 if (invoke.callingConvention == CallingConvention.Intercepted) {
458 arguments[0] = check;
459 } else {
460 receiver = check;
461 }
462 }
463 return _fragment.inlineFunction(function, receiver, arguments,
464 hint: invoke.hint);
465 } 453 }
466 454
467 Primitive nullReceiverGuard(InvocationPrimitive invoke, 455 Primitive nullReceiverGuard(InvocationPrimitive invoke,
468 CpsFragment fragment, 456 CpsFragment fragment,
469 Primitive dartReceiver, 457 Primitive dartReceiver,
470 TypeMask abstractReceiver) { 458 TypeMask abstractReceiver) {
471 Selector selector = invoke is InvokeMethod ? invoke.selector : null; 459 Selector selector = invoke is InvokeMethod ? invoke.selector : null;
472 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) { 460 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) {
473 Primitive condition = _fragment.letPrim( 461 Primitive condition = _fragment.letPrim(
474 new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber, 462 new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // We cannot inline a constructor invocation containing type arguments 508 // We cannot inline a constructor invocation containing type arguments
521 // because CreateInstance in the body does not know the type arguments. 509 // because CreateInstance in the body does not know the type arguments.
522 // We would incorrectly instantiate a class like A instead of A<B>. 510 // We would incorrectly instantiate a class like A instead of A<B>.
523 // TODO(kmillikin): try to fix this. 511 // TODO(kmillikin): try to fix this.
524 GenericType generic = node.dartType; 512 GenericType generic = node.dartType;
525 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; 513 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null;
526 } 514 }
527 return tryInlining(node, node.target, null); 515 return tryInlining(node, node.target, null);
528 } 516 }
529 } 517 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698