summaryrefslogtreecommitdiffstats
path: root/dx/src/com/android/dx/command/dump/BlockDumper.java
diff options
context:
space:
mode:
Diffstat (limited to 'dx/src/com/android/dx/command/dump/BlockDumper.java')
-rw-r--r--dx/src/com/android/dx/command/dump/BlockDumper.java360
1 files changed, 0 insertions, 360 deletions
diff --git a/dx/src/com/android/dx/command/dump/BlockDumper.java b/dx/src/com/android/dx/command/dump/BlockDumper.java
deleted file mode 100644
index 0be2fb402..000000000
--- a/dx/src/com/android/dx/command/dump/BlockDumper.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.command.dump;
-
-import com.android.dx.cf.attrib.AttCode;
-import com.android.dx.cf.code.BasicBlocker;
-import com.android.dx.cf.code.ByteBlock;
-import com.android.dx.cf.code.ByteBlockList;
-import com.android.dx.cf.code.ByteCatchList;
-import com.android.dx.cf.code.BytecodeArray;
-import com.android.dx.cf.code.ConcreteMethod;
-import com.android.dx.cf.code.Ropper;
-import com.android.dx.cf.direct.CodeObserver;
-import com.android.dx.cf.direct.DirectClassFile;
-import com.android.dx.cf.direct.StdAttributeFactory;
-import com.android.dx.cf.iface.Member;
-import com.android.dx.cf.iface.Method;
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.InsnList;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.DexTranslationAdvice;
-import com.android.dx.rop.code.TranslationAdvice;
-import com.android.dx.rop.code.AccessFlags;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.ssa.Optimizer;
-import com.android.dx.util.ByteArray;
-import com.android.dx.util.Hex;
-import com.android.dx.util.IntList;
-
-import java.io.PrintStream;
-
-/**
- * Utility to dump basic block info from methods in a human-friendly form.
- */
-public class BlockDumper
- extends BaseDumper {
- /** whether or not to registerize (make rop blocks) */
- private boolean rop;
-
- /**
- * null-ok; the class file object being constructed; becomes non-null
- * during {@link #dump}
- */
- protected DirectClassFile classFile;
-
- /** null-ok; most recently parsed code attribute */
- private AttCode codeAtt;
-
- /** whether or not to suppress dumping */
- protected boolean suppressDump;
-
- /** whether this is the first method being dumped */
- private boolean first;
-
- /** whether or not to run the ssa optimziations */
- private boolean optimize;
-
- /**
- * Dumps the given array, interpreting it as a class file and dumping
- * methods with indications of block-level stuff.
- *
- * @param bytes non-null; bytes of the (alleged) class file
- * @param out non-null; where to dump to
- * passed in as <= 0
- * @param filePath the file path for the class, excluding any base
- * directory specification
- * @param rop whether or not to registerize (make rop blocks)
- * @param args commandline parsedArgs
- */
- public static void dump(byte[] bytes, PrintStream out,
- String filePath, boolean rop, Args args) {
- BlockDumper bd =
- new BlockDumper(bytes, out, filePath,
- rop, args);
- bd.dump();
- }
-
- /**
- * Constructs an instance. This class is not publicly instantiable.
- * Use {@link #dump}.
- */
- BlockDumper(byte[] bytes, PrintStream out,
- String filePath,
- boolean rop, Args args) {
- super(bytes, out, filePath, args);
-
- this.rop = rop;
- this.classFile = null;
- this.codeAtt = null;
- this.suppressDump = true;
- this.first = true;
- this.optimize = args.optimize;
- }
-
- /**
- * Does the dumping.
- */
- public void dump() {
- byte[] bytes = getBytes();
- ByteArray ba = new ByteArray(bytes);
-
- /*
- * First, parse the file completely, so we can safely refer to
- * attributes, etc.
- */
- classFile = new DirectClassFile(ba, getFilePath(), getStrictParse());
- classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);
- classFile.getMagic(); // Force parsing to happen.
-
- // Next, reparse it and observe the process.
- DirectClassFile liveCf =
- new DirectClassFile(ba, getFilePath(), getStrictParse());
- liveCf.setAttributeFactory(StdAttributeFactory.THE_ONE);
- liveCf.setObserver(this);
- liveCf.getMagic(); // Force parsing to happen.
- }
-
- /** {@inheritDoc} */
- @Override
- public void changeIndent(int indentDelta) {
- if (!suppressDump) {
- super.changeIndent(indentDelta);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public void parsed(ByteArray bytes, int offset, int len, String human) {
- if (!suppressDump) {
- super.parsed(bytes, offset, len, human);
- }
- }
-
- /**
- * @param name method name
- * @return true if this method should be dumped
- */
- protected boolean shouldDumpMethod(String name) {
- return args.method == null || args.method.equals(name);
- }
-
- /** {@inheritDoc} */
- @Override
- public void startParsingMember(ByteArray bytes, int offset, String name,
- String descriptor) {
- if (descriptor.indexOf('(') < 0) {
- // It's a field, not a method
- return;
- }
-
- if (!shouldDumpMethod(name)) {
- return;
- }
-
- // Reset the dump cursor to the start of the method.
- setAt(bytes, offset);
-
- suppressDump = false;
-
- if (first) {
- first = false;
- } else {
- parsed(bytes, offset, 0, "\n");
- }
-
- parsed(bytes, offset, 0, "method " + name + " " + descriptor);
- suppressDump = true;
- }
-
- /** {@inheritDoc} */
- @Override
- public void endParsingMember(ByteArray bytes, int offset, String name,
- String descriptor, Member member) {
- if (!(member instanceof Method)) {
- return;
- }
-
- if (!shouldDumpMethod(name)) {
- return;
- }
-
- ConcreteMethod meth = new ConcreteMethod((Method) member, classFile,
- true, true);
-
- if (rop) {
- ropDump(meth);
- } else {
- regularDump(meth);
- }
- }
-
- /**
- * Does a regular basic block dump.
- *
- * @param meth non-null; method data to dump
- */
- private void regularDump(ConcreteMethod meth) {
- BytecodeArray code = meth.getCode();
- ByteArray bytes = code.getBytes();
- ByteBlockList list = BasicBlocker.identifyBlocks(meth);
- int sz = list.size();
- CodeObserver codeObserver = new CodeObserver(bytes, BlockDumper.this);
-
- // Reset the dump cursor to the start of the bytecode
- setAt(bytes, 0);
-
- suppressDump = false;
-
- int byteAt = 0;
- for (int i = 0; i < sz; i++) {
- ByteBlock bb = list.get(i);
- int start = bb.getStart();
- int end = bb.getEnd();
-
- if (byteAt < start) {
- parsed(bytes, byteAt, start - byteAt,
- "dead code " + Hex.u2(byteAt) + ".." + Hex.u2(start));
- }
-
- parsed(bytes, start, 0,
- "block " + Hex.u2(bb.getLabel()) + ": " +
- Hex.u2(start) + ".." + Hex.u2(end));
- changeIndent(1);
-
- int len;
- for (int j = start; j < end; j += len) {
- len = code.parseInstruction(j, codeObserver);
- codeObserver.setPreviousOffset(j);
- }
-
- IntList successors = bb.getSuccessors();
- int ssz = successors.size();
- if (ssz == 0) {
- parsed(bytes, end, 0, "returns");
- } else {
- for (int j = 0; j < ssz; j++) {
- int succ = successors.get(j);
- parsed(bytes, end, 0, "next " + Hex.u2(succ));
- }
- }
-
- ByteCatchList catches = bb.getCatches();
- int csz = catches.size();
- for (int j = 0; j < csz; j++) {
- ByteCatchList.Item one = catches.get(j);
- CstType exceptionClass = one.getExceptionClass();
- parsed(bytes, end, 0,
- "catch " +
- ((exceptionClass == CstType.OBJECT) ? "<any>" :
- exceptionClass.toHuman()) + " -> " +
- Hex.u2(one.getHandlerPc()));
- }
-
- changeIndent(-1);
- byteAt = end;
- }
-
- int end = bytes.size();
- if (byteAt < end) {
- parsed(bytes, byteAt, end - byteAt,
- "dead code " + Hex.u2(byteAt) + ".." + Hex.u2(end));
- }
-
- suppressDump = true;
- }
-
- /**
- * Does a registerizing dump.
- *
- * @param meth non-null; method data to dump
- */
- private void ropDump(ConcreteMethod meth) {
- BytecodeArray code = meth.getCode();
- ByteArray bytes = code.getBytes();
-
- TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
-
- RopMethod rmeth =
- Ropper.convert(meth, advice);
- StringBuffer sb = new StringBuffer(2000);
-
- if (optimize) {
- boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
-
- int paramWidth = computeParamWidth(meth, isStatic);
- rmeth = Optimizer.optimize(rmeth, paramWidth, isStatic, true,
- advice);
- }
-
- BasicBlockList blocks = rmeth.getBlocks();
-
- sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n");
-
- int sz = blocks.size();
- for (int i = 0; i < sz; i++) {
- BasicBlock bb = blocks.get(i);
- int label = bb.getLabel();
- sb.append("block ");
- sb.append(Hex.u2(label));
- sb.append("\n");
-
- IntList preds = rmeth.labelToPredecessors(label);
- int psz = preds.size();
- for (int j = 0; j < psz; j++) {
- sb.append(" pred ");
- sb.append(Hex.u2(preds.get(j)));
- sb.append("\n");
- }
-
- InsnList il = bb.getInsns();
- int ilsz = il.size();
- for (int j = 0; j < ilsz; j++) {
- Insn one = il.get(j);
- sb.append(" ");
- sb.append(il.get(j).toHuman());
- sb.append("\n");
- }
-
- IntList successors = bb.getSuccessors();
- int ssz = successors.size();
- if (ssz == 0) {
- sb.append(" returns\n");
- } else {
- int primary = bb.getPrimarySuccessor();
- for (int j = 0; j < ssz; j++) {
- int succ = successors.get(j);
- sb.append(" next ");
- sb.append(Hex.u2(succ));
-
- if ((ssz != 1) && (succ == primary)) {
- sb.append(" *");
- }
-
- sb.append("\n");
- }
- }
- }
-
- suppressDump = false;
- setAt(bytes, 0);
- parsed(bytes, 0, bytes.size(), sb.toString());
- suppressDump = true;
- }
-}