| Index: tools/binary_size/file_format.py
|
| diff --git a/tools/binary_size/file_format.py b/tools/binary_size/file_format.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4f1bbb9180bb67ed2dbd89b9f26a52fad747a748
|
| --- /dev/null
|
| +++ b/tools/binary_size/file_format.py
|
| @@ -0,0 +1,85 @@
|
| +# Copyright 2017 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +"""Deals with loading & saving .size files."""
|
| +
|
| +import ast
|
| +import gzip
|
| +import models
|
| +
|
| +
|
| +# File format version for .size files.
|
| +_SERIALIZATION_VERSION = 1
|
| +
|
| +
|
| +def EndsWithMaybeGz(path, suffix):
|
| + return path.endswith(suffix) or path.endswith(suffix + '.gz')
|
| +
|
| +
|
| +def OpenMaybeGz(path, mode=None):
|
| + """Calls `gzip.open()` if |path| ends in ".gz", otherwise calls `open()`."""
|
| + if path.endswith('.gz'):
|
| + if mode and 'w' in mode:
|
| + return gzip.GzipFile(path, mode, 1)
|
| + return gzip.open(path, mode)
|
| + return open(path, mode or 'r')
|
| +
|
| +
|
| +def _SaveSizeInfoToFile(result, file_obj):
|
| + """Saves the result to the given file object."""
|
| + # Store one bucket per line.
|
| + file_obj.write('%d\n' % _SERIALIZATION_VERSION)
|
| + file_obj.write('%r\n' % result.section_sizes)
|
| + file_obj.write('%d\n' % len(result.symbols))
|
| + prev_section_name = None
|
| + # Store symbol fields as tab-separated.
|
| + # Store only non-derived fields.
|
| + for symbol in result.symbols:
|
| + if symbol.section_name != prev_section_name:
|
| + file_obj.write('%s\n' % symbol.section_name)
|
| + prev_section_name = symbol.section_name
|
| + # Don't write padding nor name since these are derived values.
|
| + file_obj.write('%x\t%x\t%s\t%s\n' % (
|
| + symbol.address, symbol.size_without_padding,
|
| + symbol.function_signature or symbol.name, symbol.path))
|
| +
|
| +
|
| +def _LoadSizeInfoFromFile(file_obj):
|
| + """Loads a result from the given file."""
|
| + lines = iter(file_obj)
|
| + actual_version = int(next(lines))
|
| + assert actual_version == _SERIALIZATION_VERSION, (
|
| + 'Version mismatch. Need to write some upgrade code.')
|
| +
|
| + section_sizes = ast.literal_eval(next(lines))
|
| + num_syms = int(next(lines))
|
| + symbol_list = [None] * num_syms
|
| + section_name = None
|
| + for i in xrange(num_syms):
|
| + line = next(lines)[:-1]
|
| + if '\t' not in line:
|
| + section_name = line
|
| + line = next(lines)[:-1]
|
| + new_sym = models.Symbol.__new__(models.Symbol)
|
| + parts = line.split('\t')
|
| + new_sym.section_name = section_name
|
| + new_sym.address = int(parts[0], 16)
|
| + new_sym.size = int(parts[1], 16)
|
| + new_sym.name = parts[2]
|
| + new_sym.path = parts[3]
|
| + new_sym.padding = 0 # Derived
|
| + new_sym.function_signature = None # Derived
|
| + symbol_list[i] = new_sym
|
| +
|
| + return models.SizeInfo(models.SymbolGroup(symbol_list), section_sizes)
|
| +
|
| +
|
| +def SaveSizeInfo(result, path):
|
| + with OpenMaybeGz(path, 'wb') as f:
|
| + _SaveSizeInfoToFile(result, f)
|
| +
|
| +
|
| +def LoadSizeInfo(path):
|
| + with OpenMaybeGz(path) as f:
|
| + return _LoadSizeInfoFromFile(f)
|
|
|