Chromium Code Reviews| 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 /// Tool used mainly by dart2js developers to debug the generated info and check | 5 /// Tool used mainly by dart2js developers to debug the generated info and check |
| 6 /// that it is consistent and that it covers all the data we expect it to cover. | 6 /// that it is consistent and that it covers all the data we expect it to cover. |
| 7 library dart2js_info.bin.debug_info; | 7 library dart2js_info.bin.debug_info; |
| 8 | 8 |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'dart:io'; | 10 import 'dart:io'; |
| 11 | 11 |
| 12 import 'package:dart2js_info/info.dart'; | 12 import 'package:dart2js_info/info.dart'; |
| 13 import 'package:dart2js_info/src/graph.dart'; | 13 import 'package:dart2js_info/src/graph.dart'; |
| 14 import 'package:dart2js_info/src/util.dart'; | |
| 14 | 15 |
| 15 main(args) { | 16 main(args) { |
| 16 if (args.length < 1) { | 17 if (args.length < 1) { |
| 17 print('usage: dart tool/debug_info.dart path-to-info.json ' | 18 print('usage: dart tool/debug_info.dart path-to-info.json ' |
| 18 '[--show-library libname]'); | 19 '[--show-library libname]'); |
| 19 exit(1); | 20 exit(1); |
| 20 } | 21 } |
| 21 | 22 |
| 22 var filename = args[0]; | 23 var filename = args[0]; |
| 23 var json = JSON.decode(new File(filename).readAsStringSync()); | 24 var json = JSON.decode(new File(filename).readAsStringSync()); |
| 24 var info = new AllInfoJsonCodec().decode(json); | 25 var info = new AllInfoJsonCodec().decode(json); |
| 25 var debugLibName; | 26 var debugLibName; |
| 26 | 27 |
| 27 if (args.length > 2 && args[1] == '--show-library') { | 28 if (args.length > 2 && args[1] == '--show-library') { |
| 28 debugLibName = args[2]; | 29 debugLibName = args[2]; |
| 29 } | 30 } |
| 30 | 31 |
| 32 // Validate that codesize of elements adds up to total codesize. | |
|
Siggi Cherem (dart-lang)
2015/10/21 23:05:31
nit: let's move these comments down below as dart-
Harry Terkelsen
2015/10/21 23:07:44
Done.
| |
| 33 validateSize(info, debugLibName); | |
| 34 | |
| 35 // Validate that both forms of dependency information match. | |
| 36 compareGraphs(info); | |
| 37 | |
| 38 // Validate that all elements are reachable from `main` in the dependency | |
| 39 // graph. | |
| 40 verifyDeps(info); | |
| 41 } | |
| 42 | |
| 43 validateSize(AllInfo info, String debugLibName) { | |
| 31 // Gather data from visiting all info elements. | 44 // Gather data from visiting all info elements. |
| 32 var tracker = new _SizeTracker(debugLibName); | 45 var tracker = new _SizeTracker(debugLibName); |
| 33 info.accept(tracker); | 46 info.accept(tracker); |
| 34 | 47 |
| 35 // Validate that listed elements include elements of each library. | 48 // Validate that listed elements include elements of each library. |
| 36 Set<Info> listed = new Set()..addAll(info.functions)..addAll(info.fields); | 49 Set<Info> listed = new Set()..addAll(info.functions)..addAll(info.fields); |
| 37 // For our sanity we do some validation of dump-info invariants | 50 // For our sanity we do some validation of dump-info invariants |
| 38 var diff1 = listed.difference(tracker.discovered); | 51 var diff1 = listed.difference(tracker.discovered); |
| 39 var diff2 = tracker.discovered.difference(listed); | 52 var diff2 = tracker.discovered.difference(listed); |
| 40 if (diff1.length == 0 || diff2.length == 0) { | 53 if (diff1.length == 0 || diff2.length == 0) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 60 var percent = | 73 var percent = |
| 61 ((realTotal - accounted) * 100 / realTotal).toStringAsFixed(2); | 74 ((realTotal - accounted) * 100 / realTotal).toStringAsFixed(2); |
| 62 _fail('$percent% size missing: $accounted (all libs + consts) ' | 75 _fail('$percent% size missing: $accounted (all libs + consts) ' |
| 63 '< $realTotal (total)'); | 76 '< $realTotal (total)'); |
| 64 } | 77 } |
| 65 var missingTotal = tracker.missing.values.fold(0, (a, b) => a + b); | 78 var missingTotal = tracker.missing.values.fold(0, (a, b) => a + b); |
| 66 if (missingTotal > 0) { | 79 if (missingTotal > 0) { |
| 67 var percent = (missingTotal * 100 / realTotal).toStringAsFixed(2); | 80 var percent = (missingTotal * 100 / realTotal).toStringAsFixed(2); |
| 68 _fail('$percent% size missing in libraries (sum of elements > lib.size)'); | 81 _fail('$percent% size missing in libraries (sum of elements > lib.size)'); |
| 69 } | 82 } |
| 70 | |
| 71 // Validate dependency data. | |
| 72 compareGraphs(info); | |
| 73 } | 83 } |
| 74 | 84 |
| 75 class _SizeTracker extends RecursiveInfoVisitor { | 85 class _SizeTracker extends RecursiveInfoVisitor { |
| 76 /// A library name for which to print debugging information (if not null). | 86 /// A library name for which to print debugging information (if not null). |
| 77 final String _debugLibName; | 87 final String _debugLibName; |
| 78 | 88 |
| 79 _SizeTracker(this._debugLibName); | 89 _SizeTracker(this._debugLibName); |
| 80 | 90 |
| 81 /// [FunctionInfo]s and [FieldInfo]s transitively reachable from [LibraryInfo] | 91 /// [FunctionInfo]s and [FieldInfo]s transitively reachable from [LibraryInfo] |
| 82 /// elements. | 92 /// elements. |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 info.fields.forEach(_sameEdges); | 261 info.fields.forEach(_sameEdges); |
| 252 if (inUsesNotInDependencies == 0 && inDependenciesNotInUses == 0) { | 262 if (inUsesNotInDependencies == 0 && inDependenciesNotInUses == 0) { |
| 253 _pass('dependency data is consistent'); | 263 _pass('dependency data is consistent'); |
| 254 } else { | 264 } else { |
| 255 _fail('inconsistencies in dependency data:\n' | 265 _fail('inconsistencies in dependency data:\n' |
| 256 ' $inUsesNotInDependencies edges missing from "dependencies" graph\n' | 266 ' $inUsesNotInDependencies edges missing from "dependencies" graph\n' |
| 257 ' $inDependenciesNotInUses edges missing from "uses" graph'); | 267 ' $inDependenciesNotInUses edges missing from "uses" graph'); |
| 258 } | 268 } |
| 259 } | 269 } |
| 260 | 270 |
| 271 verifyDeps(AllInfo info) { | |
| 272 var graph = graphFromInfo(info); | |
| 273 var entrypoint = info.program.entrypoint; | |
| 274 var reachables = new Set.from(graph.preOrder(entrypoint)); | |
| 275 | |
| 276 var functionsAndFields = []..addAll(info.functions)..addAll(info.fields); | |
| 277 var unreachables = | |
| 278 functionsAndFields.where((func) => !reachables.contains(func)); | |
| 279 if (unreachables.isNotEmpty) { | |
| 280 _fail('${unreachables.length} elements are unreachable from the ' | |
| 281 'entrypoint'); | |
| 282 } else { | |
| 283 _pass('all elements are reachable from the entrypoint'); | |
| 284 } | |
| 285 } | |
| 286 | |
| 261 _pass(String msg) => print('\x1b[32mPASS\x1b[0m: $msg'); | 287 _pass(String msg) => print('\x1b[32mPASS\x1b[0m: $msg'); |
| 262 _fail(String msg) => print('\x1b[31mFAIL\x1b[0m: $msg'); | 288 _fail(String msg) => print('\x1b[31mFAIL\x1b[0m: $msg'); |
| OLD | NEW |