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

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

Issue 1253763004: dart2js: represent dump-info explicitly, so we can easily create tools that process the data (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Data collected by the dump-info task.
6 library compiler.src.lib.info;
7
8 // Note: this file intentionally doesn't import anything from the compiler. That
9 // should make it easier for tools to depend on this library. The idea is that
10 // by using this library, tools can consume the information in the same way it
11 // is produced by the compiler.
12 // TODO(sigmund): make this a proper public API (export this explicitly at the
13 // lib folder level.)
14
15 /// Common interface to many pieces of information generated by the compiler.
16 abstract class Info {
17 /// An identifier for the kind of information.
18 String get kind;
19
20 /// An unique id used to create references to this info.
21 int get id;
22
23 /// Serializes the information into a JSON format.
24 Map toJson();
25 }
26
27 /// Common information used for most kind of elements.
28 // TODO(sigmund): add more:
29 // - inputSize: bytes used in the Dart source program
30 // - transitiveSize: bytes including the size of dependencies that are only
31 // retained because of this element.
32 class BasicInfo implements Info {
33 final String kind;
34 final int id;
35
36 /// Bytes used in the generated code for the corresponding element.
37 int size;
38
39 String get serializedId => '$kind/$id';
40
41 // TODO(sigmund): make final (currently not final because we amend the name in
Johnni Winther 2015/07/27 10:14:42 'name in of' -> 'name of'
Siggi Cherem (dart-lang) 2015/07/27 20:10:59 Done.
42 // of nested closures to record their enclosing element).
43 String name;
44
45 /// If using deferred libraries, where the element associated with this info
46 /// is generated.
47 final OutputUnitInfo outputUnit;
48
49 BasicInfo(this.kind, this.id, this.name, this.outputUnit, [this.size = 0]);
50
51 Map toJson() {
52 var res = {'id': serializedId, 'kind': kind, 'name': name, 'size': size};
53 // TODO(sigmund): omit this also when outputUnit.id == 0
54 // (most code is by default in the main output unit)
55 if (outputUnit != null) res['outputUnit'] = outputUnit.serializedId;
56 return res;
57 }
58 }
59
60 /// The entire information produced while compiling a program.
61 class AllInfo {
62 /// Summary information about the program.
63 ProgramInfo program;
64
65 /// Information about each library processed by the compiler.
66 List<LibraryInfo> libraries = [];
67
68 /// Information about each function (includes methods and getters in any
69 /// library)
70 List<FunctionInfo> functions = [];
71
72 /// Information about type defs in the program.
73 List<TypedefInfo> typedefs = [];
74
75 /// Information about each class (in any library).
76 List<ClassInfo> classes = [];
77
78 /// Information about fields (in any class).
79 List<FieldInfo> fields = [];
80
81 /// Information about output units (should be just one entry if not using
82 /// deferred loading).
83 List<OutputUnitInfo> outputUnits = [];
84
85 /// Details about all deferred imports and what files would be loaded when the
86 /// import is resolved.
87 // TODO(sigmund): use a different format for dump-info. This currently emits
88 // the same map that is created for the `--deferred-map` flag.
89 Map<String, Map<String, dynamic>> deferredFiles;
90
91 /// Major version indicating breaking changes in the format. A new version
92 /// means that an old deserialization algorithm will not work with the new
93 /// format.
94 final int version = 3;
95
96 /// Minor version indicating non-breaking changes in the format. A change in
97 /// this version number means that the json parsing in this library from a
98 /// previous will continue to work after the change. This is typically
99 /// increased when adding new entries to the file format.
100 // Note: the dump-info.viewer app was written using a json parser version 3.2.
101 final int minorVersion = 3;
102
103 AllInfo();
104
105 factory AllInfo.fromJson(Map map) {
106 // TODO(sigmund): implement
107 throw UnimplementedError('deserialization of dump-info not implemented');
108 }
109
110 Map _listAsJsonMap(List<Info> list) {
111 var map = <String, Map>{};
112 for (var info in list) {
113 map['${info.id}'] = info.toJson();
114 }
115 return map;
116 }
117
118 Map _extractHoldingInfo() {
119 var map = <String, List>{};
120 for (var f in functions) {
121 if (f.uses.isEmpty) continue;
122 map[f.serializedId] = f.uses.map((u) => u.toJson()).toList();
123 }
124 return map;
125 }
126
127 Map toJson() => {
128 'elements': {
Siggi Cherem (dart-lang) 2015/07/24 01:07:58 seems wasteful that this is indented so much by th
129 'library': _listAsJsonMap(libraries),
130 'class': _listAsJsonMap(classes),
131 'function': _listAsJsonMap(functions),
132 'typedef': _listAsJsonMap(typedefs),
133 'field': _listAsJsonMap(fields),
134 },
135 'holding': _extractHoldingInfo(),
136 'outputUnits': outputUnits.map((u) => u.toJson()).toList(),
137 'dump_version': version,
138 'deferredFiles': deferredFiles,
139 'dump_minor_version': '$minorVersion',
140 // TODO(sigmund): change viewer to accept an int?
141 'program': program.toJson(),
142 };
143 }
144
145 class ProgramInfo {
146 int size;
147 String dart2jsVersion;
148 DateTime compilationMoment;
149 Duration compilationDuration;
150 // TODO(sigmund): use Duration.
151 int toJsonDuration;
152 int dumpInfoDuration;
153 bool noSuchMethodEnabled;
154 bool minified;
155
156 ProgramInfo(
157 {this.size,
158 this.dart2jsVersion,
159 this.compilationMoment,
160 this.compilationDuration,
161 this.toJsonDuration,
162 this.dumpInfoDuration,
163 this.noSuchMethodEnabled,
164 this.minified});
165
166 Map toJson() => {
167 'size': size,
168 'dart2jsVersion': dart2jsVersion,
169 'compilationMoment': '$compilationMoment',
170 'compilationDuration': '${compilationDuration}',
171 'toJsonDuration': toJsonDuration,
172 'dumpInfoDuration': '$dumpInfoDuration',
173 'noSuchMethodEnabled': noSuchMethodEnabled,
174 'minified': minified,
175 };
176 }
177
178 class LibraryInfo extends BasicInfo {
179 final Uri uri;
180 final List<FunctionInfo> topLevelFunctions = [];
181 final List<FieldInfo> topLevelVariables = [];
182 final List<ClassInfo> classes = [];
183
184 static int _id = 0;
185
186 bool get isEmpty =>
187 topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty;
188
189 LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size)
190 : super('library', _id++, name, outputUnit, size);
191
192 Map toJson() => super.toJson()
193 ..addAll({
194 'children': []
195 ..addAll(topLevelFunctions.map((f) => f.serializedId))
196 ..addAll(topLevelVariables.map((v) => v.serializedId))
197 ..addAll(classes.map((c) => c.serializedId)),
198 'canonicalUri': '$uri',
199 });
200 }
201
202 class OutputUnitInfo extends BasicInfo {
203 static int _ids = 0;
204 OutputUnitInfo(String name, int size)
205 : super('outputUnit', _ids++, name, null, size);
206 }
207
208 class ClassInfo extends BasicInfo {
209 final bool isAbstract;
210
211 // TODO(sigmund): split static vs instance vs closures
212 final List<FunctionInfo> functions = [];
213 final List<FieldInfo> fields = [];
214 static int _ids = 0;
215
216 ClassInfo(
217 {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0})
218 : super('class', _ids++, name, outputUnit, size);
219
220 Map toJson() => super.toJson()
221 ..addAll({
222 // TODO(sigmund): change format, include only when abstract is true.
223 'modifiers': {'abstract': isAbstract},
224 'children': []
225 ..addAll(fields.map((f) => f.serializedId))
226 ..addAll(functions.map((m) => m.serializedId))
227 });
228 }
229
230 class FieldInfo extends BasicInfo {
231 String type;
232 String inferredType;
233 List<FunctionInfo> closures;
234 String code;
235
236 static int _ids = 0;
237 FieldInfo(
238 {String name,
239 int size,
240 this.type,
241 this.inferredType,
242 this.closures,
243 this.code,
244 OutputUnitInfo outputUnit})
245 : super('field', _ids++, name, outputUnit, size);
246
247 Map toJson() => super.toJson()
248 ..addAll({
249 'children': closures.map((i) => i.serializedId).toList(),
250 'inferredType': inferredType,
251 'code': code,
252 'type': type,
253 });
254 }
255
256 class TypedefInfo extends BasicInfo {
257 String type;
258
259 static int _ids = 0;
260 TypedefInfo(String name, this.type, OutputUnitInfo outputUnit)
261 : super('typedef', _ids++, name, outputUnit);
262
263 Map toJson() => super.toJson()..['type'] = '$type';
264 }
265
266 class FunctionInfo extends BasicInfo {
267 static const int TOP_LEVEL_FUNCTION_KIND = 0;
268 static const int CLOSURE_FUNCTION_KIND = 1;
269 static const int METHOD_FUNCTION_KIND = 2;
270 static const int CONSTRUCTOR_FUNCTION_KIND = 3;
271 static int _ids = 0;
272
273 /// Kind of function (top-level function, closure, method, or constructor).
274 final int functionKind;
275
276 /// Modifiers applied to this function.
277 final FunctionModifiers modifiers;
278
279 /// Nested closures that appear within the body of this function.
280 List<FunctionInfo> closures;
281
282 /// The type of this function.
283 String type;
284
285 /// The declared return type.
286 String returnType;
287
288 /// The inferred return type.
289 String inferredReturnType;
290
291 /// Name and type information for each parameter.
292 List<ParameterInfo> parameters;
293
294 /// Side-effects.
295 // TODO(sigmund): serialize more precisely, not just a string representation.
296 String sideEffects;
297
298 /// How many function calls were inlined into this function.
299 int inlinedCount;
300
301 /// The actual generated code.
302 String code;
303
304 /// How does this function depend on other functions or fields.
305 List<DependencyInfo> uses = [];
karlklose 2015/07/24 07:08:22 Please add type arguments to literals (several pla
Siggi Cherem (dart-lang) 2015/07/27 20:10:59 Done. We should chat more about this long term - i
306
307 FunctionInfo(
308 {String name,
309 OutputUnitInfo outputUnit,
310 int size,
311 this.functionKind,
312 this.modifiers,
313 this.closures,
314 this.type,
315 this.returnType,
316 this.inferredReturnType,
317 this.parameters,
318 this.sideEffects,
319 this.inlinedCount,
320 this.code})
321 : super('function', _ids++, name, outputUnit, size);
322
323 Map toJson() => super.toJson()
324 ..addAll({
325 'children': closures.map((i) => i.serializedId).toList(),
326 'modifiers': modifiers.toJson(),
327 'returnType': returnType,
328 'inferredReturnType': inferredReturnType,
329 'parameters': parameters.map((p) => p.toJson()).toList(),
330 'sideEffects': sideEffects,
331 'inlinedCount': inlinedCount,
332 'code': code,
333 'type': type,
334 // Note: version 3.2 of dump-info serializes `uses` in a section called
335 // `holding` at the top-level.
336 });
337 }
338
339 /// Information about how a dependency is used.
340 class DependencyInfo {
341 /// The dependency, either a FunctionInfo or FieldInfo.
342 final Info target;
343
344 /// Either a selector mask indicating how this is used, or 'inlined'.
345 final String mask;
karlklose 2015/07/24 07:08:22 Preferably we would have an enum that describes ex
Siggi Cherem (dart-lang) 2015/07/27 20:10:58 good point. I added a TODO for now. I'm thinking t
346
347 DependencyInfo(this.target, this.mask);
348
349 Map toJson() => {'id': target.serializedId, 'mask': mask};
350 }
351
352 /// Name and type information about a function parameter.
353 class ParameterInfo {
354 final String name;
355 final String type;
356 final String declaredType;
357
358 ParameterInfo(this.name, this.type, this.declaredType);
359
360 Map toJson() => {'name': name, 'type': type, 'declaredType': declaredType};
361 }
362
363 /// Modifiers that may apply to methods.
364 class FunctionModifiers {
365 final bool isStatic;
366 final bool isConst;
367 final bool isFactory;
368 final bool isExternal;
369
370 FunctionModifiers(
371 {this.isStatic: false,
372 this.isConst: false,
373 this.isFactory: false,
374 this.isExternal: false});
375
376 factory FunctionModifiers.fromJson(Map<String, bool> json) {
377 return new FunctionModifiers(
378 isStatic: json['static'] == true,
379 isConst: json['const'] == true,
380 isFactory: json['factory'] == true,
381 isExternal: json['external'] == true);
382 }
383
384 // TODO(sigmund): exclude false values (requires bumping the format version):
385 // Map toJson() {
386 // var res = <String, bool>{};
387 // if (isStatic) res['static'] = true;
388 // if (isConst) res['const'] = true;
389 // if (isFactory) res['factory'] = true;
390 // if (isExternal) res['external'] = true;
391 // return res;
392 // }
393 Map toJson() => {
394 'static': isStatic,
395 'const': isConst,
396 'factory': isFactory,
397 'external': isExternal,
398 };
399 }
OLDNEW
« pkg/compiler/lib/src/dump_info.dart ('K') | « pkg/compiler/lib/src/dump_info.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698