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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dump_info.dart

Issue 430913002: Better dependency tracking (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix self critiques Created 6 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 | Annotate | Revision Log
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' show 7 import 'dart:convert' show
8 HtmlEscape, 8 HtmlEscape,
9 JsonEncoder, 9 JsonEncoder,
10 StringConversionSink, 10 StringConversionSink,
11 ChunkedConversionSink; 11 ChunkedConversionSink;
12 12
13 import 'elements/elements.dart'; 13 import 'elements/elements.dart';
14 import 'elements/visitor.dart'; 14 import 'elements/visitor.dart';
15 import 'dart2jslib.dart' show 15 import 'dart2jslib.dart' show
16 Compiler, 16 Compiler,
17 CompilerTask, 17 CompilerTask,
18 CodeBuffer; 18 CodeBuffer;
19 import 'dart_types.dart' show DartType; 19 import 'dart_types.dart' show DartType;
20 import 'types/types.dart' show TypeMask; 20 import 'types/types.dart' show TypeMask;
21 import 'util/util.dart' show modifiersToString; 21 import 'util/util.dart' show modifiersToString, SpannableAssertionFailure;
22 import 'deferred_load.dart' show OutputUnit; 22 import 'deferred_load.dart' show OutputUnit;
23 import 'js_backend/js_backend.dart' show JavaScriptBackend; 23 import 'js_backend/js_backend.dart' show JavaScriptBackend;
24 import 'js/js.dart' as jsAst; 24 import 'js/js.dart' as jsAst;
25 import 'compilation_info.dart' show CompilationInformation; 25 import 'dependency_info.dart' show DependencyInformation;
26 26
27 /// Maps elements to an id. Supports lookups in 27 /// Maps elements to an id. Supports lookups in
28 /// both directions. 28 /// both directions.
29 class ElementMapper { 29 class ElementMapper {
30 Map<int, Element> _idToElement = {}; 30 Map<int, Element> _idToElement = {};
31 Map<Element, int> _elementToId = {}; 31 Map<Element, int> _elementToId = {};
32 int _idCounter = 0; 32 int _idCounter = 0;
33 String name; 33 String name;
34 34
35 ElementMapper(this.name); 35 ElementMapper(this.name);
36 36
37 Iterable<Element> get elements => _elementToId.keys;
38
37 String add(Element e) { 39 String add(Element e) {
38 if (_elementToId.containsKey(e)) { 40 if (_elementToId.containsKey(e)) {
39 return name + "/${_elementToId[e]}"; 41 return name + "/${_elementToId[e]}";
40 } 42 }
41 43
42 _idToElement[_idCounter] = e; 44 _idToElement[_idCounter] = e;
43 _elementToId[e] = _idCounter; 45 _elementToId[e] = _idCounter;
44 _idCounter += 1; 46 _idCounter += 1;
45 return name + "/${_idCounter - 1}"; 47 return name + "/${_idCounter - 1}";
46 } 48 }
47 } 49 }
48 50
49 class DividedElementMapper { 51 class DividedElementMapper {
50 // Mappers for specific kinds of elements. 52 // Mappers for specific kinds of elements.
51 ElementMapper _library = new ElementMapper('library'); 53 ElementMapper _library = new ElementMapper('library');
52 ElementMapper _typedef = new ElementMapper('typedef'); 54 ElementMapper _typedef = new ElementMapper('typedef');
53 ElementMapper _field = new ElementMapper('field'); 55 ElementMapper _field = new ElementMapper('field');
54 ElementMapper _class = new ElementMapper('class'); 56 ElementMapper _class = new ElementMapper('class');
55 ElementMapper _function = new ElementMapper('function'); 57 ElementMapper _function = new ElementMapper('function');
56 58
59 Iterable<Element> get functions => _function.elements;
60
57 // Convert this database of elements into JSON for rendering 61 // Convert this database of elements into JSON for rendering
58 Map<String, dynamic> _toJson(ElementToJsonVisitor elementToJson) { 62 Map<String, dynamic> _toJson(ElementToJsonVisitor elementToJson) {
59 Map<String, dynamic> json = {}; 63 Map<String, dynamic> json = {};
60 var m = [_library, _typedef, _field, _class, _function]; 64 var m = [_library, _typedef, _field, _class, _function];
61 for (ElementMapper mapper in m) { 65 for (ElementMapper mapper in m) {
62 Map<String, dynamic> innerMapper = {}; 66 Map<String, dynamic> innerMapper = {};
63 mapper._idToElement.forEach((k, v) { 67 mapper._idToElement.forEach((k, v) {
64 // All these elements are already cached in the 68 // All these elements are already cached in the
65 // jsonCache, so this is just an access. 69 // jsonCache, so this is just an access.
66 var elementJson = elementToJson.process(v); 70 var elementJson = elementToJson.process(v);
67 if (elementJson != null) { 71 if (elementJson != null) {
68 innerMapper["$k"] = elementJson; 72 innerMapper["$k"] = elementJson;
69 } 73 }
70 }); 74 });
71 json[mapper.name] = innerMapper; 75 json[mapper.name] = innerMapper;
72 } 76 }
73 return json; 77 return json;
74 } 78 }
75 } 79 }
76 80
77 class ElementToJsonVisitor extends ElementVisitor<Map<String, dynamic>> { 81 class ElementToJsonVisitor extends ElementVisitor<Map<String, dynamic>> {
78 DividedElementMapper mapper = new DividedElementMapper(); 82 DividedElementMapper mapper = new DividedElementMapper();
79 Compiler compiler; 83 Compiler compiler;
80 84
81 CompilationInformation compilationInfo; 85 DependencyInformation dependencyInfo;
82 86
83 Map<Element, Map<String, dynamic>> jsonCache = {}; 87 Map<Element, Map<String, dynamic>> jsonCache = {};
84 Map<Element, jsAst.Expression> codeCache; 88 Map<Element, jsAst.Expression> codeCache;
85 89
86 int programSize; 90 int programSize;
87 DateTime compilationMoment; 91 DateTime compilationMoment;
88 String dart2jsVersion; 92 String dart2jsVersion;
89 Duration compilationDuration; 93 Duration compilationDuration;
90 Duration dumpInfoDuration; 94 Duration dumpInfoDuration;
91 95
92 ElementToJsonVisitor(Compiler compiler) { 96 ElementToJsonVisitor(Compiler compiler) {
93 this.compiler = compiler; 97 this.compiler = compiler;
94 this.compilationInfo = compiler.enqueuer.codegen.compilationInfo; 98 this.dependencyInfo = compiler.enqueuer.codegen.dependencyInfo;
95 99
96 programSize = compiler.assembledCode.length; 100 programSize = compiler.assembledCode.length;
97 compilationMoment = new DateTime.now(); 101 compilationMoment = new DateTime.now();
98 dart2jsVersion = compiler.hasBuildId ? compiler.buildId : null; 102 dart2jsVersion = compiler.hasBuildId ? compiler.buildId : null;
99 compilationDuration = compiler.totalCompileTime.elapsed; 103 compilationDuration = compiler.totalCompileTime.elapsed;
100 104
101 for (var library in compiler.libraryLoader.libraries.toList()) { 105 for (var library in compiler.libraryLoader.libraries.toList()) {
102 library.accept(this); 106 library.accept(this);
103 } 107 }
104 108
105 dumpInfoDuration = new DateTime.now().difference(compilationMoment); 109 dumpInfoDuration = new DateTime.now().difference(compilationMoment);
106 } 110 }
107 111
108 // If keeping the element is in question (like if a function has a size 112 // If keeping the element is in question (like if a function has a size
109 // of zero), only keep it if it holds dependencies to elsewhere. 113 // of zero), only keep it if it holds dependencies to elsewhere.
110 bool shouldKeep(Element element) { 114 bool shouldKeep(Element element) {
111 return compilationInfo.addsToWorkListMap.containsKey(element) || 115 return dependencyInfo.selectorsFromElement.containsKey(element);
112 compilationInfo.enqueuesMap.containsKey(element);
113 } 116 }
114 117
115 Map<String, dynamic> toJson() { 118 Map<String, dynamic> toJson() {
116 return mapper._toJson(this); 119 return mapper._toJson(this);
117 } 120 }
118 121
119 // Memoization of the JSON creating process. 122 // Memoization of the JSON creating process.
120 Map<String, dynamic> process(Element element) { 123 Map<String, dynamic> process(Element element) {
121 return jsonCache.putIfAbsent(element, () => element.accept(this)); 124 return jsonCache.putIfAbsent(element, () => element.accept(this));
122 } 125 }
123 126
127 String idOf(Element element) {
128 if (jsonCache.containsKey(element) && jsonCache[element] != null) {
129 return jsonCache[element]['id'];
130 } else {
131 return null;
132 }
133 }
134
124 Map<String, dynamic> visitElement(Element element) { 135 Map<String, dynamic> visitElement(Element element) {
125 return null; 136 return null;
126 } 137 }
127 138
128 Map<String, dynamic> visitConstructorBodyElement(ConstructorBodyElement e) { 139 Map<String, dynamic> visitConstructorBodyElement(ConstructorBodyElement e) {
129 return visitFunctionElement(e.constructor); 140 return visitFunctionElement(e.constructor);
130 } 141 }
131 142
132 Map<String, dynamic> visitLibraryElement(LibraryElement element) { 143 Map<String, dynamic> visitLibraryElement(LibraryElement element) {
133 var id = mapper._library.add(element); 144 var id = mapper._library.add(element);
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 compiler.outputProvider('', 'info.json') 468 compiler.outputProvider('', 'info.json')
458 ..add(jsonBuffer.toString()) 469 ..add(jsonBuffer.toString())
459 ..close(); 470 ..close();
460 }); 471 });
461 } 472 }
462 473
463 474
464 void dumpInfoJson(StringSink buffer) { 475 void dumpInfoJson(StringSink buffer) {
465 JsonEncoder encoder = const JsonEncoder(); 476 JsonEncoder encoder = const JsonEncoder();
466 477
467 // `A` uses and depends on the functions `Bs`.
468 // A Bs
469 Map<String, List<String>> holding = <String, List<String>>{};
470
471 DateTime startToJsonTime = new DateTime.now(); 478 DateTime startToJsonTime = new DateTime.now();
472 479
473 CompilationInformation compilationInfo = 480 DependencyInformation dependencyInfo =
474 infoCollector.compiler.enqueuer.codegen.compilationInfo; 481 infoCollector.compiler.enqueuer.codegen.dependencyInfo;
475 compilationInfo.addsToWorkListMap.forEach((func, deps) {
476 if (func != null) {
477 var funcJson = infoCollector.process(func);
478 if (funcJson != null) {
479 var funcId = funcJson['id'];
480 482
481 List<String> heldList = <String>[]; 483 Map<String, List<String>> holding = <String, List<String>>{};
482 484 for (Element fn in infoCollector.mapper.functions) {
483 for (var held in deps) { 485 Iterable<Element> pulling = dependencyInfo.getRetaining(fn, compiler);
484 // "process" to get the ids of the elements. 486 if (pulling.length > 0) {
485 var heldJson = infoCollector.process(held); 487 String fnId = infoCollector.idOf(fn);
486 if (heldJson != null) { 488 if (fnId != null) {
487 var heldId = heldJson['id']; 489 holding[fnId] = pulling
488 heldList.add(heldId); 490 .map((a) => infoCollector.idOf(a))
489 } 491 .where((a) => a != null)
490 } 492 .toList();
491 holding[funcId] = heldList;
492 } 493 }
493 } 494 }
494 }); 495 }
495 496
496 Map<String, dynamic> outJson = { 497 Map<String, dynamic> outJson = {
497 'elements': infoCollector.toJson(), 498 'elements': infoCollector.toJson(),
498 'holding': holding, 499 'holding': holding,
499 'dump_version': 1, 500 'dump_version': 1,
500 }; 501 };
501 502
502 Duration toJsonDuration = new DateTime.now().difference(startToJsonTime); 503 Duration toJsonDuration = new DateTime.now().difference(startToJsonTime);
503 504
504 Map<String, dynamic> generalProgramInfo = <String, dynamic> { 505 Map<String, dynamic> generalProgramInfo = <String, dynamic> {
505 'size': infoCollector.programSize, 506 'size': infoCollector.programSize,
506 'dart2jsVersion': infoCollector.dart2jsVersion, 507 'dart2jsVersion': infoCollector.dart2jsVersion,
507 'compilationMoment': infoCollector.compilationMoment.toString(), 508 'compilationMoment': infoCollector.compilationMoment.toString(),
508 'compilationDuration': infoCollector.compilationDuration.toString(), 509 'compilationDuration': infoCollector.compilationDuration.toString(),
509 'toJsonDuration': toJsonDuration.toString(), 510 'toJsonDuration': toJsonDuration.toString(),
510 'dumpInfoDuration': infoCollector.dumpInfoDuration.toString(), 511 'dumpInfoDuration': infoCollector.dumpInfoDuration.toString(),
511 'noSuchMethodEnabled': compiler.enabledNoSuchMethod 512 'noSuchMethodEnabled': compiler.enabledNoSuchMethod
512 }; 513 };
513 514
514 outJson['program'] = generalProgramInfo; 515 outJson['program'] = generalProgramInfo;
515 516
516 ChunkedConversionSink<Object> sink = 517 ChunkedConversionSink<Object> sink =
517 encoder.startChunkedConversion( 518 encoder.startChunkedConversion(
518 new StringConversionSink.fromStringSink(buffer)); 519 new StringConversionSink.fromStringSink(buffer));
519 sink.add(outJson); 520 sink.add(outJson);
520 } 521 }
521 } 522 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698