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

Side by Side Diff: pkg/compiler/lib/src/js_backend/codegen/unsugar.dart

Issue 1238163003: dart2js cps: Share interceptors by default and propagate to use later. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Renamed to let_sinking.dart Created 5 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
OLDNEW
1 library dart2js.unsugar_cps; 1 library dart2js.unsugar_cps;
2 2
3 import '../../cps_ir/cps_ir_nodes.dart'; 3 import '../../cps_ir/cps_ir_nodes.dart';
4 4
5 import '../../cps_ir/optimizers.dart' show ParentVisitor; 5 import '../../cps_ir/optimizers.dart' show ParentVisitor;
6 import '../../constants/expressions.dart'; 6 import '../../constants/expressions.dart';
7 import '../../constants/values.dart'; 7 import '../../constants/values.dart';
8 import '../../elements/elements.dart' show 8 import '../../elements/elements.dart';
9 ClassElement,
10 FieldElement,
11 FunctionElement,
12 Local,
13 ExecutableElement;
14 import '../../js_backend/codegen/glue.dart'; 9 import '../../js_backend/codegen/glue.dart';
15 import '../../dart2jslib.dart' show Selector, World; 10 import '../../dart2jslib.dart' show Selector, World;
16 import '../../cps_ir/cps_ir_builder.dart' show ThisParameterLocal; 11 import '../../cps_ir/cps_ir_builder.dart' show ThisParameterLocal;
17 12
18 class ExplicitReceiverParameterEntity implements Local { 13 class ExplicitReceiverParameterEntity implements Local {
19 String get name => 'receiver'; 14 String get name => 'receiver';
20 final ExecutableElement executableContext; 15 final ExecutableElement executableContext;
21 ExplicitReceiverParameterEntity(this.executableContext); 16 ExplicitReceiverParameterEntity(this.executableContext);
22 toString() => 'ExplicitReceiverParameterEntity($executableContext)'; 17 toString() => 'ExplicitReceiverParameterEntity($executableContext)';
23 } 18 }
24 19
20 /// Suggested name for an interceptor.
21 class InterceptorEntity extends Entity {
22 Entity interceptedVariable;
23
24 InterceptorEntity(this.interceptedVariable);
25
26 String get name => interceptedVariable.name + '_';
27 }
28
29
25 /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts 30 /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts
26 /// special nodes that respect JavaScript behavior. 31 /// special nodes that respect JavaScript behavior.
27 /// 32 ///
28 /// Performs the following rewrites: 33 /// Performs the following rewrites:
29 /// - Rewrite [IsTrue] in a [Branch] to do boolean conversion. 34 /// - Rewrite [IsTrue] in a [Branch] to do boolean conversion.
30 /// - Add interceptors at call sites that use interceptor calling convention. 35 /// - Add interceptors at call sites that use interceptor calling convention.
31 /// - Add explicit receiver argument for methods that are called in interceptor 36 /// - Add explicit receiver argument for methods that are called in interceptor
32 /// calling convention. 37 /// calling convention.
33 /// - Convert two-parameter exception handlers to one-parameter ones. 38 /// - Convert two-parameter exception handlers to one-parameter ones.
34 class UnsugarVisitor extends RecursiveVisitor { 39 class UnsugarVisitor extends RecursiveVisitor {
35 Glue _glue; 40 Glue _glue;
36 ParentVisitor _parentVisitor = new ParentVisitor(); 41 ParentVisitor _parentVisitor = new ParentVisitor();
37 42
38 Parameter thisParameter; 43 Parameter thisParameter;
39 Parameter explicitReceiverParameter; 44 Parameter explicitReceiverParameter;
40 45
46 Map<Primitive, Interceptor> interceptors = <Primitive, Interceptor>{};
47
41 // In a catch block, rethrow implicitly throws the block's exception 48 // In a catch block, rethrow implicitly throws the block's exception
42 // parameter. This is the exception parameter when nested in a catch 49 // parameter. This is the exception parameter when nested in a catch
43 // block and null otherwise. 50 // block and null otherwise.
44 Parameter _exceptionParameter = null; 51 Parameter _exceptionParameter = null;
45 52
46 UnsugarVisitor(this._glue); 53 UnsugarVisitor(this._glue);
47 54
48 void rewrite(FunctionDefinition function) { 55 void rewrite(FunctionDefinition function) {
49 bool inInterceptedMethod = _glue.isInterceptedMethod(function.element); 56 bool inInterceptedMethod = _glue.isInterceptedMethod(function.element);
50 57
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 // Rethrow can only appear in a catch block. It throws that block's 227 // Rethrow can only appear in a catch block. It throws that block's
221 // (wrapped) caught exception. 228 // (wrapped) caught exception.
222 Throw replacement = new Throw(_exceptionParameter); 229 Throw replacement = new Throw(_exceptionParameter);
223 InteriorNode parent = node.parent; 230 InteriorNode parent = node.parent;
224 parent.body = replacement; 231 parent.body = replacement;
225 replacement.parent = parent; 232 replacement.parent = parent;
226 // The original rethrow does not have any references that we need to 233 // The original rethrow does not have any references that we need to
227 // worry about unlinking. 234 // worry about unlinking.
228 } 235 }
229 236
237 /// Returns an interceptor for the given value, capable of responding to
238 /// [selector].
239 ///
240 /// A single getInterceptor call will be created per primitive, bound
241 /// immediately after the primitive is bound.
242 ///
243 /// The type propagation pass will later narrow the set of interceptors
244 /// based on the input type, and the let sinking pass will propagate the
245 /// getInterceptor call closer to its use when this is profitable.
246 Interceptor getInterceptorFor(Primitive prim, Selector selector) {
247 Interceptor interceptor = interceptors[prim];
248 if (interceptor == null) {
249 interceptor = new Interceptor(prim);
250 interceptors[prim] = interceptor;
251 InteriorNode parent = prim.parent;
252 insertLetPrim(interceptor, parent.body);
253 if (prim.hint != null) {
254 interceptor.hint = new InterceptorEntity(prim.hint);
255 }
256 }
257 // Add the interceptor classes that can respond to the given selector.
258 interceptor.interceptedClasses.addAll(
259 _glue.getInterceptedClassesOn(selector));
260 return interceptor;
261 }
262
230 processInvokeMethod(InvokeMethod node) { 263 processInvokeMethod(InvokeMethod node) {
231 Selector selector = node.selector; 264 Selector selector = node.selector;
232 if (!_glue.isInterceptedSelector(selector)) return; 265 if (!_glue.isInterceptedSelector(selector)) return;
233 266
234 Primitive receiver = node.receiver.definition; 267 Primitive receiver = node.receiver.definition;
235 Primitive newReceiver; 268 Primitive newReceiver;
236 269
237 if (receiver == explicitReceiverParameter) { 270 if (receiver == explicitReceiverParameter) {
238 // If the receiver is the explicit receiver, we are calling a method in 271 // If the receiver is the explicit receiver, we are calling a method in
239 // the same interceptor: 272 // the same interceptor:
240 // Change 'receiver.foo()' to 'this.foo(receiver)'. 273 // Change 'receiver.foo()' to 'this.foo(receiver)'.
241 newReceiver = thisParameter; 274 newReceiver = thisParameter;
242 } else { 275 } else {
243 // TODO(sra): Move the computation of interceptedClasses to a much later 276 newReceiver = getInterceptorFor(receiver, node.selector);
244 // phase and take into account the remaining uses of the interceptor.
245 Set<ClassElement> interceptedClasses =
246 _glue.getInterceptedClassesOn(selector);
247 _glue.registerSpecializedGetInterceptor(interceptedClasses);
248 newReceiver = new Interceptor(receiver, interceptedClasses);
249 insertLetPrim(newReceiver, node);
250 } 277 }
251 278
252 node.arguments.insert(0, node.receiver); 279 node.arguments.insert(0, node.receiver);
253 node.receiver = new Reference<Primitive>(newReceiver); 280 node.receiver = new Reference<Primitive>(newReceiver);
254 } 281 }
255 282
256 processInvokeMethodDirectly(InvokeMethodDirectly node) { 283 processInvokeMethodDirectly(InvokeMethodDirectly node) {
257 if (_glue.isInterceptedMethod(node.target)) { 284 if (_glue.isInterceptedMethod(node.target)) {
258 Primitive nullPrim = nullConstant; 285 Primitive nullPrim = nullConstant;
259 insertLetPrim(nullPrim, node); 286 insertLetPrim(nullPrim, node);
(...skipping 23 matching lines...) Expand all
283 condition.value.unlink(); 310 condition.value.unlink();
284 node.trueContinuation.unlink(); 311 node.trueContinuation.unlink();
285 node.falseContinuation.unlink(); 312 node.falseContinuation.unlink();
286 parent.body = newNode; 313 parent.body = newNode;
287 } 314 }
288 315
289 processInterceptor(Interceptor node) { 316 processInterceptor(Interceptor node) {
290 _glue.registerSpecializedGetInterceptor(node.interceptedClasses); 317 _glue.registerSpecializedGetInterceptor(node.interceptedClasses);
291 } 318 }
292 } 319 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/task.dart ('k') | pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698