use of com.jopdesign.common.code.InvokeSite in project jop by jop-devel.
the class MethodCacheAnalysis method getReturnMissCount.
public long getReturnMissCount(ExecFrequencyProvider ecp, CodeModification modification) {
if (analysisType == AnalysisType.ALWAYS_HIT)
return 0;
if (analysisType == AnalysisType.ALWAYS_MISS || !allFit(modification.getMethod())) {
// outside all-fit, every invoke returns with a miss
long retCount = 0;
for (InvokeSite invokeSite : modification.getMethod().getCode().getInvokeSites()) {
InstructionHandle ih = invokeSite.getInstructionHandle();
if (modification.getStart().getPosition() <= ih.getPosition() && modification.getEnd().getPosition() >= ih.getPosition()) {
continue;
}
retCount += ecp.getExecFrequency(invokeSite);
}
return ecp.getExecCount(modification.getMethod()) * retCount;
}
if (analysisType == AnalysisType.ALWAYS_MISS_OR_HIT || cache.isLRU()) {
return 0;
}
// we have at most one return miss of invokes in this method
return getPersistentMisses(ecp, callGraph.getNodes(modification.getMethod()));
}
use of com.jopdesign.common.code.InvokeSite in project jop by jop-devel.
the class InlineOptimizer method findCandidates.
@Override
public Collection<Candidate> findCandidates(MethodInfo method, AnalysisManager analyses, StacksizeAnalysis stacksize, int maxLocals, InstructionHandle start, InstructionHandle end) {
List<Candidate> candidates = new LinkedList<Candidate>();
MethodCode code = method.getCode();
InstructionHandle next = end.getNext();
for (InstructionHandle ih = start; ih != next; ih = ih.getNext()) {
if (code.isInvokeSite(ih)) {
InvokeSite site = code.getInvokeSite(ih);
// since we update the appInfo callgraph, the callstring only contains the invokesite and no
// inlined methods
CallString cs = new CallString(site);
countInvokeSites++;
MethodInfo invokee = helper.devirtualize(cs);
if (invokee == null)
continue;
countDevirtualized++;
// for the initial check and the DFA lookup we need the old callstring
cs = getInlineCallString(code, ih).push(site);
Candidate candidate = checkInvoke(code, cs, site, invokee, maxLocals);
if (candidate == null) {
continue;
}
// initial check for locals and stack, calculate gain and codesize
if (!candidate.recalculate(analyses, stacksize)) {
continue;
}
candidates.add(candidate);
}
}
return candidates;
}
use of com.jopdesign.common.code.InvokeSite 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