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

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

Issue 1554083002: dart2js: Do not inline when try is seen. (Closed) Base URL: git@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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 final List<StackEntry> stack = <StackEntry>[]; 159 final List<StackEntry> stack = <StackEntry>[];
160 160
161 Inliner(this.functionCompiler); 161 Inliner(this.functionCompiler);
162 162
163 bool isCalledOnce(Element element) { 163 bool isCalledOnce(Element element) {
164 return functionCompiler.compiler.typesTask.typesInferrer.isCalledOnce( 164 return functionCompiler.compiler.typesTask.typesInferrer.isCalledOnce(
165 element); 165 element);
166 } 166 }
167 167
168 void rewrite(FunctionDefinition node, [CallStructure callStructure]) { 168 void rewrite(FunctionDefinition node, [CallStructure callStructure]) {
169 Element function = node.element; 169 ExecutableElement function = node.element;
170 170
171 // Inlining in asynchronous or generator functions is disabled. Inlining 171 // Inlining in asynchronous or generator functions is disabled. Inlining
172 // triggers a bug in the async rewriter. 172 // triggers a bug in the async rewriter.
173 // TODO(kmillikin): Fix the bug and eliminate this restriction if it makes 173 // TODO(kmillikin): Fix the bug and eliminate this restriction if it makes
174 // sense. 174 // sense.
175 if (function is FunctionElement && 175 if (function is FunctionElement &&
176 function.asyncMarker != AsyncMarker.SYNC) { 176 function.asyncMarker != AsyncMarker.SYNC) {
177 return; 177 return;
178 } 178 }
179 179
180 // Do not inline in functions containing try statements. V8 does not
181 // optimize code in such functions, so inlining will move optimizable code
182 // into a context where it cannot be optimized.
183 if (function.resolvedAst.elements.containsTryStatement) {
184 return;
185 }
186
180 stack.add(new StackEntry(function, callStructure)); 187 stack.add(new StackEntry(function, callStructure));
181 new InliningVisitor(this).visit(node); 188 new InliningVisitor(this).visit(node);
182 assert(stack.last.match(function, callStructure)); 189 assert(stack.last.match(function, callStructure));
183 stack.removeLast(); 190 stack.removeLast();
184 new ShrinkingReducer().rewrite(node); 191 new ShrinkingReducer().rewrite(node);
185 } 192 }
186 } 193 }
187 194
188 /// Compute an abstract size of an IR function definition. 195 /// Compute an abstract size of an IR function definition.
189 /// 196 ///
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 // 353 //
347 // An optional call structure indicates a dynamic call. Calls that are 354 // An optional call structure indicates a dynamic call. Calls that are
348 // already resolved statically have a null call structure. 355 // already resolved statically have a null call structure.
349 // 356 //
350 // The [Primitive] representing the result of the inlined call is returned 357 // The [Primitive] representing the result of the inlined call is returned
351 // if the call was inlined, and the inlined function body is available in 358 // if the call was inlined, and the inlined function body is available in
352 // [_fragment]. If the call was not inlined, null is returned. 359 // [_fragment]. If the call was not inlined, null is returned.
353 Primitive tryInlining(InvocationPrimitive invoke, FunctionElement target, 360 Primitive tryInlining(InvocationPrimitive invoke, FunctionElement target,
354 CallStructure callStructure) { 361 CallStructure callStructure) {
355 // Quick checks: do not inline or even cache calls to targets without an 362 // Quick checks: do not inline or even cache calls to targets without an
356 // AST node or targets that are asynchronous or generator functions. 363 // AST node, targets that are asynchronous or generator functions, or
364 // targets containing a try statement.
357 if (!target.hasNode) return null; 365 if (!target.hasNode) return null;
358 if (target.asyncMarker != AsyncMarker.SYNC) return null; 366 if (target.asyncMarker != AsyncMarker.SYNC) return null;
367 // V8 does not optimize functions containing a try statement. Inlining
368 // code containing a try statement will make the optimizable calling code
369 // become unoptimizable.
370 if (target.resolvedAst.elements.containsTryStatement) {
371 return null;
372 }
359 373
360 Reference<Primitive> dartReceiver = invoke.dartReceiverReference; 374 Reference<Primitive> dartReceiver = invoke.dartReceiverReference;
361 TypeMask abstractReceiver = 375 TypeMask abstractReceiver =
362 dartReceiver == null ? null : abstractType(dartReceiver); 376 dartReceiver == null ? null : abstractType(dartReceiver);
363 List<TypeMask> abstractArguments = 377 List<TypeMask> abstractArguments =
364 invoke.arguments.map(abstractType).toList(); 378 invoke.arguments.map(abstractType).toList();
365 var cachedResult = _inliner.cache.get(target, callStructure, 379 var cachedResult = _inliner.cache.get(target, callStructure,
366 abstractReceiver, 380 abstractReceiver,
367 abstractArguments); 381 abstractArguments);
368 382
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 // We cannot inline a constructor invocation containing type arguments 523 // We cannot inline a constructor invocation containing type arguments
510 // because CreateInstance in the body does not know the type arguments. 524 // because CreateInstance in the body does not know the type arguments.
511 // We would incorrectly instantiate a class like A instead of A<B>. 525 // We would incorrectly instantiate a class like A instead of A<B>.
512 // TODO(kmillikin): try to fix this. 526 // TODO(kmillikin): try to fix this.
513 GenericType generic = node.dartType; 527 GenericType generic = node.dartType;
514 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; 528 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null;
515 } 529 }
516 return tryInlining(node, node.target, null); 530 return tryInlining(node, node.target, null);
517 } 531 }
518 } 532 }
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