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 import java.io.PrintStream; 22 23 /** 24 * Static methods and variables for collecting statistics on generated 25 * code. 26 */ 27 public 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 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 int runningDeltaInsns = 0; 42 43 /** running sum of the total number of Rop insns processed */ 44 public 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 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 int dexRunningDeltaInsns = 0; 58 59 /** 60 * running sum of the total number of dex insns (actually code 61 * units) processed 62 */ 63 public int dexRunningTotalInsns = 0; 64 65 /** running sum of original class bytecode bytes */ 66 public int runningOriginalBytes = 0; 67 68 /** 69 * Updates the number of original bytecode bytes processed. 70 * 71 * @param count {@code >= 0;} the number of bytes to add 72 */ updateOriginalByteCount(int count)73 public void updateOriginalByteCount(int count) { 74 runningOriginalBytes += count; 75 } 76 77 /** 78 * Updates the dex statistics. 79 * 80 * @param nonOptCode non-optimized code block 81 * @param code optimized code block 82 */ updateDexStatistics(DalvCode nonOptCode, DalvCode code)83 public void updateDexStatistics(DalvCode nonOptCode, 84 DalvCode code) { 85 if (DEBUG) { 86 System.err.println("dex insns (old/new) " 87 + nonOptCode.getInsns().codeSize() 88 + "/" + code.getInsns().codeSize() 89 + " regs (o/n) " 90 + nonOptCode.getInsns().getRegistersSize() 91 + "/" + code.getInsns().getRegistersSize() 92 ); 93 } 94 95 dexRunningDeltaInsns 96 += (code.getInsns().codeSize() 97 - nonOptCode.getInsns().codeSize()); 98 99 dexRunningDeltaRegisters 100 += (code.getInsns().getRegistersSize() 101 - nonOptCode.getInsns().getRegistersSize()); 102 103 dexRunningTotalInsns += code.getInsns().codeSize(); 104 } 105 106 /** 107 * Updates the ROP statistics. 108 * 109 * @param nonOptRmeth non-optimized method 110 * @param rmeth optimized method 111 */ updateRopStatistics(RopMethod nonOptRmeth, RopMethod rmeth)112 public void updateRopStatistics(RopMethod nonOptRmeth, 113 RopMethod rmeth) { 114 int oldCountInsns 115 = nonOptRmeth.getBlocks().getEffectiveInstructionCount(); 116 int oldCountRegs = nonOptRmeth.getBlocks().getRegCount(); 117 118 if (DEBUG) { 119 System.err.println("insns (old/new): " 120 + oldCountInsns + "/" 121 + rmeth.getBlocks().getEffectiveInstructionCount() 122 + " regs (o/n):" + oldCountRegs 123 + "/" + rmeth.getBlocks().getRegCount()); 124 } 125 126 int newCountInsns 127 = rmeth.getBlocks().getEffectiveInstructionCount(); 128 129 runningDeltaInsns 130 += (newCountInsns - oldCountInsns); 131 132 runningDeltaRegisters 133 += (rmeth.getBlocks().getRegCount() - oldCountRegs); 134 135 runningTotalInsns += newCountInsns; 136 } 137 138 /** 139 * Prints out the collected statistics. 140 * 141 * @param out {@code non-null;} where to output to 142 */ dumpStatistics(PrintStream out)143 public void dumpStatistics(PrintStream out) { 144 out.printf("Optimizer Delta Rop Insns: %d total: %d " 145 + "(%.2f%%) Delta Registers: %d\n", 146 runningDeltaInsns, 147 runningTotalInsns, 148 (100.0 * (((float) runningDeltaInsns) 149 / (runningTotalInsns + Math.abs(runningDeltaInsns)))), 150 runningDeltaRegisters); 151 152 out.printf("Optimizer Delta Dex Insns: Insns: %d total: %d " 153 + "(%.2f%%) Delta Registers: %d\n", 154 dexRunningDeltaInsns, 155 dexRunningTotalInsns, 156 (100.0 * (((float) dexRunningDeltaInsns) 157 / (dexRunningTotalInsns 158 + Math.abs(dexRunningDeltaInsns)))), 159 dexRunningDeltaRegisters); 160 161 out.printf("Original bytecode byte count: %d\n", 162 runningOriginalBytes); 163 } 164 } 165