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

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;
388 List<Primitive> arguments = 386 List<Primitive> arguments =
389 invoke.arguments.map((Reference ref) => ref.definition).toList(); 387 invoke.arguments.map((Reference ref) => ref.definition).toList();
390 // Add a null check to the inlined function body if necessary. The 388 // Add a null check to the inlined function body if necessary. The
391 // cached function body does not contain the null check. 389 // cached function body does not contain the null check.
392 if (dartReceiver != null && abstractReceiver.isNullable) { 390 if (dartReceiver != null && abstractReceiver.isNullable) {
393 Primitive check = nullReceiverGuard( 391 Primitive check = nullReceiverGuard(
394 invoke, _fragment, dartReceiver.definition, abstractReceiver); 392 invoke, _fragment, dartReceiver.definition, abstractReceiver);
395 if (invoke.callingConvention == CallingConvention.Intercepted) { 393 if (invoke.callingConvention == CallingConvention.Intercepted) {
396 arguments[0] = check; 394 arguments[0] = check;
397 } else { 395 } else {
398 receiver = check; 396 receiver = check;
399 } 397 }
400 } 398 }
401 return _fragment.inlineFunction(function, receiver, arguments, 399 return _fragment.inlineFunction(function, receiver, arguments,
402 hint: invoke.hint); 400 hint: invoke.hint);
403 } 401 }
404 402
403 // Positive inlining result in the cache.
404 if (cachedResult is FunctionDefinition) {
405 return finish(cachedResult);
406 }
407
405 // We have not seen this combination of target and abstract arguments 408 // We have not seen this combination of target and abstract arguments
406 // before. Make an inlining decision. 409 // before. Make an inlining decision.
407 assert(cachedResult == InliningCache.ABSENT); 410 assert(cachedResult == InliningCache.ABSENT);
408 Primitive doNotInline() { 411 Primitive doNotInline() {
409 _inliner.cache.putNegative(target, callStructure, abstractReceiver, 412 _inliner.cache.putNegative(target, callStructure, abstractReceiver,
410 abstractArguments); 413 abstractArguments);
411 return null; 414 return null;
412 } 415 }
413 if (backend.annotations.noInline(target)) return doNotInline(); 416 if (backend.annotations.noInline(target)) return doNotInline();
414 if (isRecursive(target, callStructure)) return doNotInline(); 417 if (isRecursive(target, callStructure)) return doNotInline();
(...skipping 23 matching lines...) Expand all
438 // Inline calls in the body. 441 // Inline calls in the body.
439 _inliner.rewrite(function, callStructure); 442 _inliner.rewrite(function, callStructure);
440 443
441 // Compute the size. 444 // Compute the size.
442 // TODO(kmillikin): Tune the size bound. 445 // TODO(kmillikin): Tune the size bound.
443 int size = SizeVisitor.sizeOf(invoke, function); 446 int size = SizeVisitor.sizeOf(invoke, function);
444 if (!_inliner.isCalledOnce(target) && size > 11) return doNotInline(); 447 if (!_inliner.isCalledOnce(target) && size > 11) return doNotInline();
445 448
446 _inliner.cache.putPositive(target, callStructure, abstractReceiver, 449 _inliner.cache.putPositive(target, callStructure, abstractReceiver,
447 abstractArguments, function); 450 abstractArguments, function);
448 _fragment = new CpsFragment(invoke.sourceInformation); 451 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 } 452 }
466 453
467 Primitive nullReceiverGuard(InvocationPrimitive invoke, 454 Primitive nullReceiverGuard(InvocationPrimitive invoke,
468 CpsFragment fragment, 455 CpsFragment fragment,
469 Primitive dartReceiver, 456 Primitive dartReceiver,
470 TypeMask abstractReceiver) { 457 TypeMask abstractReceiver) {
471 Selector selector = invoke is InvokeMethod ? invoke.selector : null; 458 Selector selector = invoke is InvokeMethod ? invoke.selector : null;
472 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) { 459 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) {
473 Primitive condition = _fragment.letPrim( 460 Primitive condition = _fragment.letPrim(
474 new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber, 461 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 507 // We cannot inline a constructor invocation containing type arguments
521 // because CreateInstance in the body does not know the type arguments. 508 // because CreateInstance in the body does not know the type arguments.
522 // We would incorrectly instantiate a class like A instead of A<B>. 509 // We would incorrectly instantiate a class like A instead of A<B>.
523 // TODO(kmillikin): try to fix this. 510 // TODO(kmillikin): try to fix this.
524 GenericType generic = node.dartType; 511 GenericType generic = node.dartType;
525 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; 512 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null;
526 } 513 }
527 return tryInlining(node, node.target, null); 514 return tryInlining(node, node.target, null);
528 } 515 }
529 } 516 }
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