| #!/usr/bin/env dart | |
| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:io'; | |
| import 'package:kernel/kernel.dart'; | |
| import 'package:kernel/binary/ast_from_binary.dart'; | |
| import 'package:kernel/src/tool/command_line_util.dart'; | |
| void usage() { | |
| print("Gives an overview of which parts of the dill file"); | |
| print("contributes how many bytes."); | |
| print(""); | |
| print("Usage: dart <script> dillFile.dill"); | |
| print("The given argument should be an existing file"); | |
| print("that is valid to load as a dill file."); | |
| exit(1); | |
| } | |
| void main(args) { | |
| CommandLineHelper.requireExactlyOneArgument( | |
| args, | |
| usage, | |
| requireFileExists: true, | |
| ); | |
| List<int> bytes = new File(args[0]).readAsBytesSync(); | |
| try { | |
| Component p = new Component(); | |
| new WrappedBinaryBuilder(bytes) | |
| ..readComponent(p) | |
| ..report(); | |
| } catch (e) { | |
| print("Argument given isn't a dill file that can be loaded."); | |
| usage(); | |
| } | |
| } | |
| class WrappedBinaryBuilder extends BinaryBuilder { | |
| new(_bytes) : super(_bytes, disableLazyReading: true); | |
| int offsetsSize = 0; | |
| int stringTableSize = 0; | |
| int linkTableSize = 0; | |
| int uriToSourceSize = 0; | |
| int constantTableSize = 0; | |
| Map<Uri, int> librarySizes = {}; | |
| @override | |
| int readOffset() { | |
| offsetsSize -= byteOffset; | |
| int result = super.readOffset(); | |
| offsetsSize += byteOffset; | |
| return result; | |
| } | |
| @override | |
| void readStringTable() { | |
| stringTableSize -= byteOffset; | |
| super.readStringTable(); | |
| stringTableSize += byteOffset; | |
| } | |
| @override | |
| void readLinkTable(CanonicalName linkRoot) { | |
| linkTableSize -= byteOffset; | |
| super.readLinkTable(linkRoot); | |
| linkTableSize += byteOffset; | |
| } | |
| @override | |
| Map<Uri, Source> readUriToSource({required bool readCoverage}) { | |
| uriToSourceSize -= byteOffset; | |
| Map<Uri, Source> result = super.readUriToSource(readCoverage: readCoverage); | |
| uriToSourceSize += byteOffset; | |
| return result; | |
| } | |
| @override | |
| void readConstantTable() { | |
| constantTableSize -= byteOffset; | |
| super.readConstantTable(); | |
| constantTableSize += byteOffset; | |
| } | |
| @override | |
| Library readLibrary(Component component, int endOffset) { | |
| int size = -byteOffset; | |
| var result = super.readLibrary(component, endOffset); | |
| size += byteOffset; | |
| librarySizes[result.importUri] = size; | |
| return result; | |
| } | |
| String _bytesToReadable(int size) { | |
| const List<String> what = const ["B", "KB", "MB", "GB", "TB"]; | |
| int idx = 0; | |
| double dSize = size + 0.0; | |
| while ((idx + 1) < what.length && dSize >= 512) { | |
| ++idx; | |
| dSize /= 1024; | |
| } | |
| return "${dSize.toStringAsFixed(1)} ${what[idx]} ($size B)"; | |
| } | |
| void report() { | |
| print("Offsets: ${_bytesToReadable(offsetsSize)}"); | |
| print("String table: ${_bytesToReadable(stringTableSize)}"); | |
| print("Link table: ${_bytesToReadable(linkTableSize)}"); | |
| print("URI to source table: ${_bytesToReadable(uriToSourceSize)}"); | |
| print("Constant table: ${_bytesToReadable(constantTableSize)}"); | |
| print(""); | |
| for (Uri uri in librarySizes.keys) { | |
| print("Library '$uri': ${_bytesToReadable(librarySizes[uri]!)}."); | |
| } | |
| } | |
| } |