use of org.apache.bcel.generic.ARRAYLENGTH in project jop by jop-devel.
the class SymbolicPointsTo method printResult.
public void printResult(DFATool program) {
Map<String, String> getFields = new TreeMap<String, String>();
for (InstructionHandle instr : usedRefs.keySet()) {
ContextMap<CallString, BoundedSet<SymbolicAddress>> r = usedRefs.get(instr);
Context c = r.getContext();
MethodInfo method = c.getMethodInfo();
if (method == null) {
throw new AssertionError("Internal Error: No method '" + c.method() + "'");
}
LineNumberTable lines = method.getCode().getLineNumberTable();
int sourceLine = lines.getSourceLine(instr.getPosition());
for (CallString callString : r.keySet()) {
System.out.println(c.method() + ":" + sourceLine + ":" + callString + ": " + instr);
BoundedSet<SymbolicAddress> symAddr = r.get(callString);
String infoStr;
if (instr.getInstruction() instanceof GETFIELD) {
GETFIELD gfInstr = (GETFIELD) instr.getInstruction();
infoStr = String.format("GETFIELD %s %s %s", symAddr.toString(), gfInstr.getFieldName(c.constPool()), gfInstr.getFieldType(c.constPool()));
} else if (instr.getInstruction() instanceof ARRAYLENGTH) {
infoStr = String.format("ARRAYLENGTH %s", symAddr.toString());
} else if (instr.getInstruction() instanceof ArrayInstruction) {
ArrayInstruction aInstr = (ArrayInstruction) instr.getInstruction();
infoStr = String.format("%s %s %s[]", aInstr.getName().toUpperCase(), symAddr.toString(), aInstr.getType(c.constPool()));
} else {
infoStr = String.format("%s %s", instr.getInstruction().getName().toUpperCase(), symAddr.toString());
}
if (infoStr != null) {
String infoKey = String.format("%s:%04d:%s", c.method(), sourceLine, callString);
while (getFields.containsKey(infoKey)) infoKey += "'";
getFields.put(infoKey, infoStr);
}
}
}
for (Entry<String, String> entry : getFields.entrySet()) {
System.out.println(entry.getKey());
System.out.println(" " + entry.getValue());
}
}
use of org.apache.bcel.generic.ARRAYLENGTH in project jop by jop-devel.
the class ObjectCacheAnalysis method getHandleType.
public static String getHandleType(WCETTool project, ControlFlowGraph cfg, InstructionHandle ih) {
ConstantPoolGen constPool = cfg.getMethodInfo().getConstantPoolGen();
Instruction instr = ih.getInstruction();
if (instr instanceof GETFIELD) {
GETFIELD gf = (GETFIELD) instr;
ReferenceType refty = gf.getReferenceType(constPool);
return refty.toString();
}
if (!ALL_HANDLE_ACCESSES)
return null;
if (instr instanceof PUTFIELD) {
PUTFIELD pf = (PUTFIELD) instr;
ReferenceType refty = pf.getReferenceType(constPool);
return refty.toString();
}
if (instr instanceof ArrayInstruction) {
//ArrayInstruction ainstr = (ArrayInstruction) instr;
return "[]";
}
if (instr instanceof ARRAYLENGTH) {
//ARRAYLENGTH ainstr = (ARRAYLENGTH) instr;
return "[]";
}
if (instr instanceof INVOKEINTERFACE || instr instanceof INVOKEVIRTUAL) {
return "$header";
}
return null;
}
use of org.apache.bcel.generic.ARRAYLENGTH in project jop by jop-devel.
the class SimpleInliner method analyzeInvokee.
/**
* @param cs the callstring from the invoker to the invoke to inline (if recursive). Used to check DFA results.
* @param invokee the invoked method to analyze
* @param inlineData the map to populate with the parameters and the instructions to inline.
* @return true if inlining is possible
*/
private boolean analyzeInvokee(CallString cs, MethodInfo invokee, InlineData inlineData) {
// we allow loading of parameters, loading of constants, some instruction, and a return
ValueMapAnalysis values = new ValueMapAnalysis(invokee);
values.loadParameters();
InstructionList il = invokee.getCode().getInstructionList(true, false);
InstructionHandle ih = il.getStart();
// we should at least have a return instruction, so even for empty methods we should fall through
// generate the parameter mapping
int count = 0;
while (true) {
Instruction instruction = ih.getInstruction();
if (instruction instanceof PushInstruction || instruction instanceof NOP) {
values.transfer(instruction);
ih = ih.getNext();
count++;
} else {
break;
}
}
// store the mapping
for (ValueInfo value : values.getValueTable().getStack()) {
inlineData.addParam(value);
}
inlineData.setInlineStart(count);
// if we do not need an NP check, we can also inline code which does not throw an exception in the same way
boolean needsNPCheck = helper.needsNullpointerCheck(cs, invokee, false);
boolean hasNPCheck = false;
// we allow up to 5 instructions and one return before assuming that the resulting code will be too large
for (int i = 0; i < 6; i++) {
// now lets see what we have here as non-push instructions
Instruction instruction = ih.getInstruction();
if (instruction instanceof InvokeInstruction) {
if (inlineData.getInvokeSite() != null) {
// only inline at most one invoke
return false;
}
InvokeSite is = invokee.getCode().getInvokeSite(ih);
inlineData.setInvokeSite(is);
hasNPCheck |= !is.isInvokeStatic();
} else if (instruction instanceof FieldInstruction) {
if (instruction instanceof GETFIELD) {
hasNPCheck |= values.getValueTable().top().isThisReference();
}
if (instruction instanceof PUTFIELD) {
int down = values.getValueTable().top().isContinued() ? 2 : 1;
hasNPCheck |= values.getValueTable().top(down).isThisReference();
}
} else if (instruction instanceof ArithmeticInstruction || instruction instanceof ConversionInstruction || instruction instanceof StackInstruction || instruction instanceof LDC || instruction instanceof LDC2_W || instruction instanceof ARRAYLENGTH || instruction instanceof CHECKCAST || instruction instanceof NOP) {
// nothing to do, just copy them
} else if (instruction instanceof ReturnInstruction) {
if (needsNPCheck && !hasNPCheck) {
// We were nearly finished.. but NP check test failed
this.requiresNPCheck++;
if (logger.isTraceEnabled()) {
logger.trace("Not inlining " + invokee + " because it requires a NP check.");
}
return false;
}
// else we need to add pop instructions
if (instruction instanceof RETURN) {
// we do not return anything, so we must empty the stack
while (values.getValueTable().getStackSize() > 0) {
Instruction pop;
if (values.getValueTable().top().isContinued()) {
pop = new POP2();
} else {
pop = new POP();
}
inlineData.addEpilogue(pop);
values.transfer(pop);
}
return true;
} else {
Type type = ((ReturnInstruction) instruction).getType();
// javac anyway)
return values.getValueTable().getStackSize() == type.getSize();
}
} else {
// if we encounter an instruction which we do not handle, we do not inline
unhandledInstructions++;
if (logger.isTraceEnabled()) {
logger.trace("Not inlining " + invokee + " because of unhandled instruction " + instruction.toString(invokee.getClassInfo().getConstantPoolGen().getConstantPool()));
}
return false;
}
// update the stack map since we need it to handle RETURN
values.transfer(instruction);
ih = ih.getNext();
}
// too many instructions, do not inline
return false;
}
Aggregations