CodeStatistics.java revision 99409883d9c4c0ffb49b070ce307bb33a9dfe9f1
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dx.dex.cf;
18
19import com.android.dx.dex.code.DalvCode;
20import com.android.dx.rop.code.RopMethod;
21
22import java.io.PrintStream;
23
24/**
25 * Static methods and variables for collecting statistics on generated
26 * code.
27 */
28public final class CodeStatistics {
29    /** set to {@code true} to enable development-time debugging code */
30    private static final boolean DEBUG = false;
31
32    /**
33     * running sum of the number of registers added/removed in
34     * SSA form by the optimizer
35     */
36    public static int runningDeltaRegisters = 0;
37
38    /**
39     * running sum of the number of insns added/removed in
40     * SSA form by the optimizer
41     */
42    public static int runningDeltaInsns = 0;
43
44    /** running sum of the total number of Rop insns processed */
45    public static int runningTotalInsns = 0;
46
47    /**
48     * running sum of the number of dex-form registers added/removed in
49     * SSA form by the optimizer. Only valid if args.statistics is true.
50     */
51    public static int dexRunningDeltaRegisters = 0;
52
53    /**
54     * running sum of the number of dex-form insns (actually code
55     * units) added/removed in SSA form by the optimizer. Only valid
56     * if args.statistics is true.
57     */
58    public static int dexRunningDeltaInsns = 0;
59
60    /**
61     * running sum of the total number of dex insns (actually code
62     * units) processed
63     */
64    public static int dexRunningTotalInsns = 0;
65
66    /** running sum of original class bytecode bytes */
67    public static int runningOriginalBytes = 0;
68
69    /**
70     * This class is uninstantiable.
71     */
72    private CodeStatistics() {
73        // This space intentionally left blank.
74    }
75
76    /**
77     * Updates the number of original bytecode bytes processed.
78     *
79     * @param count {@code >= 0;} the number of bytes to add
80     */
81    public static void updateOriginalByteCount(int count) {
82        runningOriginalBytes += count;
83    }
84
85    /**
86     * Updates the dex statistics.
87     *
88     * @param nonOptCode non-optimized code block
89     * @param code optimized code block
90     */
91    public static void updateDexStatistics(DalvCode nonOptCode,
92            DalvCode code) {
93        if (DEBUG) {
94            System.err.println("dex insns (old/new) "
95                    + nonOptCode.getInsns().codeSize()
96                    + "/" + code.getInsns().codeSize()
97                    + " regs (o/n) "
98                    + nonOptCode.getInsns().getRegistersSize()
99                    + "/" + code.getInsns().getRegistersSize()
100            );
101        }
102
103        dexRunningDeltaInsns
104            += (code.getInsns().codeSize()
105                - nonOptCode.getInsns().codeSize());
106
107        dexRunningDeltaRegisters
108            += (code.getInsns().getRegistersSize()
109                - nonOptCode.getInsns().getRegistersSize());
110
111        dexRunningTotalInsns += code.getInsns().codeSize();
112    }
113
114    /**
115     * Updates the ROP statistics.
116     *
117     * @param nonOptRmeth non-optimized method
118     * @param rmeth optimized method
119     */
120    public static void updateRopStatistics(RopMethod nonOptRmeth,
121            RopMethod rmeth) {
122        int oldCountInsns
123                = nonOptRmeth.getBlocks().getEffectiveInstructionCount();
124        int oldCountRegs = nonOptRmeth.getBlocks().getRegCount();
125
126        if (DEBUG) {
127            System.err.println("insns (old/new): "
128                    + oldCountInsns + "/"
129                    + rmeth.getBlocks().getEffectiveInstructionCount()
130                    + " regs (o/n):" + oldCountRegs
131                    + "/"  +  rmeth.getBlocks().getRegCount());
132        }
133
134        int newCountInsns
135                = rmeth.getBlocks().getEffectiveInstructionCount();
136
137        runningDeltaInsns
138            += (newCountInsns - oldCountInsns);
139
140        runningDeltaRegisters
141            += (rmeth.getBlocks().getRegCount() - oldCountRegs);
142
143        runningTotalInsns += newCountInsns;
144    }
145
146    /**
147     * Prints out the collected statistics.
148     *
149     * @param out {@code non-null;} where to output to
150     */
151    public static void dumpStatistics(PrintStream out) {
152        out.printf("Optimizer Delta Rop Insns: %d total: %d "
153                + "(%.2f%%) Delta Registers: %d\n",
154                runningDeltaInsns,
155                runningTotalInsns,
156                (100.0 * (((float) runningDeltaInsns)
157                        / (runningTotalInsns + Math.abs(runningDeltaInsns)))),
158                runningDeltaRegisters);
159
160        out.printf("Optimizer Delta Dex Insns: Insns: %d total: %d "
161                + "(%.2f%%) Delta Registers: %d\n",
162                dexRunningDeltaInsns,
163                dexRunningTotalInsns,
164                (100.0 * (((float) dexRunningDeltaInsns)
165                        / (dexRunningTotalInsns
166                                + Math.abs(dexRunningDeltaInsns)))),
167                dexRunningDeltaRegisters);
168
169        out.printf("Original bytecode byte count: %d\n",
170                runningOriginalBytes);
171    }
172}
173