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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 19250002: Support for inlining small methods (independent of they're called inside a loop or not) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of js_backend; 5 part of js_backend;
6 6
7 class JavaScriptItemCompilationContext extends ItemCompilationContext { 7 class JavaScriptItemCompilationContext extends ItemCompilationContext {
8 final Set<HInstruction> boundsChecked; 8 final Set<HInstruction> boundsChecked;
9 9
10 JavaScriptItemCompilationContext() 10 JavaScriptItemCompilationContext()
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 List<jsAst.Expression> arguments) { 115 List<jsAst.Expression> arguments) {
116 DartType type = node.typeExpression; 116 DartType type = node.typeExpression;
117 assert(type.isMalformed); 117 assert(type.isMalformed);
118 String reasons = Types.fetchReasonsFromMalformedType(type); 118 String reasons = Types.fetchReasonsFromMalformedType(type);
119 arguments.add(js.string('$type')); 119 arguments.add(js.string('$type'));
120 // TODO(johnniwinther): Handle escaping correctly. 120 // TODO(johnniwinther): Handle escaping correctly.
121 arguments.add(js.string(reasons)); 121 arguments.add(js.string(reasons));
122 } 122 }
123 } 123 }
124 124
125 /*
126 * Invariants:
127 * canInline(function) implies canInline(function, insideLoop:true)
128 * !canInline(function, insideLoop: true) implies !canInline(function)
129 */
130 class FunctionInlineCache {
131 final Map<FunctionElement, bool> canBeInlined =
132 new Map<FunctionElement, bool>();
133
134 final Map<FunctionElement, bool> canBeInlinedInsideLoop =
135 new Map<FunctionElement, bool>();
136
137 // Returns [:true:]/[:false:] if we have a cached decision.
138 // Returns [:null:] otherwise.
139 bool canInline(FunctionElement element, {bool insideLoop: false}) {
ngeoffray 2013/07/16 08:04:45 I'd drop the default value: it reads easier if all
kustermann 2013/07/16 13:27:50 Done.
140 if (insideLoop)
141 return canBeInlinedInsideLoop[element];
142 return canBeInlined[element];
ngeoffray 2013/07/16 08:04:45 nit: use return insideLoop ? ... : ...;
kustermann 2013/07/16 13:27:50 Done.
143 }
144
145 void markAsInlinable(FunctionElement element, {bool insideLoop: false}) {
ngeoffray 2013/07/16 08:04:45 ditto for insideLoop argument.
kustermann 2013/07/16 13:27:50 Done.
146 if (insideLoop) {
147 canBeInlinedInsideLoop[element] = true;
148 } else {
149 // If we can inline a function outside a loop then we should do it inside
150 // a loop as well.
151 canBeInlined[element] = true;
152 canBeInlinedInsideLoop[element] = true;
153 }
154 }
155
156 void markAsNonInlinable(FunctionElement element, {bool insideLoop: false}) {
ngeoffray 2013/07/16 08:04:45 ditto.
kustermann 2013/07/16 13:27:50 Done.
157 if (insideLoop) {
158 // If we can't inline a function inside a loop, then we should not inline
159 // it outside a loop either.
160 canBeInlined[element] = false;
161 canBeInlinedInsideLoop[element] = false;
162 } else {
163 canBeInlined[element] = false;
164 }
165 }
166 }
167
125 168
126 class JavaScriptBackend extends Backend { 169 class JavaScriptBackend extends Backend {
127 SsaBuilderTask builder; 170 SsaBuilderTask builder;
128 SsaOptimizerTask optimizer; 171 SsaOptimizerTask optimizer;
129 SsaCodeGeneratorTask generator; 172 SsaCodeGeneratorTask generator;
130 CodeEmitterTask emitter; 173 CodeEmitterTask emitter;
131 174
132 /** 175 /**
133 * The generated code as a js AST for compiled methods. 176 * The generated code as a js AST for compiled methods.
134 */ 177 */
135 Map<Element, jsAst.Expression> get generatedCode { 178 Map<Element, jsAst.Expression> get generatedCode {
136 return compiler.enqueuer.codegen.generatedCode; 179 return compiler.enqueuer.codegen.generatedCode;
137 } 180 }
138 181
139 /** 182 /**
140 * The generated code as a js AST for compiled bailout methods. 183 * The generated code as a js AST for compiled bailout methods.
141 */ 184 */
142 final Map<Element, jsAst.Expression> generatedBailoutCode = 185 final Map<Element, jsAst.Expression> generatedBailoutCode =
143 new Map<Element, jsAst.Expression>(); 186 new Map<Element, jsAst.Expression>();
144 187
145 /** 188 FunctionInlineCache inlineCache = new FunctionInlineCache();
146 * Keep track of which function elements are simple enough to be
147 * inlined in callers.
148 */
149 final Map<FunctionElement, bool> canBeInlined =
150 new Map<FunctionElement, bool>();
151 189
152 ClassElement jsInterceptorClass; 190 ClassElement jsInterceptorClass;
153 ClassElement jsStringClass; 191 ClassElement jsStringClass;
154 ClassElement jsArrayClass; 192 ClassElement jsArrayClass;
155 ClassElement jsNumberClass; 193 ClassElement jsNumberClass;
156 ClassElement jsIntClass; 194 ClassElement jsIntClass;
157 ClassElement jsDoubleClass; 195 ClassElement jsDoubleClass;
158 ClassElement jsNullClass; 196 ClassElement jsNullClass;
159 ClassElement jsBoolClass; 197 ClassElement jsBoolClass;
160 ClassElement jsUnknownClass; 198 ClassElement jsUnknownClass;
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 compiler.findInterceptor(const SourceString('setDispatchProperty')); 467 compiler.findInterceptor(const SourceString('setDispatchProperty'));
430 getNativeInterceptorMethod = 468 getNativeInterceptorMethod =
431 compiler.findInterceptor(const SourceString('getNativeInterceptor')); 469 compiler.findInterceptor(const SourceString('getNativeInterceptor'));
432 initializeDispatchPropertyMethod = 470 initializeDispatchPropertyMethod =
433 compiler.findInterceptor( 471 compiler.findInterceptor(
434 new SourceString(emitter.nameOfDispatchPropertyInitializer)); 472 new SourceString(emitter.nameOfDispatchPropertyInitializer));
435 defineNativeMethodsFinishMethod = 473 defineNativeMethodsFinishMethod =
436 compiler.findHelper(const SourceString('defineNativeMethodsFinish')); 474 compiler.findHelper(const SourceString('defineNativeMethodsFinish'));
437 475
438 // These methods are overwritten with generated versions. 476 // These methods are overwritten with generated versions.
439 canBeInlined[getInterceptorMethod] = false; 477 inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true);
440 canBeInlined[getDispatchPropertyMethod] = false; 478 inlineCache.markAsNonInlinable(getDispatchPropertyMethod, insideLoop: true);
441 canBeInlined[setDispatchPropertyMethod] = false; 479 inlineCache.markAsNonInlinable(setDispatchPropertyMethod, insideLoop: true);
442 480
443 List<ClassElement> classes = [ 481 List<ClassElement> classes = [
444 jsInterceptorClass = 482 jsInterceptorClass =
445 compiler.findInterceptor(const SourceString('Interceptor')), 483 compiler.findInterceptor(const SourceString('Interceptor')),
446 jsStringClass = compiler.findInterceptor(const SourceString('JSString')), 484 jsStringClass = compiler.findInterceptor(const SourceString('JSString')),
447 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')), 485 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')),
448 // The int class must be before the double class, because the 486 // The int class must be before the double class, because the
449 // emitter relies on this list for the order of type checks. 487 // emitter relies on this list for the order of type checks.
450 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')), 488 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')),
451 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')), 489 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')),
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 } 1480 }
1443 } 1481 }
1444 1482
1445 /// Records that [type] is used by [user.element]. 1483 /// Records that [type] is used by [user.element].
1446 class Dependency { 1484 class Dependency {
1447 final DartType type; 1485 final DartType type;
1448 final TreeElements user; 1486 final TreeElements user;
1449 1487
1450 const Dependency(this.type, this.user); 1488 const Dependency(this.type, this.user);
1451 } 1489 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698