aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/tiny/ksize.py
blob: 275c983b8d74439b02f92bd19d5a8ff13cba2110 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@media only all and (prefers-color-scheme: dark) {
.highlight .hll { background-color: #49483e }
.highlight .c { color: #75715e } /* Comment */
.highlight .err { color: #960050; background-color: #1e0010 } /* Error */
.highlight .k { color: #66d9ef } /* Keyword */
.highlight .l { color: #ae81ff } /* Literal */
.highlight .n { color: #f8f8f2 } /* Name */
.highlight .o { color: #f92672 } /* Operator */
.highlight .p { color: #f8f8f2 } /* Punctuation */
.highlight .ch { color: #75715e } /* Comment.Hashbang */
.highlight .cm { color: #75715e } /* Comment.Multiline */
.highlight .cp { color: #75715e } /* Comment.Preproc */
.highlight .cpf { color: #75715e } /* Comment.PreprocFile */
.highlight .c1 { color: #75715e } /* Comment.Single */
.highlight .cs { color: #75715e } /* Comment.Special */
.highlight .gd { color: #f92672 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gi { color: #a6e22e } /* Generic.Inserted */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #75715e } /* Generic.Subheading */
.highlight .kc { color: #66d9ef } /* Keyword.Constant */
.highlight .kd { color: #66d9ef } /* Keyword.Declaration */
.highlight .kn { color: #f92672 } /* Keyword.Namespace */
.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */
.highlight .kr { color: #66d9ef } /* Keyword.Reserved */
.highlight .kt { color: #66d9ef } /* Keyword.Type */
.highlight .ld { color: #e6db74 } /* Literal.Date */
.highlight .m { color: #ae81ff } /* Literal.Number */
.highlight .s { color: #e6db74 } /* Literal.String */
.highlight .na { color: #a6e22e } /* Name.Attribute */
.highlight .nb { color: #f8f8f2 } /* Name.Builtin */
.highlight .nc { color: #a6e22e } /* Name.Class */
.highlight .no { color: #66d9ef } /* Name.Constant */
.highlight .nd { color: #a6e22e } /* Name.Decorator */
.highlight .ni { color: #f8f8f2 } /* Name.Entity */
.highlight .ne { color: #a6e22e } /* Name.Exception */
.highlight .nf { color: #a6e22e } /* Name.Function */
.highlight .nl { color: #f8f8f2 } /* Name.Label */
.highlight .nn { color: #f8f8f2 } /* Name.Namespace */
.highlight .nx { color: #a6e22e } /* Name.Other */
.highlight .py { color: #f8f8f2 } /* Name.Property */
.highlight .nt { color: #f92672 } /* Name.Tag */
.highlight .nv { color: #f8f8f2 } /* Name.Variable */
.highlight .ow { color: #f92672 } /* Operator.Word */
.highlight .w { color: #f8f8f2 } /* Text.Whitespace */
.highlight .mb { color: #ae81ff } /* Literal.Number.Bin */
.highlight .mf { color: #ae81ff } /* Literal.Number.Float */
.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */
.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */
.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */
.highlight .sa { color: #e6db74 } /* Literal.String.Affix */
.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */
.highlight .sc { color: #e6db74 } /* Literal.String.Char */
.highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */
.highlight .sd { color: #e6db74 } /* Literal.String.Doc */
.highlight .s2 { color: #e6db74 } /* Literal.String.Double */
.highlight .se { color: #ae81ff } /* Literal.String.Escape */
.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */
.highlight .si { color: #e6db74 } /* Literal.String.Interpol */
.highlight .sx { color: #e6db74 } /* Literal.String.Other */
.highlight .sr { color: #e6db74 } /* Literal.String.Regex */
.highlight .s1 { color: #e6db74 } /* Literal.String.Single */
.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */
.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #a6e22e } /* Name.Function.Magic */
.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */
.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */
.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */
.highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */
.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */
}
@media (prefers-color-scheme: light) {
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.high
#!/usr/bin/env python
#
# Copyright (c) 2011, Intel Corporation.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Display details of the kernel build size, broken up by built-in.o. Sort
# the objects by size. Run from the top level kernel build directory.
#
# Author: Darren Hart <dvhart@linux.intel.com>
#

import sys
import getopt
import os
from subprocess import *
from string import join


def usage():
    prog = os.path.basename(sys.argv[0])
    print('Usage: %s [OPTION]...' % prog)
    print('  -d,                 display an additional level of drivers detail')
    print('  -h, --help          display this help and exit')
    print('')
    print('Run %s from the top-level Linux kernel build directory.' % prog)


class Sizes:
    def __init__(self, glob):
        self.title = glob
        p = Popen("size -t " + glob, shell=True, stdout=PIPE, stderr=PIPE)
        output = p.communicate()[0].splitlines()
        if len(output) > 2:
            sizes = output[-1].split()[0:4]
            self.text = int(sizes[0])
            self.data = int(sizes[1])
            self.bss = int(sizes[2])
            self.total = int(sizes[3])
        else:
            self.text = self.data = self.bss = self.total = 0

    def show(self, indent=""):
        print("%-32s %10d | %10d %10d %10d" % \
              (indent+self.title, self.total, self.text, self.data, self.bss))


class Report:
    def create(filename, title, subglob=None):
        r = Report(filename, title)
        path = os.path.dirname(filename)

        p = Popen("ls " + path + "/*.o | grep -v built-in.o",
                  shell=True, stdout=PIPE, stderr=PIPE)
        glob = join(p.communicate()[0].splitlines())
        oreport = Report(glob, path + "/*.o")
        oreport.sizes.title = path + "/*.o"
        r.parts.append(oreport)

        if subglob:
            p = Popen("ls " + subglob, shell=True, stdout=PIPE, stderr=PIPE)
            for f in p.communicate()[0].splitlines():
                path = os.path.dirname(f)
                r.parts.append(Report.create(f, path, path + "/*/built-in.o"))
            r.parts.sort(reverse=True)

        for b in r.parts:
            r.totals["total"] += b.sizes.total
            r.totals["text"] += b.sizes.text
            r.totals["data"] += b.sizes.data
            r.totals["bss"] += b.sizes.bss

        r.deltas["total"] = r.sizes.total - r.totals["total"]
        r.deltas["text"] = r.sizes.text - r.totals["text"]
        r.deltas["data"] = r.sizes.data - r.totals["data"]
        r.deltas["bss"] = r.sizes.bss - r.totals["bss"]
        return r
    create = staticmethod(create)

    def __init__(self, glob, title):
        self.glob = glob
        self.title = title
        self.sizes = Sizes(glob)
        self.parts = []
        self.totals = {"total":0, "text":0, "data":0, "bss":0}
        self.deltas = {"total":0, "text":0, "data":0, "bss":0}

    def show(self, indent=""):
        rule = str.ljust(indent, 80, '-')
        print("%-32s %10s | %10s %10s %10s" % \
              (indent+self.title, "total", "text", "data", "bss"))
        print(rule)
        self.sizes.show(indent)
        print(rule)
        for p in self.parts:
            if p.sizes.total > 0:
                p.sizes.show(indent)
        print(rule)
        print("%-32s %10d | %10d %10d %10d" % \
              (indent+"sum", self.totals["total"], self.totals["text"],
               self.totals["data"], self.totals["bss"]))
        print("%-32s %10d | %10d %10d %10d" % \
              (indent+"delta", self.deltas["total"], self.deltas["text"],
               self.deltas["data"], self.deltas["bss"]))
        print("\n")

    def __cmp__(this, that):
        if that is None:
            return 1
        if not isinstance(that, Report):
            raise TypeError
        if this.sizes.total < that.sizes.total:
            return -1
        if this.sizes.total > that.sizes.total:
            return 1
        return 0


def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "dh", ["help"])
    except getopt.GetoptError, err:
        print('%s' % str(err))
        usage()
        sys.exit(2)

    driver_detail = False
    for o, a in opts:
        if o == '-d':
            driver_detail = True
        elif o in ('-h', '--help'):
            usage()
            sys.exit(0)
        else:
            assert False, "unhandled option"

    glob = "arch/*/built-in.o */built-in.o"
    vmlinux = Report.create("vmlinux",  "Linux Kernel", glob)

    vmlinux.show()
    for b in vmlinux.parts:
        if b.totals["total"] > 0 and len(b.parts) > 1:
            b.show()
        if b.title == "drivers" and driver_detail:
            for d in b.parts:
                if d.totals["total"] > 0 and len(d.parts) > 1:
                    d.show("    ")


if __name__ == "__main__":
    main()