diff --git a/jode/jode/flow/MarkInlineExpression.java b/jode/jode/flow/MarkInlineExpression.java new file mode 100644 index 0000000..b89976d --- /dev/null +++ b/jode/jode/flow/MarkInlineExpression.java @@ -0,0 +1,139 @@ +/* + * MarkInlineExpression (c) 1998 Jochen Hoenicke + * + * You may distribute under the terms of the GNU General Public License. + * + * IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, + * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF + * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE + * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + * BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, + * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * $Id$ + */ + +package jode.flow; +import jode.Decompiler; +import jode.decompiler.*; + +/** + * This handles inline methods. When you compile with -O flag javac will + * inline methods that are static, final or private (i.e. non virtual). + * The parameters may be stored in locals, before inlining the body of the + * method. + * + * This transformation will mark the expression as inlined and + * This transformation creates expressions. It transforms + *
+ * Sequ[expr_1, Sequ[expr_2, ..., Sequ[expr_n, op] ...]] + *+ * to + *
+ * expr(op, [ expr_1, ..., expr_n ]) + *+ */ +public class MarkInlineExpression { + + /** + * This does the transformation. + * @param FlowBlock the flow block to transform. + * @return true if flow block was simplified. + */ + public static boolean transform(InstructionContainer ic, + StructuredBlock last) { + + int params = ic.getInstruction().getOperandCount(); + if (params == 0) + return false; + + ComplexExpression parent = null; + Expression inner = ic.getInstruction(); + while (inner instanceof ComplexExpression) { + parent = (ComplexExpression)inner; + inner = parent.getSubExpressions()[0]; + } + + if (!(inner instanceof Operator)) + return false; + + Operator op = (Operator)inner; + + if (!(last.outer instanceof SequentialBlock)) + return false; + SequentialBlock sequBlock = (SequentialBlock)last.outer; + + /* First check if Expression can be created, but do nothing yet. + */ + Expression lastExpression = null; + for (int i = params;;) { + + if (!(sequBlock.subBlocks[0] instanceof InstructionBlock)) + return false; + + Expression expr = + ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); + + + if (!expr.isVoid()) { + if (--i == 0) + break; + } else if (lastExpression == null + || lastExpression.canCombine(expr) <= 0) + return false; + + if (expr.getOperandCount() > 0) + /* This is a not fully resolved expression in the + * middle, we must not touch it. */ + return false; + + lastExpression = expr; + + if (!(sequBlock.outer instanceof SequentialBlock)) + return false; + sequBlock = (SequentialBlock) sequBlock.outer; + } + + /* Now, do the combination. Everything must succeed now. + */ + Expression[] exprs = new Expression[params]; + sequBlock = (SequentialBlock) last.outer; + for (int i=params; ;) { + + Expression expr = + ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); + + if (!expr.isVoid()) { + exprs[--i] = expr; + if (i == 0) + break; + } else + exprs[i] = exprs[i].combine(expr); + + sequBlock = (SequentialBlock)sequBlock.outer; + } + + if(Decompiler.isVerbose) + Decompiler.err.print('x'); + + Expression newExpr; + if (params == 1 && op instanceof NopOperator) { + exprs[0].setType(op.getType()); + newExpr = exprs[0]; + } else + newExpr = new ComplexExpression(op, exprs); + + if (parent != null) + parent.setSubExpressions(0, newExpr); + else + ic.setInstruction(newExpr); + + ic.moveDefinitions(sequBlock, last); + last.replace(sequBlock); + return true; + } +} diff --git a/jode/test/OptimizeTest.java b/jode/test/OptimizeTest.java new file mode 100644 index 0000000..1818f2a --- /dev/null +++ b/jode/test/OptimizeTest.java @@ -0,0 +1,35 @@ +public class OptimizeTest { + + public final int getInlined(String str, int i) { + return str.charAt(i); + } + + public final int getInlined(String str, int i, OptimizeTest t) { + return str.charAt(i) + t.getInlined(str, i) + i; + } + + + public int complexInline(String str, int i) { + System.err.println(""); + return str.charAt(i)+str.charAt(-i); + } + + public int notInlined(String str, int i, OptimizeTest t) { + return str.charAt(i) + t.getInlined(str, i); + } + + public void main(String[] param) { + OptimizeTest ot = new OptimizeTest(); + + System.err.println(ot.getInlined("Hallo", ot.notInlined(param[1], 10 - ot.getInlined(param[0], 0, new OptimizeTest()), ot))); + System.err.println(ot.complexInline("ollah", param.length)); + } +} + + + + + + + +