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

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}) {
140 return insideLoop ? canBeInlinedInsideLoop[element] : canBeInlined[element];
141 }
142
143 void markAsInlinable(FunctionElement element, {bool insideLoop}) {
144 if (insideLoop) {
145 canBeInlinedInsideLoop[element] = true;
146 } else {
147 // If we can inline a function outside a loop then we should do it inside
148 // a loop as well.
149 canBeInlined[element] = true;
150 canBeInlinedInsideLoop[element] = true;
151 }
152 }
153
154 void markAsNonInlinable(FunctionElement element, {bool insideLoop}) {
155 if (insideLoop) {
156 // If we can't inline a function inside a loop, then we should not inline
157 // it outside a loop either.
158 canBeInlined[element] = false;
159 canBeInlinedInsideLoop[element] = false;
160 } else {
161 canBeInlined[element] = false;
162 }
163 }
164 }
165
125 166
126 class JavaScriptBackend extends Backend { 167 class JavaScriptBackend extends Backend {
127 SsaBuilderTask builder; 168 SsaBuilderTask builder;
128 SsaOptimizerTask optimizer; 169 SsaOptimizerTask optimizer;
129 SsaCodeGeneratorTask generator; 170 SsaCodeGeneratorTask generator;
130 CodeEmitterTask emitter; 171 CodeEmitterTask emitter;
131 172
132 /** 173 /**
133 * The generated code as a js AST for compiled methods. 174 * The generated code as a js AST for compiled methods.
134 */ 175 */
135 Map<Element, jsAst.Expression> get generatedCode { 176 Map<Element, jsAst.Expression> get generatedCode {
136 return compiler.enqueuer.codegen.generatedCode; 177 return compiler.enqueuer.codegen.generatedCode;
137 } 178 }
138 179
139 /** 180 /**
140 * The generated code as a js AST for compiled bailout methods. 181 * The generated code as a js AST for compiled bailout methods.
141 */ 182 */
142 final Map<Element, jsAst.Expression> generatedBailoutCode = 183 final Map<Element, jsAst.Expression> generatedBailoutCode =
143 new Map<Element, jsAst.Expression>(); 184 new Map<Element, jsAst.Expression>();
144 185
145 /** 186 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 187
152 ClassElement jsInterceptorClass; 188 ClassElement jsInterceptorClass;
153 ClassElement jsStringClass; 189 ClassElement jsStringClass;
154 ClassElement jsArrayClass; 190 ClassElement jsArrayClass;
155 ClassElement jsNumberClass; 191 ClassElement jsNumberClass;
156 ClassElement jsIntClass; 192 ClassElement jsIntClass;
157 ClassElement jsDoubleClass; 193 ClassElement jsDoubleClass;
158 ClassElement jsNullClass; 194 ClassElement jsNullClass;
159 ClassElement jsBoolClass; 195 ClassElement jsBoolClass;
160 ClassElement jsUnknownClass; 196 ClassElement jsUnknownClass;
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 compiler.findInterceptor(const SourceString('setDispatchProperty')); 465 compiler.findInterceptor(const SourceString('setDispatchProperty'));
430 getNativeInterceptorMethod = 466 getNativeInterceptorMethod =
431 compiler.findInterceptor(const SourceString('getNativeInterceptor')); 467 compiler.findInterceptor(const SourceString('getNativeInterceptor'));
432 initializeDispatchPropertyMethod = 468 initializeDispatchPropertyMethod =
433 compiler.findInterceptor( 469 compiler.findInterceptor(
434 new SourceString(emitter.nameOfDispatchPropertyInitializer)); 470 new SourceString(emitter.nameOfDispatchPropertyInitializer));
435 defineNativeMethodsFinishMethod = 471 defineNativeMethodsFinishMethod =
436 compiler.findHelper(const SourceString('defineNativeMethodsFinish')); 472 compiler.findHelper(const SourceString('defineNativeMethodsFinish'));
437 473
438 // These methods are overwritten with generated versions. 474 // These methods are overwritten with generated versions.
439 canBeInlined[getInterceptorMethod] = false; 475 inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true);
440 canBeInlined[getDispatchPropertyMethod] = false; 476 inlineCache.markAsNonInlinable(getDispatchPropertyMethod, insideLoop: true);
441 canBeInlined[setDispatchPropertyMethod] = false; 477 inlineCache.markAsNonInlinable(setDispatchPropertyMethod, insideLoop: true);
442 478
443 List<ClassElement> classes = [ 479 List<ClassElement> classes = [
444 jsInterceptorClass = 480 jsInterceptorClass =
445 compiler.findInterceptor(const SourceString('Interceptor')), 481 compiler.findInterceptor(const SourceString('Interceptor')),
446 jsStringClass = compiler.findInterceptor(const SourceString('JSString')), 482 jsStringClass = compiler.findInterceptor(const SourceString('JSString')),
447 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')), 483 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')),
448 // The int class must be before the double class, because the 484 // The int class must be before the double class, because the
449 // emitter relies on this list for the order of type checks. 485 // emitter relies on this list for the order of type checks.
450 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')), 486 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')),
451 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')), 487 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')),
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 } 1478 }
1443 } 1479 }
1444 1480
1445 /// Records that [type] is used by [user.element]. 1481 /// Records that [type] is used by [user.element].
1446 class Dependency { 1482 class Dependency {
1447 final DartType type; 1483 final DartType type;
1448 final TreeElements user; 1484 final TreeElements user;
1449 1485
1450 const Dependency(this.type, this.user); 1486 const Dependency(this.type, this.user);
1451 } 1487 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698