use of org.apache.bcel.util.InstructionFinder in project jop by jop-devel.
the class ClinitOrder method findDependencies.
private Set<ClassInfo> findDependencies(MethodInfo method, boolean inRec) {
// System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
Set<ClassInfo> depends = new HashSet<ClassInfo>();
if (method.isNative() || method.isAbstract()) {
// subclasses???? :-(
return depends;
}
ClassInfo classInfo = method.getClassInfo();
ConstantPoolGen cpoolgen = method.getConstantPoolGen();
InstructionList il = method.getCode().getInstructionList();
InstructionFinder f = new InstructionFinder(il);
// TODO can we encounter an empty instruction list?
//if(il.getStart() == null) {
// return depends;
//}
// 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 = cpoolgen.getConstant(idx);
ClassRef classRef = null;
Set addDepends = null;
ClassInfo clinfo;
MethodInfo minfo;
switch(co.getTag()) {
case Constants.CONSTANT_Class:
classRef = classInfo.getConstantInfo(co).getClassRef();
clinfo = classRef.getClassInfo();
if (clinfo != null) {
minfo = clinfo.getMethodInfo("<init>()V");
if (minfo != null) {
addDepends = findDependencies(minfo, true);
}
}
break;
case Constants.CONSTANT_Fieldref:
case Constants.CONSTANT_InterfaceMethodref:
classRef = classInfo.getConstantInfo(co).getClassRef();
break;
case Constants.CONSTANT_Methodref:
ConstantMethodInfo mref = (ConstantMethodInfo) classInfo.getConstantInfo(co);
classRef = mref.getClassRef();
minfo = mref.getMethodRef().getMethodInfo();
if (minfo != null) {
addDepends = findDependencies(minfo, true);
}
break;
}
if (classRef != null) {
ClassInfo clinf = classRef.getClassInfo();
if (clinf != null) {
if (clinf.getMethodInfo(clinitSig) != null) {
// don't add myself as dependency
if (!clinf.equals(method.getClassInfo())) {
depends.add(clinf);
}
}
}
}
if (addDepends != null) {
for (Object addDepend : addDepends) {
ClassInfo addCli = (ClassInfo) addDepend;
if (addCli.equals(method.getClassInfo())) {
throw new JavaClassFormatError("cyclic indirect <clinit> dependency");
}
depends.add(addCli);
}
}
}
return depends;
}
use of org.apache.bcel.util.InstructionFinder in project jop by jop-devel.
the class OldClinitOrder method findDependencies.
private Set findDependencies(OldClassInfo cli, OldMethodInfo mi, boolean inRec) {
// System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
Method method = mi.getMethod();
Set depends = new HashSet();
if (method.isNative() || method.isAbstract()) {
// subclasses???? :-(
return depends;
}
ConstantPool cpool = cli.clazz.getConstantPool();
ConstantPoolGen cpoolgen = new ConstantPoolGen(cpool);
MethodGen mg = new MethodGen(method, cli.clazz.getClassName(), cpoolgen);
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);
ConstantClass cocl = null;
Set addDepends = null;
String clname;
OldClassInfo clinfo;
OldMethodInfo minfo;
switch(co.getTag()) {
case Constants.CONSTANT_Class:
cocl = (ConstantClass) co;
clname = cocl.getBytes(cpool).replace('/', '.');
clinfo = (OldClassInfo) ai.cliMap.get(clname);
if (clinfo != null) {
minfo = clinfo.getMethodInfo("<init>()V");
if (minfo != null) {
addDepends = findDependencies(clinfo, minfo, true);
}
}
break;
case Constants.CONSTANT_InterfaceMethodref:
cocl = (ConstantClass) cpool.getConstant(((ConstantInterfaceMethodref) co).getClassIndex());
break;
case Constants.CONSTANT_Methodref:
cocl = (ConstantClass) cpool.getConstant(((ConstantMethodref) co).getClassIndex());
clname = cocl.getBytes(cpool).replace('/', '.');
clinfo = (OldClassInfo) ai.cliMap.get(clname);
int sigidx = ((ConstantMethodref) co).getNameAndTypeIndex();
ConstantNameAndType signt = (ConstantNameAndType) cpool.getConstant(sigidx);
String sigstr = signt.getName(cpool) + signt.getSignature(cpool);
if (clinfo != null) {
minfo = clinfo.getMethodInfo(sigstr);
if (minfo != null) {
addDepends = findDependencies(clinfo, minfo, true);
}
}
break;
case Constants.CONSTANT_Fieldref:
cocl = (ConstantClass) cpool.getConstant(((ConstantFieldref) co).getClassIndex());
break;
}
if (cocl != null) {
clname = cocl.getBytes(cpool).replace('/', '.');
OldClassInfo clinf = (OldClassInfo) ai.cliMap.get(clname);
if (clinf != null) {
if (clinf.getMethodInfo(OldAppInfo.clinitSig) != null) {
// don't add myself as dependency
if (clinf != cli) {
depends.add(clinf);
}
}
}
}
if (addDepends != null) {
Iterator itAddDep = addDepends.iterator();
while (itAddDep.hasNext()) {
OldClassInfo addCli = (OldClassInfo) itAddDep.next();
if (addCli == cli) {
throw new Error("cyclic indirect <clinit> dependency");
}
depends.add(addCli);
}
}
}
il.dispose();
return depends;
}
use of org.apache.bcel.util.InstructionFinder in project jop by jop-devel.
the class ReplaceAtomicAnnotation method transform.
public static Method transform(Method m, JavaClass clazz, ConstantPoolGen _cp) {
MethodGen method = new MethodGen(m, clazz.getClassName(), _cp);
InstructionList oldIl = method.getInstructionList();
Type returnType = m.getReturnType();
if (returnType.equals(Type.LONG) || returnType.equals(Type.DOUBLE)) {
throw new UnsupportedOperationException();
}
final int transactionLocals = 2;
/*
* local variable indices:
* isNotNestedTransaction is -2+2
* result is -2+3
* Throwable e is -2+3
*/
final int maxLocals = method.getMaxLocals();
final int transactionLocalsBaseIndex = maxLocals;
final int copyBaseIndex = transactionLocalsBaseIndex + transactionLocals;
SortedSet<Integer> modifiedArguments = getModifiedArguments(method);
// maps modified arguments indices to copies
Map<Integer, Integer> modifiedArgumentsCopies = new TreeMap<Integer, Integer>();
{
int copyIndex = copyBaseIndex;
for (Integer i : modifiedArguments) {
System.out.println("RTTM: method " + method.getClassName() + "." + method.getName() + method.getSignature() + ": saving argument " + i + " to variable " + copyIndex);
modifiedArgumentsCopies.put(i, copyIndex++);
}
}
InstructionList il = new InstructionList();
InstructionFactory _factory = new InstructionFactory(_cp);
method.setInstructionList(il);
{
// InstructionHandle ih_0 = il.append(new PUSH(_cp, -559038737));
// il.append(_factory.createStore(Type.INT, transactionLocalsBaseIndex-2+1));
InstructionHandle ih_3 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
il.append(new PUSH(_cp, -122));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
il.append(InstructionConstants.BALOAD);
BranchInstruction ifne_12 = InstructionFactory.createBranchInstruction(Constants.IFNE, null);
il.append(ifne_12);
il.append(new PUSH(_cp, 1));
BranchInstruction goto_16 = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
il.append(goto_16);
InstructionHandle ih_19 = il.append(new PUSH(_cp, 0));
InstructionHandle ih_20 = il.append(InstructionFactory.createStore(Type.INT, transactionLocalsBaseIndex - 2 + 2));
InstructionHandle ih_21 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
BranchInstruction ifeq_22 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifeq_22);
// InstructionHandle ih_25 = il.append(_factory.createLoad(Type.INT, transactionLocalsBaseIndex-2+0));
// il.append(_factory.createStore(Type.INT, transactionLocalsBaseIndex-2+1));
{
// only save arguments which might be modified
for (int i : modifiedArguments) {
il.append(InstructionFactory.createLoad(Type.INT, i));
il.append(InstructionFactory.createStore(Type.INT, modifiedArgumentsCopies.get(i)));
}
}
InstructionHandle ih_27 = il.append(new PUSH(_cp, 0));
il.append(new PUSH(_cp, -128));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wr", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
InstructionHandle ih_33 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
il.append(new PUSH(_cp, -122));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
il.append(new PUSH(_cp, 1));
il.append(InstructionConstants.BASTORE);
// transaction loop
InstructionHandle ih_43 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
BranchInstruction ifeq_44 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifeq_44);
InstructionHandle ih_47 = il.append(new PUSH(_cp, 1));
il.append(new PUSH(_cp, Const.MEM_TM_MAGIC));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wrMem", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
// InstructionHandle ih_53 = il.append(_factory.createLoad(Type.INT, transactionLocalsBaseIndex-2+0));
// il.append(_factory.createInvoke("rttm.swtest.Transaction", "atomicSection", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
// il.append(_factory.createStore(Type.INT, transactionLocalsBaseIndex-2+3));
InstructionHandle ih_53 = oldIl.getStart();
Collection<BranchInstruction> gotos_transactionCommit = new ArrayList<BranchInstruction>();
{
// redirect returns
InstructionFinder f = new InstructionFinder(oldIl);
String returnInstructionsPattern = "ARETURN|IRETURN|FRETURN|RETURN";
for (Iterator i = f.search(returnInstructionsPattern); i.hasNext(); ) {
InstructionHandle oldIh = ((InstructionHandle[]) i.next())[0];
InstructionList nl = new InstructionList();
if (!method.getReturnType().equals(Type.VOID)) {
nl.append(InstructionFactory.createStore(method.getReturnType(), transactionLocalsBaseIndex - 2 + 3));
}
BranchInstruction goto_transactionCommit = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
nl.append(goto_transactionCommit);
gotos_transactionCommit.add(goto_transactionCommit);
InstructionHandle newTarget = nl.getStart();
oldIl.append(oldIh, nl);
try {
oldIl.delete(oldIh);
} catch (TargetLostException e) {
InstructionHandle[] targets = e.getTargets();
for (int k = 0; k < targets.length; k++) {
InstructionTargeter[] targeters = targets[k].getTargeters();
for (int j = 0; j < targeters.length; j++) {
targeters[j].updateTarget(targets[k], newTarget);
}
}
}
}
il.append(oldIl);
}
InstructionHandle ih_58 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
BranchInstruction ifeq_59 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifeq_59);
InstructionHandle ih_62 = il.append(new PUSH(_cp, 0));
il.append(new PUSH(_cp, Const.MEM_TM_MAGIC));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wrMem", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
InstructionHandle ih_68 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
il.append(new PUSH(_cp, -122));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
il.append(new PUSH(_cp, 0));
il.append(InstructionConstants.BASTORE);
InstructionHandle ih_78 = il.append(new PUSH(_cp, 1));
il.append(new PUSH(_cp, -128));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wr", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
// InstructionHandle ih_84 = il.append(_factory.createLoad(Type.INT, transactionLocalsBaseIndex-2+3));
// il.append(_factory.createReturn(Type.INT));
InstructionHandle ih_84;
{
// return
if (!method.getReturnType().equals(Type.VOID)) {
ih_84 = il.append(InstructionFactory.createLoad(method.getReturnType(), transactionLocalsBaseIndex - 2 + 3));
il.append(InstructionFactory.createReturn(method.getReturnType()));
} else {
ih_84 = il.append(InstructionFactory.createReturn(method.getReturnType()));
}
}
// catch block
// variable e has index 3
// } catch (Throwable e) {
InstructionHandle nih_86 = il.append(InstructionFactory.createStore(Type.OBJECT, transactionLocalsBaseIndex - 2 + 3));
// if (isNotNestedTransaction) {
InstructionHandle nih_87 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
BranchInstruction ifeq_88 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifeq_88);
InstructionHandle nih_91 = il.append(InstructionFactory.createLoad(Type.OBJECT, transactionLocalsBaseIndex - 2 + 3));
il.append(_factory.createFieldAccess("com.jopdesign.sys.RetryException", "instance", new ObjectType("com.jopdesign.sys.RetryException"), Constants.GETSTATIC));
BranchInstruction if_acmpne_95 = InstructionFactory.createBranchInstruction(Constants.IF_ACMPNE, null);
il.append(if_acmpne_95);
// InstructionHandle nih_98 = il.append(_factory.createLoad(Type.INT,
// 1));
// il.append(_factory.createStore(Type.INT, 0));
{
for (int i : modifiedArguments) {
il.append(InstructionFactory.createLoad(Type.INT, modifiedArgumentsCopies.get(i)));
il.append(InstructionFactory.createStore(Type.INT, i));
}
}
BranchInstruction goto_110 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_43);
InstructionHandle ih_110 = il.append(goto_110);
// exception was manually aborted or a bug triggered
InstructionHandle nih_103 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
il.append(new PUSH(_cp, -122));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
il.append(new PUSH(_cp, 0));
il.append(InstructionConstants.BASTORE);
InstructionHandle nih_113 = il.append(new PUSH(_cp, 1));
il.append(new PUSH(_cp, -128));
il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wrMem", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
InstructionHandle nih_119 = il.append(InstructionFactory.createLoad(Type.OBJECT, transactionLocalsBaseIndex - 2 + 3));
// il.append(_factory.createCheckCast(new
// ObjectType("java.lang.RuntimeException")));
il.append(InstructionConstants.ATHROW);
// set branch targets
ifne_12.setTarget(ih_19);
goto_16.setTarget(ih_20);
ifeq_22.setTarget(ih_43);
ifeq_44.setTarget(ih_53);
ifeq_59.setTarget(ih_84);
ifeq_88.setTarget(nih_119);
if_acmpne_95.setTarget(nih_103);
{
for (BranchInstruction b : gotos_transactionCommit) {
b.setTarget(ih_58);
}
}
// set exception handlers
// TODO restrict exception handler
method.addExceptionHandler(ih_53, ih_84, nih_86, null);
method.setMaxStack();
method.setMaxLocals();
}
m = method.getMethod();
oldIl.dispose();
il.dispose();
return m;
}
use of org.apache.bcel.util.InstructionFinder in project jop by jop-devel.
the class FindUsedConstants method find.
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;
}
// 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);
}
}
}
use of org.apache.bcel.util.InstructionFinder in project jop by jop-devel.
the class InsertSynchronized method synchronize.
private void synchronize(MethodInfo method) {
MethodCode mc = method.getCode();
InstructionList il = mc.getInstructionList();
InstructionFinder f;
// prepend monitorenter (reversed order of opcodes)
il.insert(new MONITORENTER());
if (method.isStatic()) {
// il.insert(new GET_CURRENT_CLASS());
throw new JavaClassFormatError("synchronized on static methods not yet supported");
} else {
il.insert(new ALOAD(0));
}
il.setPositions();
f = new InstructionFinder(il);
// find return instructions and insert monitorexit
String retInstr = "ReturnInstruction";
for (Iterator iterator = f.search(retInstr); iterator.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) iterator.next();
InstructionHandle ih = match[0];
// handle for inserted sequence
InstructionHandle newh;
if (method.isStatic()) {
// il.insert(ih, new GET_CURRENT_CLASS());
throw new JavaClassFormatError("synchronized on static methods not yet supported");
} else {
// TODO this could become a bug if JCopter ever reassigns local variable slots, then
// we could not be sure that slot 0 holds the this reference anymore.. To be on the safe side
// we should check if there is an xSTORE_0 somewhere in the code
newh = il.insert(ih, new ALOAD(0));
}
il.insert(ih, new MONITOREXIT());
// correct jumps
method.getCode().retarget(ih, newh);
}
il.setPositions();
method.compile();
}
Aggregations