SsaDumper.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
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.command.dump; 18 19import com.android.dx.cf.code.ConcreteMethod; 20import com.android.dx.cf.code.Ropper; 21import com.android.dx.cf.iface.Member; 22import com.android.dx.cf.iface.Method; 23import com.android.dx.rop.code.RopMethod; 24import com.android.dx.rop.code.TranslationAdvice; 25import com.android.dx.rop.code.DexTranslationAdvice; 26import com.android.dx.rop.code.AccessFlags; 27import com.android.dx.ssa.DeadCodeRemover; 28import com.android.dx.ssa.PhiTypeResolver; 29import com.android.dx.ssa.SsaBasicBlock; 30import com.android.dx.ssa.SsaConverter; 31import com.android.dx.ssa.SsaInsn; 32import com.android.dx.ssa.SsaMethod; 33import com.android.dx.ssa.Optimizer; 34import com.android.dx.ssa.ConstCollector; 35import com.android.dx.ssa.SCCP; 36import com.android.dx.ssa.LiteralOpUpgrader; 37import com.android.dx.ssa.back.SsaToRop; 38import com.android.dx.util.ByteArray; 39import com.android.dx.util.Hex; 40import com.android.dx.util.IntList; 41 42import java.io.PrintStream; 43import java.util.BitSet; 44import java.util.EnumSet; 45 46public class SsaDumper extends BlockDumper { 47 48 public static void dump(byte[] bytes, PrintStream out, 49 String filePath, Args args) { 50 51 SsaDumper sd = 52 new SsaDumper(bytes, out, filePath, args); 53 sd.dump(); 54 } 55 56 SsaDumper(byte[] bytes, PrintStream out, String filePath, Args args) { 57 58 super(bytes, out, filePath, true, args); 59 60 } 61 62 /** {@inheritDoc} */ 63 @Override 64 public void endParsingMember(ByteArray bytes, int offset, String name, 65 String descriptor, Member member) { 66 if (!(member instanceof Method)) { 67 return; 68 } 69 70 if (!shouldDumpMethod(name)) { 71 return; 72 } 73 74 ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, 75 true, true); 76 77 TranslationAdvice advice = DexTranslationAdvice.THE_ONE; 78 79 RopMethod rmeth = Ropper.convert(meth, advice); 80 81 SsaMethod ssaMeth = null; 82 83 boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); 84 int paramWidth = computeParamWidth(meth, isStatic); 85 if (args.ssaStep == null) { 86 ssaMeth = Optimizer.debugNoRegisterAllocation(rmeth, 87 paramWidth, isStatic, true, advice, 88 EnumSet.allOf(Optimizer.OptionalStep.class)); 89 } else if ("edge-split".equals(args.ssaStep)) { 90 ssaMeth = Optimizer.debugEdgeSplit(rmeth, paramWidth, 91 isStatic, true, advice); 92 } else if ("phi-placement".equals(args.ssaStep)) { 93 ssaMeth = Optimizer.debugPhiPlacement( 94 rmeth, paramWidth, isStatic, true, advice); 95 } else if ("renaming".equals(args.ssaStep)) { 96 ssaMeth = Optimizer.debugRenaming( 97 rmeth, paramWidth, isStatic, true, advice); 98 } else if ("dead-code".equals(args.ssaStep)) { 99 ssaMeth = Optimizer.debugDeadCodeRemover( 100 rmeth, paramWidth, isStatic,true, advice); 101 } 102 103 StringBuffer sb = new StringBuffer(2000); 104 105 sb.append("first "); 106 sb.append(Hex.u2( 107 ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex()))); 108 sb.append('\n'); 109 110 for (SsaBasicBlock block : ssaMeth.getBlocks()) { 111 sb.append("block ") 112 .append(Hex.u2(block.getRopLabel())).append('\n'); 113 114 BitSet preds = block.getPredecessors(); 115 116 for(int i=preds.nextSetBit(0); i>=0; i=preds.nextSetBit(i+1)) { 117 sb.append (" pred "); 118 sb.append (Hex.u2(ssaMeth.blockIndexToRopLabel(i))); 119 sb.append('\n'); 120 } 121 122 sb.append (" live in:" + block.getLiveInRegs()); 123 sb.append ("\n"); 124 125 for (SsaInsn insn: block.getInsns()) { 126 sb.append(" "); 127 sb.append(insn.toHuman()); 128 sb.append('\n'); 129 } 130 131 if (block.getSuccessors().cardinality() == 0) { 132 sb.append (" returns\n"); 133 } else { 134 int primary = block.getPrimarySuccessorRopLabel(); 135 136 IntList succLabelList = block.getRopLabelSuccessorList(); 137 138 int szSuccLabels = succLabelList.size(); 139 140 for (int i = 0; i < szSuccLabels; i++) { 141 sb.append (" next "); 142 sb.append (Hex.u2(succLabelList.get(i))); 143 144 if (szSuccLabels != 1 && primary == succLabelList.get(i)) { 145 sb.append (" *"); 146 } 147 sb.append('\n'); 148 } 149 } 150 151 sb.append (" live out:" + block.getLiveOutRegs()); 152 sb.append ("\n"); 153 } 154 155 suppressDump = false; 156 setAt(bytes, 0); 157 parsed(bytes, 0, bytes.size(), sb.toString()); 158 suppressDump = true; 159 } 160} 161