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; 21import java.io.PrintStream; 22 23/** 24 * Static methods and variables for collecting statistics on generated 25 * code. 26 */ 27public final class CodeStatistics { 28 /** set to {@code true} to enable development-time debugging code */ 29 private static final boolean DEBUG = false; 30 31 /** 32 * running sum of the number of registers added/removed in 33 * SSA form by the optimizer 34 */ 35 public static int runningDeltaRegisters = 0; 36 37 /** 38 * running sum of the number of insns added/removed in 39 * SSA form by the optimizer 40 */ 41 public static int runningDeltaInsns = 0; 42 43 /** running sum of the total number of Rop insns processed */ 44 public static int runningTotalInsns = 0; 45 46 /** 47 * running sum of the number of dex-form registers added/removed in 48 * SSA form by the optimizer. Only valid if args.statistics is true. 49 */ 50 public static int dexRunningDeltaRegisters = 0; 51 52 /** 53 * running sum of the number of dex-form insns (actually code 54 * units) added/removed in SSA form by the optimizer. Only valid 55 * if args.statistics is true. 56 */ 57 public static int dexRunningDeltaInsns = 0; 58 59 /** 60 * running sum of the total number of dex insns (actually code 61 * units) processed 62 */ 63 public static int dexRunningTotalInsns = 0; 64 65 /** running sum of original class bytecode bytes */ 66 public static int runningOriginalBytes = 0; 67 68 /** 69 * This class is uninstantiable. 70 */ 71 private CodeStatistics() { 72 // This space intentionally left blank. 73 } 74 75 /** 76 * Updates the number of original bytecode bytes processed. 77 * 78 * @param count {@code >= 0;} the number of bytes to add 79 */ 80 public static void updateOriginalByteCount(int count) { 81 runningOriginalBytes += count; 82 } 83 84 /** 85 * Updates the dex statistics. 86 * 87 * @param nonOptCode non-optimized code block 88 * @param code optimized code block 89 */ 90 public static void updateDexStatistics(DalvCode nonOptCode, 91 DalvCode code) { 92 if (DEBUG) { 93 System.err.println("dex insns (old/new) " 94 + nonOptCode.getInsns().codeSize() 95 + "/" + code.getInsns().codeSize() 96 + " regs (o/n) " 97 + nonOptCode.getInsns().getRegistersSize() 98 + "/" + code.getInsns().getRegistersSize() 99 ); 100 } 101 102 dexRunningDeltaInsns 103 += (code.getInsns().codeSize() 104 - nonOptCode.getInsns().codeSize()); 105 106 dexRunningDeltaRegisters 107 += (code.getInsns().getRegistersSize() 108 - nonOptCode.getInsns().getRegistersSize()); 109 110 dexRunningTotalInsns += code.getInsns().codeSize(); 111 } 112 113 /** 114 * Updates the ROP statistics. 115 * 116 * @param nonOptRmeth non-optimized method 117 * @param rmeth optimized method 118 */ 119 public static void updateRopStatistics(RopMethod nonOptRmeth, 120 RopMethod rmeth) { 121 int oldCountInsns 122 = nonOptRmeth.getBlocks().getEffectiveInstructionCount(); 123 int oldCountRegs = nonOptRmeth.getBlocks().getRegCount(); 124 125 if (DEBUG) { 126 System.err.println("insns (old/new): " 127 + oldCountInsns + "/" 128 + rmeth.getBlocks().getEffectiveInstructionCount() 129 + " regs (o/n):" + oldCountRegs 130 + "/" + rmeth.getBlocks().getRegCount()); 131 } 132 133 int newCountInsns 134 = rmeth.getBlocks().getEffectiveInstructionCount(); 135 136 runningDeltaInsns 137 += (newCountInsns - oldCountInsns); 138 139 runningDeltaRegisters 140 += (rmeth.getBlocks().getRegCount() - oldCountRegs); 141 142 runningTotalInsns += newCountInsns; 143 } 144 145 /** 146 * Prints out the collected statistics. 147 * 148 * @param out {@code non-null;} where to output to 149 */ 150 public static void dumpStatistics(PrintStream out) { 151 out.printf("Optimizer Delta Rop Insns: %d total: %d " 152 + "(%.2f%%) Delta Registers: %d\n", 153 runningDeltaInsns, 154 runningTotalInsns, 155 (100.0 * (((float) runningDeltaInsns) 156 / (runningTotalInsns + Math.abs(runningDeltaInsns)))), 157 runningDeltaRegisters); 158 159 out.printf("Optimizer Delta Dex Insns: Insns: %d total: %d " 160 + "(%.2f%%) Delta Registers: %d\n", 161 dexRunningDeltaInsns, 162 dexRunningTotalInsns, 163 (100.0 * (((float) dexRunningDeltaInsns) 164 / (dexRunningTotalInsns 165 + Math.abs(dexRunningDeltaInsns)))), 166 dexRunningDeltaRegisters); 167 168 out.printf("Original bytecode byte count: %d\n", 169 runningOriginalBytes); 170 } 171} 172