/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
Copyright (C) 2005-2008, Martin Schoeberl (martin@jopdesign.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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/>.
*/
/*
* Created on 04.06.2005
*
*/
package com.jopdesign.build;
import java.util.Iterator;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.Constant;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.CPInstruction;
import org.apache.bcel.generic.CodeExceptionGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.util.InstructionFinder;
/**
* Create a usefull constant pool mapping and change the index in the
* instructions.
*
* @author Flavius, Martin
*
*
*/
public class FindUsedConstants extends JOPizerVisitor {
private ConstantPoolGen cpool;
public FindUsedConstants(OldAppInfo jz) {
super(jz);
}
public void visitJavaClass(JavaClass clazz) {
super.visitJavaClass(clazz);
cpool = new ConstantPoolGen(clazz.getConstantPool());
Method[] methods = clazz.getMethods();
for(int i=0; i < methods.length; i++) {
if(!(methods[i].isAbstract() || methods[i].isNative())) {
// methods[i] = find(methods[i]);
find(methods[i]);
}
}
// clazz.setConstantPool(cpoolNew.getConstantPool());
//System.out.println(clazz.getConstantPool());
}
private void find(Method method) {
MethodGen mg = new MethodGen(method, clazz.getClassName(), cpool);
InstructionList il = mg.getInstructionList();
InstructionFinder f = new InstructionFinder(il);
// find instructions that access the constant pool
// collect all indices to constants in ClassInfo
String cpInstr = "CPInstruction";
for(Iterator it = f.search(cpInstr); it.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[])it.next();
InstructionHandle first = match[0];
CPInstruction ii = (CPInstruction)first.getInstruction();
int idx = ii.getIndex();
Constant co = cpool.getConstant(idx);
int len = 1;
switch(co.getTag()) {
case Constants.CONSTANT_Long:
case Constants.CONSTANT_Double:
len = 2;
break;
}
// System.out.println(co+" "+idx+" "+len);
// we don't need the field references in the cpool anymore
if (co.getTag()!=Constants.CONSTANT_Fieldref) {
getCli().addUsedConst(idx, len);
}
// also modify the index!
// Constant cnst = cpool.getConstant(ii.getIndex());
// int newIndex = addConstant(cnst);
//System.out.println(ii+" -> "+newIndex);
// ii.setIndex(newIndex);
}
il.dispose();
CodeExceptionGen[] et = mg.getExceptionHandlers();
for (int i = 0; i < et.length; i++) {
ObjectType ctype = et[i].getCatchType();
if (ctype != null) {
getCli().addUsedConst(cpool.lookupClass(ctype.getClassName()), 1);
}
}
}
}