| OLD | NEW |
| 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 /// Computes measurements about sends in a function. | 5 /// Computes measurements about sends in a function. |
| 6 library compiler.src.info.send_info; | 6 library compiler.src.info.send_info; |
| 7 | 7 |
| 8 import 'package:dart2js_info/src/measurements.dart'; | 8 import 'package:dart2js_info/src/measurements.dart'; |
| 9 import 'package:dart2js_info/src/util.dart' show recursiveDiagnosticString; | 9 import 'package:dart2js_info/src/util.dart' show recursiveDiagnosticString; |
| 10 | 10 |
| 11 import '../closure.dart'; |
| 11 import '../common.dart'; | 12 import '../common.dart'; |
| 12 import '../compiler.dart' show Compiler; | 13 import '../compiler.dart' show Compiler; |
| 14 import '../constants/expressions.dart'; |
| 13 import '../dart_types.dart'; | 15 import '../dart_types.dart'; |
| 14 import '../closure.dart'; | |
| 15 import '../elements/elements.dart'; | 16 import '../elements/elements.dart'; |
| 16 import '../elements/visitor.dart' show ElementVisitor; | 17 import '../elements/visitor.dart' show ElementVisitor; |
| 18 import '../parser/partial_elements.dart' show PartialElement; |
| 17 import '../resolution/operators.dart'; | 19 import '../resolution/operators.dart'; |
| 18 import '../resolution/semantic_visitor.dart'; | 20 import '../resolution/semantic_visitor.dart'; |
| 19 import '../resolution/tree_elements.dart'; | 21 import '../resolution/tree_elements.dart'; |
| 20 import '../constants/expressions.dart'; | |
| 21 import '../parser/partial_elements.dart' show PartialElement; | |
| 22 import '../tree/tree.dart'; | 22 import '../tree/tree.dart'; |
| 23 import '../universe/call_structure.dart' show CallStructure; | 23 import '../universe/call_structure.dart' show CallStructure; |
| 24 import '../universe/selector.dart' show Selector; | 24 import '../universe/selector.dart' show Selector; |
| 25 | |
| 26 import 'analysis_result.dart'; | 25 import 'analysis_result.dart'; |
| 27 import 'naive_analysis_result.dart'; | 26 import 'naive_analysis_result.dart'; |
| 28 import 'trusted_types_analysis_result.dart'; | 27 import 'trusted_types_analysis_result.dart'; |
| 29 | 28 |
| 30 /// Collects a set of [Measurements] about send expressions in the function [f]. | 29 /// Collects a set of [Measurements] about send expressions in the function [f]. |
| 31 // TODO(sigmund): collect information on initializers too. | 30 // TODO(sigmund): collect information on initializers too. |
| 32 Measurements collectSendMeasurements(FunctionElement f, Compiler compiler) { | 31 Measurements collectSendMeasurements(FunctionElement f, Compiler compiler) { |
| 33 DiagnosticReporter reporter = compiler.reporter; | 32 DiagnosticReporter reporter = compiler.reporter; |
| 34 return reporter.withCurrentElement(f, () { | 33 return reporter.withCurrentElement(f, () { |
| 35 // TODO(sigmund): enable for platform too. | 34 // TODO(sigmund): enable for platform too. |
| 36 if (f.library.isPlatformLibrary) return null; | 35 if (f.library.isPlatformLibrary) return null; |
| 37 var name = _qualifiedName(f); | |
| 38 if (!f.hasNode) { | 36 if (!f.hasNode) { |
| 39 if (f is PartialElement) return const Measurements.unreachableFunction(); | 37 if (f is PartialElement) return const Measurements.unreachableFunction(); |
| 40 assert(f is ConstructorElement && f.isSynthesized); | 38 assert(f is ConstructorElement && f.isSynthesized); |
| 41 // TODO(sigmund): measure synthethic forwarding sends, measure | 39 // TODO(sigmund): measure synthethic forwarding sends, measure |
| 42 // initializers | 40 // initializers |
| 43 return new Measurements.reachableFunction(); | 41 return new Measurements.reachableFunction(); |
| 44 } | 42 } |
| 45 if (!f.hasResolvedAst) { | 43 if (!f.hasResolvedAst) { |
| 46 _debug('no resolved ast ${f.runtimeType}'); | 44 _debug('no resolved ast ${f.runtimeType}'); |
| 47 return null; | 45 return null; |
| 48 } | 46 } |
| 49 var resolvedAst = f.resolvedAst; | 47 var resolvedAst = f.resolvedAst; |
| 50 if (resolvedAst.node == null) { | 48 if (resolvedAst.node == null) { |
| 51 _debug('no node ${f.runtimeType}'); | 49 _debug('no node ${f.runtimeType}'); |
| 52 return null; | 50 return null; |
| 53 } | 51 } |
| 54 var def = resolvedAst.elements.getFunctionDefinition(resolvedAst.node); | 52 var def = resolvedAst.elements.getFunctionDefinition(resolvedAst.node); |
| 55 if (def == null) { | 53 if (def == null) { |
| 56 assert(f is PartialElement); | 54 assert(f is PartialElement); |
| 57 return const Measurements.unreachableFunction(); | 55 return const Measurements.unreachableFunction(); |
| 58 } | 56 } |
| 59 | 57 |
| 60 var visitor = new _StatsTraversalVisitor(compiler, resolvedAst.elements, | 58 var visitor = new _StatsTraversalVisitor(compiler, resolvedAst.elements, |
| 61 reporter.spanFromSpannable(resolvedAst.node).uri); | 59 reporter.spanFromSpannable(resolvedAst.node).uri); |
| 62 resolvedAst.node.accept(visitor); | 60 resolvedAst.node.accept(visitor); |
| 63 return visitor.measurements; | 61 return visitor.measurements; |
| 64 }); | 62 }); |
| 65 } | 63 } |
| 66 | 64 |
| 67 _qualifiedName(FunctionElement f) { | |
| 68 var cls = f.enclosingClass; | |
| 69 return (cls != null) ? '${cls.name}.${f.name}' : f.name; | |
| 70 } | |
| 71 | |
| 72 /// Visitor that categorizes data about an individual send. | 65 /// Visitor that categorizes data about an individual send. |
| 73 class _StatsVisitor<T> extends Visitor | 66 class _StatsVisitor<T> extends Visitor |
| 74 with SemanticSendResolvedMixin<dynamic, T> | 67 with SemanticSendResolvedMixin<dynamic, T> |
| 75 implements SemanticSendVisitor<dynamic, T> { | 68 implements SemanticSendVisitor<dynamic, T> { |
| 76 // TODO(sigmund): consider passing in several AnalysisResults at once, so we | 69 // TODO(sigmund): consider passing in several AnalysisResults at once, so we |
| 77 // can compute the different metrics together. | 70 // can compute the different metrics together. |
| 78 /// Information we know about the program from static analysis. | 71 /// Information we know about the program from static analysis. |
| 79 final AnalysisResult info; | 72 final AnalysisResult info; |
| 80 | 73 |
| 81 /// Results from this function. | 74 /// Results from this function. |
| (...skipping 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2356 e.forEachLocalMember((l) => l.accept(this, arg)); | 2349 e.forEachLocalMember((l) => l.accept(this, arg)); |
| 2357 return null; | 2350 return null; |
| 2358 } | 2351 } |
| 2359 | 2352 |
| 2360 @override | 2353 @override |
| 2361 R visitLibraryElement(LibraryElement e, A arg) { | 2354 R visitLibraryElement(LibraryElement e, A arg) { |
| 2362 e.implementation.compilationUnits.forEach((u) => u.accept(this, arg)); | 2355 e.implementation.compilationUnits.forEach((u) => u.accept(this, arg)); |
| 2363 return null; | 2356 return null; |
| 2364 } | 2357 } |
| 2365 | 2358 |
| 2366 @override | |
| 2367 R visitVariableElement(VariableElement e, A arg) => null; | 2359 R visitVariableElement(VariableElement e, A arg) => null; |
| 2368 | 2360 |
| 2369 @override | 2361 @override |
| 2370 R visitParameterElement(ParameterElement e, A arg) => null; | 2362 R visitParameterElement(ParameterElement e, A arg) => null; |
| 2371 | 2363 |
| 2372 @override | 2364 @override |
| 2373 R visitFormalElement(FormalElement e, A arg) => null; | 2365 R visitFormalElement(FormalElement e, A arg) => null; |
| 2374 | 2366 |
| 2375 @override | 2367 @override |
| 2376 R visitFieldElement(FieldElement e, A arg) => null; | 2368 R visitFieldElement(FieldElement e, A arg) => null; |
| 2377 | 2369 |
| 2378 @override | 2370 @override |
| 2379 R visitFieldParameterElement(InitializingFormalElement e, A arg) => null; | 2371 R visitFieldParameterElement(InitializingFormalElement e, A arg) => null; |
| 2380 | 2372 |
| 2381 @override | 2373 @override |
| 2382 R visitAbstractFieldElement(AbstractFieldElement e, A arg) => null; | 2374 R visitAbstractFieldElement(AbstractFieldElement e, A arg) => null; |
| 2383 | 2375 |
| 2384 @override | |
| 2385 R visitFunctionElement(FunctionElement e, A arg) => null; | 2376 R visitFunctionElement(FunctionElement e, A arg) => null; |
| 2386 | 2377 |
| 2387 @override | 2378 @override |
| 2388 R visitConstructorElement(ConstructorElement e, A arg) { | 2379 R visitConstructorElement(ConstructorElement e, A arg) { |
| 2389 return visitFunctionElement(e, arg); | 2380 return visitFunctionElement(e, arg); |
| 2390 } | 2381 } |
| 2391 | 2382 |
| 2392 @override | 2383 @override |
| 2393 R visitConstructorBodyElement(ConstructorBodyElement e, A arg) { | 2384 R visitConstructorBodyElement(ConstructorBodyElement e, A arg) { |
| 2394 return visitFunctionElement(e.constructor, arg); | 2385 return visitFunctionElement(e.constructor, arg); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2415 @override | 2406 @override |
| 2416 R visitClosureFieldElement(ClosureFieldElement e, A arg) { | 2407 R visitClosureFieldElement(ClosureFieldElement e, A arg) { |
| 2417 return visitVariableElement(e, arg); | 2408 return visitVariableElement(e, arg); |
| 2418 } | 2409 } |
| 2419 } | 2410 } |
| 2420 | 2411 |
| 2421 // TODO(sigmund): get rid of debug messages. | 2412 // TODO(sigmund): get rid of debug messages. |
| 2422 _debug(String message) { | 2413 _debug(String message) { |
| 2423 print('[33mdebug:[0m $message'); | 2414 print('[33mdebug:[0m $message'); |
| 2424 } | 2415 } |
| OLD | NEW |