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

Side by Side Diff: pkg/compiler/lib/src/dump_info.dart

Issue 1301903002: Record information about constants in dump info (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dump_info; 5 library dump_info;
6 6
7 import 'dart:convert' 7 import 'dart:convert'
8 show HtmlEscape, JsonEncoder, StringConversionSink, ChunkedConversionSink; 8 show HtmlEscape, JsonEncoder, StringConversionSink, ChunkedConversionSink;
9 9
10 import 'package:dart2js_info/info.dart'; 10 import 'package:dart2js_info/info.dart';
11 11
12 import 'common/tasks.dart' show 12 import 'common/tasks.dart' show
13 CompilerTask; 13 CompilerTask;
14 import 'constants/values.dart' show ConstantValue;
14 import 'compiler.dart' show 15 import 'compiler.dart' show
15 Compiler; 16 Compiler;
16 import 'diagnostics/messages.dart' show 17 import 'diagnostics/messages.dart' show
17 MessageKind; 18 MessageKind;
18 import 'diagnostics/spannable.dart' show 19 import 'diagnostics/spannable.dart' show
19 NO_LOCATION_SPANNABLE; 20 NO_LOCATION_SPANNABLE;
20 import 'elements/elements.dart'; 21 import 'elements/elements.dart';
21 import 'elements/visitor.dart'; 22 import 'elements/visitor.dart';
22 import 'types/types.dart' show 23 import 'types/types.dart' show
23 TypeMask; 24 TypeMask;
24 import 'deferred_load.dart' show 25 import 'deferred_load.dart' show
25 OutputUnit; 26 OutputUnit;
26 import 'js_backend/js_backend.dart' show 27 import 'js_backend/js_backend.dart' show
27 JavaScriptBackend; 28 JavaScriptBackend;
28 import 'js_emitter/full_emitter/emitter.dart' as full show 29 import 'js_emitter/full_emitter/emitter.dart' as full show
29 Emitter; 30 Emitter;
30 import 'js/js.dart' as jsAst; 31 import 'js/js.dart' as jsAst;
31 import 'universe/universe.dart' show 32 import 'universe/universe.dart' show
32 Selector, 33 Selector,
33 UniverseSelector; 34 UniverseSelector;
34 35
35 class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { 36 class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
36 final Compiler compiler; 37 final Compiler compiler;
37 38
38 final AllInfo result = new AllInfo(); 39 final AllInfo result = new AllInfo();
39 final Map<Element, Info> _elementToInfo = <Element, Info>{}; 40 final Map<Element, Info> _elementToInfo = <Element, Info>{};
41 final Map<ConstantValue, Info> _constantToInfo = <ConstantValue, Info>{};
40 final Map<OutputUnit, OutputUnitInfo> _outputToInfo = {}; 42 final Map<OutputUnit, OutputUnitInfo> _outputToInfo = {};
41 43
42 ElementInfoCollector(this.compiler); 44 ElementInfoCollector(this.compiler);
43 45
44 void run() => compiler.libraryLoader.libraries.forEach(visit); 46 void run() {
47 compiler.dumpInfoTask._constantToNode.forEach((constant, node) {
48 // TODO(sigmund): add dependencies on other constants
49 var size = compiler.dumpInfoTask._nodeToSize[node];
50 var code = jsAst.prettyPrint(node, compiler).getText();
51 var info = new ConstantInfo(size: size, code: code);
52 _constantToInfo[constant] = info;
53 result.constants.add(info);
54
55 });
56 compiler.libraryLoader.libraries.forEach(visit);
57 }
45 58
46 Info visit(Element e, [_]) => e.accept(this, null); 59 Info visit(Element e, [_]) => e.accept(this, null);
47 60
48 /// Whether to emit information about [element]. 61 /// Whether to emit information about [element].
49 /// 62 ///
50 /// By default we emit information for any element that contributes to the 63 /// By default we emit information for any element that contributes to the
51 /// output size. Either becuase the it is a function being emitted or inlined, 64 /// output size. Either becuase the it is a function being emitted or inlined,
52 /// or because it is an element that holds dependencies to other elements. 65 /// or because it is an element that holds dependencies to other elements.
53 bool shouldKeep(Element element) { 66 bool shouldKeep(Element element) {
54 return compiler.dumpInfoTask.selectorsFromElement.containsKey(element) || 67 return compiler.dumpInfoTask.selectorsFromElement.containsKey(element) ||
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 _unitInfoForElement(element)); 121 _unitInfoForElement(element));
109 _elementToInfo[element] = info; 122 _elementToInfo[element] = info;
110 result.typedefs.add(info); 123 result.typedefs.add(info);
111 return info; 124 return info;
112 } 125 }
113 126
114 FieldInfo visitFieldElement(FieldElement element, _) { 127 FieldInfo visitFieldElement(FieldElement element, _) {
115 TypeMask inferredType = 128 TypeMask inferredType =
116 compiler.typesTask.getGuaranteedTypeOfElement(element); 129 compiler.typesTask.getGuaranteedTypeOfElement(element);
117 // If a field has an empty inferred type it is never used. 130 // If a field has an empty inferred type it is never used.
118 if (inferredType == null || inferredType.isEmpty || element.isConst) { 131 if (inferredType == null || inferredType.isEmpty) return null;
119 return null;
120 }
121 132
122 int size = compiler.dumpInfoTask.sizeOf(element); 133 int size = compiler.dumpInfoTask.sizeOf(element);
123 String code; 134 String code = compiler.dumpInfoTask.codeOf(element);
124 StringBuffer emittedCode = compiler.dumpInfoTask.codeOf(element); 135 if (code != null) size += code.length;
Siggi Cherem (dart-lang) 2015/08/19 04:21:08 FYI - these lines related to `codeOf` were just cl
125 if (emittedCode != null) {
126 size += emittedCode.length;
127 code = emittedCode.toString();
128 }
129 136
130 FieldInfo info = new FieldInfo( 137 FieldInfo info = new FieldInfo(
131 name: element.name, 138 name: element.name,
132 // We use element.hashCode because it is globally unique and it is 139 // We use element.hashCode because it is globally unique and it is
133 // available while we are doing codegen. 140 // available while we are doing codegen.
134 coverageId: '${element.hashCode}', 141 coverageId: '${element.hashCode}',
135 type: '${element.type}', 142 type: '${element.type}',
136 inferredType: '$inferredType', 143 inferredType: '$inferredType',
137 size: size, 144 size: size,
138 code: code, 145 code: code,
139 outputUnit: _unitInfoForElement(element)); 146 outputUnit: _unitInfoForElement(element),
147 isConst: element.isConst);
140 _elementToInfo[element] = info; 148 _elementToInfo[element] = info;
149 if (element.isConst) {
150 var value = compiler.backend.constantCompilerTask
151 .getConstantValueForVariable(element);
152 if (value != null) {
153 info.initializer = _constantToInfo[value];
154 }
155 }
141 156
142 List<FunctionInfo> nestedClosures = <FunctionInfo>[]; 157 List<FunctionInfo> nestedClosures = <FunctionInfo>[];
143 for (Element closure in element.nestedClosures) { 158 for (Element closure in element.nestedClosures) {
144 Info child = this.process(closure); 159 Info child = this.process(closure);
145 if (child != null) { 160 if (child != null) {
146 ClassInfo parent = this.process(closure.enclosingElement); 161 ClassInfo parent = this.process(closure.enclosingElement);
147 if (parent != null) { 162 if (parent != null) {
148 child.name = "${parent.name}.${child.name}"; 163 child.name = "${parent.name}.${child.name}";
149 } 164 }
150 nestedClosures.add(child); 165 nestedClosures.add(child);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 ? "${element.enclosingElement.name}" 250 ? "${element.enclosingElement.name}"
236 : "${element.enclosingElement.name}.${element.name}"; 251 : "${element.enclosingElement.name}.${element.name}";
237 kind = FunctionInfo.CONSTRUCTOR_FUNCTION_KIND; 252 kind = FunctionInfo.CONSTRUCTOR_FUNCTION_KIND;
238 } 253 }
239 254
240 FunctionModifiers modifiers = new FunctionModifiers( 255 FunctionModifiers modifiers = new FunctionModifiers(
241 isStatic: element.isStatic, 256 isStatic: element.isStatic,
242 isConst: element.isConst, 257 isConst: element.isConst,
243 isFactory: element.isFactoryConstructor, 258 isFactory: element.isFactoryConstructor,
244 isExternal: element.isPatched); 259 isExternal: element.isPatched);
245 StringBuffer emittedCode = compiler.dumpInfoTask.codeOf(element); 260 String code = compiler.dumpInfoTask.codeOf(element);
246 String code = emittedCode == null ? null : '$emittedCode';
247 261
248 List<ParameterInfo> parameters = <ParameterInfo>[]; 262 List<ParameterInfo> parameters = <ParameterInfo>[];
249 if (element.hasFunctionSignature) { 263 if (element.hasFunctionSignature) {
250 FunctionSignature signature = element.functionSignature; 264 FunctionSignature signature = element.functionSignature;
251 signature.forEachParameter((parameter) { 265 signature.forEachParameter((parameter) {
252 parameters.add(new ParameterInfo( 266 parameters.add(new ParameterInfo(
253 parameter.name, 267 parameter.name,
254 '${compiler.typesTask.getGuaranteedTypeOfElement(parameter)}', 268 '${compiler.typesTask.getGuaranteedTypeOfElement(parameter)}',
255 '${parameter.node.type}')); 269 '${parameter.node.type}'));
256 }); 270 });
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 /// The size of the generated output. 354 /// The size of the generated output.
341 int _programSize; 355 int _programSize;
342 356
343 // A set of javascript AST nodes that we care about the size of. 357 // A set of javascript AST nodes that we care about the size of.
344 // This set is automatically populated when registerElementAst() 358 // This set is automatically populated when registerElementAst()
345 // is called. 359 // is called.
346 final Set<jsAst.Node> _tracking = new Set<jsAst.Node>(); 360 final Set<jsAst.Node> _tracking = new Set<jsAst.Node>();
347 // A mapping from Dart Elements to Javascript AST Nodes. 361 // A mapping from Dart Elements to Javascript AST Nodes.
348 final Map<Element, List<jsAst.Node>> _elementToNodes = 362 final Map<Element, List<jsAst.Node>> _elementToNodes =
349 <Element, List<jsAst.Node>>{}; 363 <Element, List<jsAst.Node>>{};
364 final Map<ConstantValue, jsAst.Node> _constantToNode =
365 <ConstantValue, jsAst.Node>{};
350 // A mapping from Javascript AST Nodes to the size of their 366 // A mapping from Javascript AST Nodes to the size of their
351 // pretty-printed contents. 367 // pretty-printed contents.
352 final Map<jsAst.Node, int> _nodeToSize = <jsAst.Node, int>{}; 368 final Map<jsAst.Node, int> _nodeToSize = <jsAst.Node, int>{};
353 369
354 final Map<Element, Set<UniverseSelector>> selectorsFromElement = {}; 370 final Map<Element, Set<UniverseSelector>> selectorsFromElement = {};
355 final Map<Element, int> inlineCount = <Element, int>{}; 371 final Map<Element, int> inlineCount = <Element, int>{};
356 // A mapping from an element to a list of elements that are 372 // A mapping from an element to a list of elements that are
357 // inlined inside of it. 373 // inlined inside of it.
358 final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{}; 374 final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{};
359 375
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 // dart Element `element`. 435 // dart Element `element`.
420 void registerElementAst(Element element, jsAst.Node code) { 436 void registerElementAst(Element element, jsAst.Node code) {
421 if (compiler.dumpInfo) { 437 if (compiler.dumpInfo) {
422 _elementToNodes 438 _elementToNodes
423 .putIfAbsent(element, () => new List<jsAst.Node>()) 439 .putIfAbsent(element, () => new List<jsAst.Node>())
424 .add(code); 440 .add(code);
425 _tracking.add(code); 441 _tracking.add(code);
426 } 442 }
427 } 443 }
428 444
445 void registerConstantAst(ConstantValue constant, jsAst.Node code) {
446 if (compiler.dumpInfo) {
447 assert(_constantToNode[constant] == null ||
448 _constantToNode[constant] == code);
449 _constantToNode[constant] = code;
450 _tracking.add(code);
451 }
452 }
453
429 // Records the size of a dart AST node after it has been 454 // Records the size of a dart AST node after it has been
430 // pretty-printed into the output buffer. 455 // pretty-printed into the output buffer.
431 void recordAstSize(jsAst.Node node, int size) { 456 void recordAstSize(jsAst.Node node, int size) {
432 if (isTracking(node)) { 457 if (isTracking(node)) {
433 //TODO: should I be incrementing here instead? 458 //TODO: should I be incrementing here instead?
434 _nodeToSize[node] = size; 459 _nodeToSize[node] = size;
435 } 460 }
436 } 461 }
437 462
438 // Returns the size of the source code that 463 // Returns the size of the source code that
439 // was generated for an element. If no source 464 // was generated for an element. If no source
440 // code was produced, return 0. 465 // code was produced, return 0.
441 int sizeOf(Element element) { 466 int sizeOf(Element element) {
442 if (_elementToNodes.containsKey(element)) { 467 if (_elementToNodes.containsKey(element)) {
443 return _elementToNodes[element].map(sizeOfNode).fold(0, (a, b) => a + b); 468 return _elementToNodes[element].map(sizeOfNode).fold(0, (a, b) => a + b);
444 } else { 469 } else {
445 return 0; 470 return 0;
446 } 471 }
447 } 472 }
448 473
449 int sizeOfNode(jsAst.Node node) { 474 int sizeOfNode(jsAst.Node node) => _nodeToSize[node] ?? 0;
450 if (_nodeToSize.containsKey(node)) {
451 return _nodeToSize[node];
452 } else {
453 return 0;
454 }
455 }
456 475
457 StringBuffer codeOf(Element element) { 476 String codeOf(Element element) {
458 List<jsAst.Node> code = _elementToNodes[element]; 477 List<jsAst.Node> code = _elementToNodes[element];
459 if (code == null) return null; 478 if (code == null) return null;
460 // Concatenate rendered ASTs. 479 // Concatenate rendered ASTs.
461 StringBuffer sb = new StringBuffer(); 480 StringBuffer sb = new StringBuffer();
462 for (jsAst.Node ast in code) { 481 for (jsAst.Node ast in code) {
463 sb.writeln(jsAst.prettyPrint(ast, compiler).getText()); 482 sb.writeln(jsAst.prettyPrint(ast, compiler).getText());
464 } 483 }
465 return sb; 484 return sb.toString();
466 } 485 }
467 486
468 void collectInfo() { 487 void collectInfo() {
469 infoCollector = new ElementInfoCollector(compiler)..run(); 488 infoCollector = new ElementInfoCollector(compiler)..run();
470 } 489 }
471 490
472 void dumpInfo() { 491 void dumpInfo() {
473 measure(() { 492 measure(() {
474 if (infoCollector == null) { 493 if (infoCollector == null) {
475 collectInfo(); 494 collectInfo();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 558
540 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion( 559 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion(
541 new StringConversionSink.fromStringSink(buffer)); 560 new StringConversionSink.fromStringSink(buffer));
542 sink.add(result.toJson()); 561 sink.add(result.toJson());
543 compiler.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, { 562 compiler.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, {
544 'text': "View the dumped .info.json file at " 563 'text': "View the dumped .info.json file at "
545 "https://dart-lang.github.io/dump-info-visualizer" 564 "https://dart-lang.github.io/dump-info-visualizer"
546 }); 565 });
547 } 566 }
548 } 567 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart » ('j') | pkg/compiler/pubspec.yaml » ('J')

Powered by Google App Engine
This is Rietveld 408576698