/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package EDU.purdue.cs.bloat.tree; import java.util.*; /** * AscendVisitor is the superclass of Type0Visitor and Type1Visitor, * conveniently containing the common code. It makes an upward traversal of the * tree as if it were a binary tree (nodes with more than two children, such as * a method call, are considered in a form similar to curried form). * * @author Thomas VanDrunen */ public abstract class AscendVisitor extends TreeVisitor { Hashtable defInfoMap; /* the same as the fields of Stack Optimizer */ Hashtable useInfoMap; /* of the same name */ LocalExpr start; /* where we start the search from */ Node previous; Vector visited; public AscendVisitor(final Hashtable defInfoMap, final Hashtable useInfoMap) { this.defInfoMap = defInfoMap; this.useInfoMap = useInfoMap; visited = new Vector(); } abstract public void check(Node node); public void visitTree(final Tree tree) { final ListIterator iter = tree.stmts().listIterator( tree.stmts().lastIndexOf(previous)); if (iter.hasPrevious()) { final Stmt p = (Stmt) iter.previous(); check(p); } /* * Object prev = iter.previous(); if (prev instanceof LocalExpr) * check(prev); */ } public void visitExprStmt(final ExprStmt stmt) { previous = stmt; stmt.parent().visit(this); } public void visitIfCmpStmt(final IfCmpStmt stmt) { if (stmt.right() == previous) { check(stmt.left()); } else if (stmt.left() == previous) { previous = stmt; stmt.parent().visit(this); } } public void visitIfZeroStmt(final IfZeroStmt stmt) { previous = stmt; stmt.parent.visit(this); } public void visitInitStmt(final InitStmt stmt) { final LocalExpr[] targets = stmt.targets(); for (int i = 0; i < targets.length; i++) { if (targets[i] == previous) { if (i > 0) { check(targets[i - 1]); } else { break; } } } } public void visitGotoStmt(final GotoStmt stmt) { } public void visitLabelStmt(final LabelStmt stmt) { } public void visitMonitorStmt(final MonitorStmt stmt) { previous = stmt; stmt.parent().visit(this); } public void visitPhiStmt(final PhiStmt stmt) { if (stmt instanceof PhiCatchStmt) { visitPhiCatchStmt((PhiCatchStmt) stmt); } else if (stmt instanceof PhiJoinStmt) { visitPhiJoinStmt((PhiJoinStmt) stmt); /* * else if (stmt instanceof PhiReturnStmt) * visitPhiReturnStmt((PhiReturnStmt) stmt); */ } } public void visitCatchExpr(final CatchExpr expr) { } public void visitDefExpr(final DefExpr expr) { if (expr instanceof MemExpr) { visitMemExpr((MemExpr) expr); } } public void visitStackManipStmt(final StackManipStmt stmt) { } public void visitPhiCatchStmt(final PhiCatchStmt stmt) { } public void visitPhiJoinStmt(final PhiJoinStmt stmt) { } public void visitRetStmt(final RetStmt stmt) { } public void visitReturnExprStmt(final ReturnExprStmt stmt) { previous = stmt; stmt.parent.visit(this); } public void visitReturnStmt(final ReturnStmt stmt) { } public void visitAddressStoreStmt(final AddressStoreStmt stmt) { } public void visitStoreExpr(final StoreExpr expr) { if ((expr.target() instanceof LocalExpr) || (expr.target() instanceof StaticFieldExpr)) { if (previous == expr.expr()) { // can't be target, because then // it would be a definition, for which // Type0Visitor is not called previous = expr; expr.parent.visit(this); } } else if (expr.target() instanceof ArrayRefExpr) { if (previous == expr.expr()) { check(((ArrayRefExpr) expr.target()).index()); } else if (previous == expr.target()) { previous = expr; expr.parent.visit(this); } } else if (expr.target() instanceof FieldExpr) { if (previous == expr.expr()) { check(expr.target()); } else if (previous == expr.target()) { previous = expr; expr.parent.visit(this); } } } public void visitJsrStmt(final JsrStmt stmt) { } public void visitSwitchStmt(final SwitchStmt stmt) { if (previous == stmt.index()) { previous = stmt; stmt.parent.visit(this); } } public void visitThrowStmt(final ThrowStmt stmt) { } public void visitStmt(final Stmt stmt) { } public void visitSCStmt(final SCStmt stmt) { } public void visitSRStmt(final SRStmt stmt) { } public void visitArithExpr(final ArithExpr expr) { if (previous == expr.left()) { previous = expr; expr.parent.visit(this); } else if (previous == expr.right()) { check(expr.left()); } } public void visitArrayLengthExpr(final ArrayLengthExpr expr) { } public void visitMemExpr(final MemExpr expr) { if (expr instanceof MemRefExpr) { visitMemRefExpr((MemRefExpr) expr); } else if (expr instanceof VarExpr) { visitVarExpr((VarExpr) expr); } } public void visitMemRefExpr(final MemRefExpr expr) { if (expr instanceof FieldExpr) { visitFieldExpr((FieldExpr) expr); } else if (expr instanceof StaticFieldExpr) { visitStaticFieldExpr((StaticFieldExpr) expr); } else if (expr instanceof ArrayRefExpr) { visitArrayRefExpr((ArrayRefExpr) expr); } } public void visitArrayRefExpr(final ArrayRefExpr expr) { if (previous == expr.array()) { // the array reference is like the previous = expr; // left child expr.parent().visit(this); } else if (previous == expr.index()) { check(expr.array()); // right child } } public void visitCallExpr(final CallExpr expr) { if (expr instanceof CallMethodExpr) { visitCallMethodExpr((CallMethodExpr) expr); } if (expr instanceof CallStaticExpr) { visitCallStaticExpr((CallStaticExpr) expr); } } public void visitCallMethodExpr(final CallMethodExpr expr) { if (previous == expr.receiver()) { previous = expr; expr.parent.visit(this); } else { final Expr[] params = expr.params(); for (int i = 0; i < params.length; i++) { if (params[i] == previous) { if (i > 0) { check(params[i - 1]); } else { check(expr.receiver()); } } } } } public void visitCallStaticExpr(final CallStaticExpr expr) { final Expr[] params = expr.params(); for (int i = 0; i < params.length; i++) { if (params[i] == previous) { if (i > 0) { check(params[i - 1]); } else { previous = expr; expr.parent().visit(this); } break; } } } public void visitCastExpr(final CastExpr expr) { previous = expr; expr.parent.visit(this); } public void visitConstantExpr(final ConstantExpr expr) { } public void visitFieldExpr(final FieldExpr expr) { if (previous == expr.object()) { previous = expr; expr.parent.visit(this); } } public void visitInstanceOfExpr(final InstanceOfExpr expr) { if (previous == expr.expr()) { previous = expr; expr.parent.visit(this); } } public void visitLocalExpr(final LocalExpr expr) { } public void visitNegExpr(final NegExpr expr) { if (previous == expr.expr()) { previous = expr; expr.parent.visit(this); } } public void visitNewArrayExpr(final NewArrayExpr expr) { if (previous == expr.size()) { previous = expr; expr.parent.visit(this); } } public void visitNewExpr(final NewExpr expr) { } public void visitNewMultiArrayExpr(final NewMultiArrayExpr expr) { final Expr[] dims = expr.dimensions; for (int i = 0; i < dims.length; i++) { if (dims[i] == previous) { if (i > 0) { check(dims[i - 1]); } else { previous = expr; expr.parent().visit(this); } } } } public void visitCheckExpr(final CheckExpr expr) { if (expr instanceof ZeroCheckExpr) { visitZeroCheckExpr((ZeroCheckExpr) expr); } else if (expr instanceof RCExpr) { visitRCExpr((RCExpr) expr); } else if (expr instanceof UCExpr) { visitUCExpr((UCExpr) expr); } } public void visitZeroCheckExpr(final ZeroCheckExpr expr) { /* * if (previous == expr.expr()) { previous = expr; * expr.parent.visit(this); } */ } public void visitRCExpr(final RCExpr expr) { } public void visitUCExpr(final UCExpr expr) { } public void visitReturnAddressExpr(final ReturnAddressExpr expr) { } public void visitShiftExpr(final ShiftExpr expr) { if (previous == expr.expr()) { // the expression to be shifted is like previous = expr; // the left child expr.parent().visit(this); } else if (previous == expr.bits()) { check(expr.expr()); // the right child } } public void visitStackExpr(final StackExpr expr) { } public void visitVarExpr(final VarExpr expr) { if (expr instanceof LocalExpr) { visitLocalExpr((LocalExpr) expr); } if (expr instanceof StackExpr) { visitStackExpr((StackExpr) expr); } } public void visitStaticFieldExpr(final StaticFieldExpr expr) { } public void visitExpr(final Expr expr) { } public void visitNode(final Node node) { } }