| Index: pkg/compiler/lib/src/cps_ir/inline.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/inline.dart b/pkg/compiler/lib/src/cps_ir/inline.dart
|
| index 076e809581579b6345116c7330d78b097dad0e82..cbb673dfe95a055ccd552111c7020af3f9e59048 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/inline.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/inline.dart
|
| @@ -14,8 +14,8 @@ import '../world.dart' show World;
|
| import '../elements/elements.dart';
|
| import '../js_backend/js_backend.dart' show JavaScriptBackend;
|
| import '../js_backend/codegen/task.dart' show CpsFunctionCompiler;
|
| -import '../types/types.dart' show
|
| - FlatTypeMask, ForwardingTypeMask, TypeMask, UnionTypeMask;
|
| +import '../types/types.dart'
|
| + show FlatTypeMask, ForwardingTypeMask, TypeMask, UnionTypeMask;
|
| import '../universe/call_structure.dart' show CallStructure;
|
| import '../universe/selector.dart' show Selector;
|
| import 'package:js_ast/js_ast.dart' as js;
|
| @@ -62,7 +62,7 @@ class CacheEntry {
|
| if (callStructure == null) {
|
| if (otherCallStructure != null) return false;
|
| } else if (otherCallStructure == null ||
|
| - !callStructure.match(otherCallStructure)) {
|
| + !callStructure.match(otherCallStructure)) {
|
| return false;
|
| }
|
|
|
| @@ -97,20 +97,23 @@ class InliningCache {
|
| // copied because the compiler passes will mutate them.
|
| final CopyingVisitor copier = new CopyingVisitor();
|
|
|
| - void _putInternal(ExecutableElement element, CallStructure callStructure,
|
| + void _putInternal(
|
| + ExecutableElement element,
|
| + CallStructure callStructure,
|
| TypeMask receiver,
|
| List<TypeMask> arguments,
|
| bool decision,
|
| FunctionDefinition function) {
|
| - map.putIfAbsent(element, () => <CacheEntry>[])
|
| - .add(new CacheEntry(callStructure, receiver, arguments, decision,
|
| - function));
|
| + map.putIfAbsent(element, () => <CacheEntry>[]).add(
|
| + new CacheEntry(callStructure, receiver, arguments, decision, function));
|
| }
|
|
|
| /// Put a positive inlining decision in the cache.
|
| ///
|
| /// A positive inlining decision maps to an IR function definition.
|
| - void putPositive(ExecutableElement element, CallStructure callStructure,
|
| + void putPositive(
|
| + ExecutableElement element,
|
| + CallStructure callStructure,
|
| TypeMask receiver,
|
| List<TypeMask> arguments,
|
| FunctionDefinition function) {
|
| @@ -119,10 +122,8 @@ class InliningCache {
|
| }
|
|
|
| /// Put a negative inlining decision in the cache.
|
| - void putNegative(ExecutableElement element,
|
| - CallStructure callStructure,
|
| - TypeMask receiver,
|
| - List<TypeMask> arguments) {
|
| + void putNegative(ExecutableElement element, CallStructure callStructure,
|
| + TypeMask receiver, List<TypeMask> arguments) {
|
| _putInternal(element, callStructure, receiver, arguments, false, null);
|
| }
|
|
|
| @@ -188,10 +189,11 @@ class Inliner implements Pass {
|
| if (element is ConstructorBodyElement) {
|
| ClassElement class_ = element.enclosingClass;
|
| return !functionCompiler.compiler.world.hasAnyStrictSubclass(class_) &&
|
| - class_.constructors.tail?.isEmpty ?? false;
|
| + class_.constructors.tail?.isEmpty ??
|
| + false;
|
| }
|
| - return functionCompiler.compiler.typesTask.typesInferrer.isCalledOnce(
|
| - element);
|
| + return functionCompiler.compiler.typesTask.typesInferrer
|
| + .isCalledOnce(element);
|
| }
|
|
|
| void rewrite(FunctionDefinition node, [CallStructure callStructure]) {
|
| @@ -344,25 +346,21 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| /// function that takes optional arguments not passed at the call site.
|
| FunctionDefinition buildAdapter(InvokeMethod node, FunctionElement target) {
|
| Parameter thisParameter = new Parameter(new ThisParameterLocal(target))
|
| - ..type = node.receiver.type;
|
| - Parameter interceptorParameter = node.interceptorRef != null
|
| - ? new Parameter(null)
|
| - : null;
|
| - List<Parameter> parameters = new List<Parameter>.generate(
|
| - node.argumentRefs.length,
|
| - (int index) {
|
| - // TODO(kmillikin): Use a hint for the parameter names.
|
| - return new Parameter(null)
|
| - ..type = node.argument(index).type;
|
| - });
|
| + ..type = node.receiver.type;
|
| + Parameter interceptorParameter =
|
| + node.interceptorRef != null ? new Parameter(null) : null;
|
| + List<Parameter> parameters =
|
| + new List<Parameter>.generate(node.argumentRefs.length, (int index) {
|
| + // TODO(kmillikin): Use a hint for the parameter names.
|
| + return new Parameter(null)..type = node.argument(index).type;
|
| + });
|
| Continuation returnContinuation = new Continuation.retrn();
|
| CpsFragment cps = new CpsFragment();
|
|
|
| FunctionSignature signature = target.functionSignature;
|
| int requiredParameterCount = signature.requiredParameterCount;
|
| List<Primitive> arguments = new List<Primitive>.generate(
|
| - requiredParameterCount,
|
| - (int index) => parameters[index]);
|
| + requiredParameterCount, (int index) => parameters[index]);
|
|
|
| int parameterIndex = requiredParameterCount;
|
| CallStructure newCallStructure;
|
| @@ -400,21 +398,17 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| newCallStructure = new CallStructure(signature.parameterCount);
|
| }
|
|
|
| - Selector newSelector =
|
| - new Selector(node.selector.kind, node.selector.memberName,
|
| - newCallStructure);
|
| - Primitive result = cps.invokeMethod(thisParameter,
|
| - newSelector,
|
| - node.mask,
|
| - arguments,
|
| + Selector newSelector = new Selector(
|
| + node.selector.kind, node.selector.memberName, newCallStructure);
|
| + Primitive result = cps.invokeMethod(
|
| + thisParameter, newSelector, node.mask, arguments,
|
| interceptor: interceptorParameter,
|
| callingConvention: node.callingConvention);
|
| result.type = typeSystem.getInvokeReturnType(node.selector, node.mask);
|
| returnContinuation.parameters.single.type = result.type;
|
| cps.invokeContinuation(returnContinuation, <Primitive>[result]);
|
| - return new FunctionDefinition(target, thisParameter, parameters,
|
| - returnContinuation,
|
| - cps.root,
|
| + return new FunctionDefinition(
|
| + target, thisParameter, parameters, returnContinuation, cps.root,
|
| interceptorParameter: interceptorParameter);
|
| }
|
|
|
| @@ -427,7 +421,7 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| // if the call was inlined, and the inlined function body is available in
|
| // [_fragment]. If the call was not inlined, null is returned.
|
| Primitive tryInlining(InvocationPrimitive invoke, FunctionElement target,
|
| - CallStructure callStructure) {
|
| + CallStructure callStructure) {
|
| // Quick checks: do not inline or even cache calls to targets without an
|
| // AST node, targets that are asynchronous or generator functions, or
|
| // targets containing a try statement.
|
| @@ -468,9 +462,8 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| : abstractReceiver.nonNullable();
|
| List<TypeMask> abstractArguments =
|
| invoke.arguments.map(abstractType).toList();
|
| - var cachedResult = _inliner.cache.get(target, callStructure,
|
| - abstractReceiverInMethod,
|
| - abstractArguments);
|
| + var cachedResult = _inliner.cache.get(
|
| + target, callStructure, abstractReceiverInMethod, abstractArguments);
|
|
|
| // Negative inlining result in the cache.
|
| if (cachedResult == InliningCache.NO_INLINE) return null;
|
| @@ -482,11 +475,11 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| // Add a null check to the inlined function body if necessary. The
|
| // cached function body does not contain the null check.
|
| if (receiver != null && abstractReceiver.isNullable) {
|
| - receiver = nullReceiverGuard(
|
| - invoke, _fragment, receiver, abstractReceiver);
|
| + receiver =
|
| + nullReceiverGuard(invoke, _fragment, receiver, abstractReceiver);
|
| }
|
| return _fragment.inlineFunction(function, receiver, arguments,
|
| - interceptor: invoke.interceptor, hint: invoke.hint);
|
| + interceptor: invoke.interceptor, hint: invoke.hint);
|
| }
|
|
|
| // Positive inlining result in the cache.
|
| @@ -542,35 +535,30 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| return finish(function);
|
| }
|
|
|
| - Primitive nullReceiverGuard(InvocationPrimitive invoke,
|
| - CpsFragment fragment,
|
| - Primitive dartReceiver,
|
| - TypeMask abstractReceiver) {
|
| + Primitive nullReceiverGuard(InvocationPrimitive invoke, CpsFragment fragment,
|
| + Primitive dartReceiver, TypeMask abstractReceiver) {
|
| if (invoke is! InvokeMethod) return dartReceiver;
|
| InvokeMethod invokeMethod = invoke;
|
| Selector selector = invokeMethod.selector;
|
| if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) {
|
| - Primitive condition = _fragment.letPrim(
|
| - new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber,
|
| - <Primitive>[dartReceiver],
|
| - invoke.sourceInformation));
|
| + Primitive condition = _fragment.letPrim(new ApplyBuiltinOperator(
|
| + BuiltinOperator.IsNotNumber,
|
| + <Primitive>[dartReceiver],
|
| + invoke.sourceInformation));
|
| condition.type = typeSystem.boolType;
|
| - Primitive check = _fragment.letPrim(
|
| - new ReceiverCheck.nullCheck(dartReceiver, selector,
|
| - invoke.sourceInformation,
|
| - condition: condition));
|
| + Primitive check = _fragment.letPrim(new ReceiverCheck.nullCheck(
|
| + dartReceiver, selector, invoke.sourceInformation,
|
| + condition: condition));
|
| check.type = abstractReceiver.nonNullable();
|
| return check;
|
| }
|
|
|
| - Primitive check = _fragment.letPrim(
|
| - new ReceiverCheck.nullCheck(dartReceiver, selector,
|
| - invoke.sourceInformation));
|
| + Primitive check = _fragment.letPrim(new ReceiverCheck.nullCheck(
|
| + dartReceiver, selector, invoke.sourceInformation));
|
| check.type = abstractReceiver.nonNullable();
|
| return check;
|
| }
|
|
|
| -
|
| @override
|
| Primitive visitInvokeStatic(InvokeStatic node) {
|
| return tryInlining(node, node.target, null);
|
| @@ -585,8 +573,8 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| if (node.selector.isSetter != element.isSetter) return null;
|
| if (node.selector.name != element.name) return null;
|
|
|
| - return tryInlining(node, element.asFunctionElement(),
|
| - node.selector.callStructure);
|
| + return tryInlining(
|
| + node, element.asFunctionElement(), node.selector.callStructure);
|
| }
|
|
|
| @override
|
| @@ -613,8 +601,8 @@ class InliningVisitor extends TrampolineRecursiveVisitor {
|
| ClassElement enclosingClass = target.enclosingClass;
|
| if (target.isOperator &&
|
| (enclosingClass == backend.helpers.jsNumberClass ||
|
| - enclosingClass == backend.helpers.jsDoubleClass ||
|
| - enclosingClass == backend.helpers.jsIntClass)) {
|
| + enclosingClass == backend.helpers.jsDoubleClass ||
|
| + enclosingClass == backend.helpers.jsIntClass)) {
|
| // These should be handled by operator specialization.
|
| return true;
|
| }
|
|
|