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 17 package com.android.dx.dex.cf; 18 19 import com.android.dx.dex.code.DalvCode; 20 import com.android.dx.rop.code.RopMethod; 21 22 import java.io.PrintStream; 23 24 /** 25 * Static methods and variables for collecting statistics on generated 26 * code. 27 */ 28 public final class CodeStatistics { 29 /** set to <code>true</code> 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 */ CodeStatistics()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 >= 0; the number of bytes to add 80 */ updateOriginalByteCount(int count)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 */ updateDexStatistics(DalvCode nonOptCode, DalvCode code)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 */ updateRopStatistics(RopMethod nonOptRmeth, RopMethod rmeth)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 non-null; where to output to 150 */ dumpStatistics(PrintStream out)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