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

Side by Side Diff: pkg/compiler/lib/src/ssa/kernel_impact.dart

Issue 2456643006: More functionality in kernel_impact. (Closed)
Patch Set: Fix errors. Created 4 years, 1 month 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 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/names.dart'; 8 import '../common/names.dart';
9 import '../compiler.dart'; 9 import '../compiler.dart';
10 import '../constants/expressions.dart'; 10 import '../constants/expressions.dart';
11 import '../dart_types.dart'; 11 import '../dart_types.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../js_backend/backend.dart' show JavaScriptBackend; 13 import '../js_backend/backend.dart' show JavaScriptBackend;
14 import '../kernel/kernel.dart'; 14 import '../kernel/kernel.dart';
15 import '../kernel/kernel_debug.dart'; 15 import '../kernel/kernel_debug.dart';
16 import '../kernel/kernel_visitor.dart'; 16 import '../kernel/kernel_visitor.dart';
17 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder; 17 import '../resolution/registry.dart' show ResolutionWorldImpactBuilder;
18 import '../universe/call_structure.dart'; 18 import '../universe/call_structure.dart';
19 import '../universe/feature.dart'; 19 import '../universe/feature.dart';
20 import '../universe/selector.dart'; 20 import '../universe/selector.dart';
21 import '../universe/use.dart'; 21 import '../universe/use.dart';
22 22
23 import 'kernel_ast_adapter.dart'; 23 import 'kernel_ast_adapter.dart';
24 import '../common/resolution.dart'; 24 import '../common/resolution.dart';
25 25
26 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel. 26 /// Computes the [ResolutionImpact] for [resolvedAst] through kernel.
27 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) { 27 ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) {
28 AstElement element = resolvedAst.element; 28 AstElement element = resolvedAst.element;
29 JavaScriptBackend backend = compiler.backend; 29 return compiler.reporter.withCurrentElement(element.implementation, () {
30 Kernel kernel = backend.kernelTask.kernel; 30 JavaScriptBackend backend = compiler.backend;
31 KernelImpactBuilder builder = 31 Kernel kernel = backend.kernelTask.kernel;
32 new KernelImpactBuilder(resolvedAst, compiler, kernel); 32 KernelImpactBuilder builder =
33 if (element.isFunction || 33 new KernelImpactBuilder(resolvedAst, compiler, kernel);
34 element.isGetter || 34 if (element.isFunction ||
35 element.isSetter || 35 element.isGetter ||
36 element.isFactoryConstructor) { 36 element.isSetter ||
37 ir.Procedure function = kernel.functions[element]; 37 element.isFactoryConstructor) {
38 if (function == null) { 38 ir.Procedure function = kernel.functions[element];
39 throw "FOUND NULL FUNCTION: $element"; 39 if (function == null) {
40 throw "FOUND NULL FUNCTION: $element";
41 } else {
42 return builder.buildProcedure(function);
43 }
44 } else if (element.isGenerativeConstructor) {
45 ir.Constructor constructor = kernel.functions[element];
46 if (constructor == null) {
47 throw "FOUND NULL CONSTRUCTOR: $element";
48 } else {
49 return builder.buildConstructor(constructor);
50 }
51 } else if (element.isField) {
52 ir.Field field = kernel.fields[element];
53 if (field == null) {
54 throw "FOUND NULL FIELD: $element";
55 } else {
56 return builder.buildField(field);
57 }
40 } else { 58 } else {
41 return builder.buildProcedure(function); 59 throw new UnsupportedError("Unsupported element: $element");
42 } 60 }
43 } else if (element.isGenerativeConstructor) { 61 });
44 ir.Constructor constructor = kernel.functions[element];
45 if (constructor == null) {
46 throw "FOUND NULL CONSTRUCTOR: $element";
47 } else {
48 return builder.buildConstructor(constructor);
49 }
50 } else if (element.isField) {
51 ir.Field field = kernel.fields[element];
52 if (field == null) {
53 throw "FOUND NULL FIELD: $element";
54 } else {
55 return builder.buildField(field);
56 }
57 } else {
58 throw new UnsupportedError("Unsupported element: $element");
59 }
60 } 62 }
61 63
62 class KernelImpactBuilder extends ir.Visitor { 64 class KernelImpactBuilder extends ir.Visitor {
63 final ResolvedAst resolvedAst; 65 final ResolvedAst resolvedAst;
64 final Compiler compiler; 66 final Compiler compiler;
65 67
66 JavaScriptBackend get backend => compiler.backend; 68 JavaScriptBackend get backend => compiler.backend;
67 69
68 ResolutionWorldImpactBuilder impactBuilder; 70 ResolutionWorldImpactBuilder impactBuilder;
69 KernelAstAdapter astAdapter; 71 KernelAstAdapter astAdapter;
(...skipping 28 matching lines...) Expand all
98 checkType(node.returnType); 100 checkType(node.returnType);
99 } 101 }
100 node.positionalParameters.forEach(handleParameter); 102 node.positionalParameters.forEach(handleParameter);
101 node.namedParameters.forEach(handleParameter); 103 node.namedParameters.forEach(handleParameter);
102 } 104 }
103 105
104 ResolutionImpact buildField(ir.Field field) { 106 ResolutionImpact buildField(ir.Field field) {
105 checkType(field.type); 107 checkType(field.type);
106 if (field.initializer != null) { 108 if (field.initializer != null) {
107 visitNode(field.initializer); 109 visitNode(field.initializer);
108 if (!field.isConst) { 110 if (!field.isInstanceMember && !field.isConst) {
109 impactBuilder.registerFeature(Feature.LAZY_FIELD); 111 impactBuilder.registerFeature(Feature.LAZY_FIELD);
110 } 112 }
111 } else { 113 } else {
112 impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER); 114 impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER);
113 } 115 }
114 return impactBuilder; 116 return impactBuilder;
115 } 117 }
116 118
117 ResolutionImpact buildConstructor(ir.Constructor constructor) { 119 ResolutionImpact buildConstructor(ir.Constructor constructor) {
118 handleSignature(constructor.function, checkReturnType: false); 120 handleSignature(constructor.function, checkReturnType: false);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 // main() { 286 // main() {
285 // print(new A<int>.regular() is B<int>); 287 // print(new A<int>.regular() is B<int>);
286 // print(new A<String>.redirect() is B<String>); 288 // print(new A<String>.redirect() is B<String>);
287 // } 289 // }
288 // 290 //
289 // To track that B is actually instantiated as B<int> and B<String> we 291 // To track that B is actually instantiated as B<int> and B<String> we
290 // need to follow the type arguments passed to A.regular and A.redirect 292 // need to follow the type arguments passed to A.regular and A.redirect
291 // to B. Currently, we only do this soundly if we register A<int> and 293 // to B. Currently, we only do this soundly if we register A<int> and
292 // A<String> as instantiated. We should instead register that A.T is 294 // A<String> as instantiated. We should instead register that A.T is
293 // instantiated as int and String. 295 // instantiated as int and String.
294 handleNew(node, node.target); 296 handleNew(node, node.target, isConst: node.isConst);
295 } else { 297 } else {
296 _visitArguments(node.arguments); 298 _visitArguments(node.arguments);
297 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( 299 impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
298 target, astAdapter.getCallStructure(node.arguments))); 300 target, astAdapter.getCallStructure(node.arguments)));
299 } 301 }
300 } 302 }
301 303
302 @override 304 @override
303 void visitStaticGet(ir.StaticGet node) { 305 void visitStaticGet(ir.StaticGet node) {
304 ir.Member target = node.target; 306 ir.Member target = node.target;
305 Element element = astAdapter.getElement(target).declaration; 307 Element element = astAdapter.getElement(target).declaration;
306 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { 308 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) {
307 impactBuilder.registerStaticUse(new StaticUse.staticTearOff(element)); 309 impactBuilder.registerStaticUse(new StaticUse.staticTearOff(element));
308 } else { 310 } else {
309 impactBuilder.registerStaticUse(new StaticUse.staticGet(element)); 311 impactBuilder.registerStaticUse(new StaticUse.staticGet(element));
310 } 312 }
311 } 313 }
312 314
313 @override 315 @override
314 void visitStaticSet(ir.StaticSet node) { 316 void visitStaticSet(ir.StaticSet node) {
315 visitNode(node.value); 317 visitNode(node.value);
316 Element element = astAdapter.getElement(node.target).declaration; 318 Element element = astAdapter.getElement(node.target).declaration;
317 impactBuilder.registerStaticUse(new StaticUse.staticSet(element)); 319 impactBuilder.registerStaticUse(new StaticUse.staticSet(element));
318 } 320 }
319 321
322 void handleSuperInvocation(ir.Node target, ir.Node arguments) {
323 Element element = astAdapter.getElement(target).declaration;
324 _visitArguments(arguments);
325 impactBuilder.registerStaticUse(new StaticUse.superInvoke(
326 element, astAdapter.getCallStructure(arguments)));
327 }
328
329 @override
330 void visitDirectMethodInvocation(ir.DirectMethodInvocation node) {
331 handleSuperInvocation(node.target, node.arguments);
332 }
333
334 @override
335 void visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
336 // TODO(johnniwinther): Should we support this or always use the
337 // [MixinFullResolution] transformer?
338 handleSuperInvocation(node.interfaceTarget, node.arguments);
339 }
340
341 void handleSuperGet(ir.Member target) {
342 Element element = astAdapter.getElement(target).declaration;
343 if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) {
344 impactBuilder.registerStaticUse(new StaticUse.superTearOff(element));
345 } else {
346 impactBuilder.registerStaticUse(new StaticUse.superGet(element));
347 }
348 }
349
350 @override
351 void visitDirectGet(ir.StaticGet node) {
352 handleSuperGet(node.target);
353 }
354
355 @override
356 void visitSuperPropertyGet(ir.SuperPropertyGet node) {
357 handleSuperGet(node.interfaceTarget);
358 }
359
360 void handleSuperSet(ir.Node target, ir.Node value) {
361 visitNode(value);
362 Element element = astAdapter.getElement(target).declaration;
363 if (target is ir.Field) {
364 impactBuilder.registerStaticUse(new StaticUse.superFieldSet(element));
365 } else {
366 impactBuilder.registerStaticUse(new StaticUse.superSetterSet(element));
367 }
368 }
369
370 @override
371 void visitDirectPropertySet(ir.DirectPropertySet node) {
372 handleSuperSet(node.target, node.value);
373 }
374
375 @override
376 void visitSuperPropertySet(ir.SuperPropertySet node) {
377 handleSuperSet(node.interfaceTarget, node.value);
378 }
379
320 @override 380 @override
321 void visitMethodInvocation(ir.MethodInvocation invocation) { 381 void visitMethodInvocation(ir.MethodInvocation invocation) {
322 var receiver = invocation.receiver; 382 var receiver = invocation.receiver;
323 if (receiver is ir.VariableGet && 383 if (receiver is ir.VariableGet &&
324 receiver.variable.isFinal && 384 receiver.variable.isFinal &&
325 receiver.variable.parent is ir.FunctionDeclaration) { 385 receiver.variable.parent is ir.FunctionDeclaration) {
326 // Invocation of a local function. No need for dynamic use. 386 // Invocation of a local function. No need for dynamic use.
327 } else { 387 } else {
328 visitNode(invocation.receiver); 388 visitNode(invocation.receiver);
329 impactBuilder.registerDynamicUse( 389 impactBuilder.registerDynamicUse(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 visitNode(node.initializer); 445 visitNode(node.initializer);
386 } else { 446 } else {
387 impactBuilder.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER); 447 impactBuilder.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER);
388 } 448 }
389 } 449 }
390 450
391 @override 451 @override
392 void visitIsExpression(ir.IsExpression node) { 452 void visitIsExpression(ir.IsExpression node) {
393 impactBuilder.registerTypeUse( 453 impactBuilder.registerTypeUse(
394 new TypeUse.isCheck(astAdapter.getDartType(node.type))); 454 new TypeUse.isCheck(astAdapter.getDartType(node.type)));
455 visitNode(node.operand);
395 } 456 }
396 457
397 @override 458 @override
398 void visitAsExpression(ir.AsExpression node) { 459 void visitAsExpression(ir.AsExpression node) {
399 impactBuilder 460 impactBuilder
400 .registerTypeUse(new TypeUse.asCast(astAdapter.getDartType(node.type))); 461 .registerTypeUse(new TypeUse.asCast(astAdapter.getDartType(node.type)));
462 visitNode(node.operand);
401 } 463 }
402 464
403 @override 465 @override
404 void visitThrow(ir.Throw node) { 466 void visitThrow(ir.Throw node) {
405 impactBuilder.registerFeature(Feature.THROW_EXPRESSION); 467 impactBuilder.registerFeature(Feature.THROW_EXPRESSION);
406 visitNode(node.expression); 468 visitNode(node.expression);
407 } 469 }
408 470
409 @override 471 @override
410 void visitForInStatement(ir.ForInStatement node) { 472 void visitForInStatement(ir.ForInStatement node) {
(...skipping 30 matching lines...) Expand all
441 } 503 }
442 visitNode(node.body); 504 visitNode(node.body);
443 } 505 }
444 506
445 @override 507 @override
446 void visitTryFinally(ir.TryFinally node) { 508 void visitTryFinally(ir.TryFinally node) {
447 visitNode(node.body); 509 visitNode(node.body);
448 visitNode(node.finalizer); 510 visitNode(node.finalizer);
449 } 511 }
450 512
513 @override
514 void visitTypeLiteral(ir.TypeLiteral node) {
515 impactBuilder.registerTypeUse(
516 new TypeUse.typeLiteral(astAdapter.getDartType(node.type)));
517 }
518
519 @override
520 void visitFieldInitializer(ir.FieldInitializer node) {
521 impactBuilder.registerStaticUse(
522 new StaticUse.fieldInit(astAdapter.getElement(node.field)));
523 visitNode(node.value);
524 }
525
526 @override
527 void visitRedirectingInitializer(ir.RedirectingInitializer node) {
528 _visitArguments(node.arguments);
529 Element target = astAdapter.getElement(node.target).declaration;
530 impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke(
531 target, astAdapter.getCallStructure(node.arguments)));
532 }
533
451 // TODO(johnniwinther): Make this throw and visit child nodes explicitly 534 // TODO(johnniwinther): Make this throw and visit child nodes explicitly
452 // instead to ensure that we don't visit unwanted parts of the ir. 535 // instead to ensure that we don't visit unwanted parts of the ir.
453 @override 536 @override
454 void defaultNode(ir.Node node) => node.visitChildren(this); 537 void defaultNode(ir.Node node) => node.visitChildren(this);
455 } 538 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart ('k') | tests/compiler/dart2js/kernel/impact_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698