in core/src/main/java/org/adoptopenjdk/jitwatch/jarscan/sequencecount/SequenceCountOperation.java [95:188]
private void handleChainStartingAtIndex(int index, List<BytecodeInstruction> instructions)
{
boolean stopChain = false;
boolean abandonChain = false;
Set<Integer> visitedBCI = new HashSet<>();
while (chain.size() < maxLength)
{
if(index >=instructions.size())
{
break;
}
BytecodeInstruction instruction = instructions.get(index);
int instrBCI = instruction.getOffset();
visitedBCI.add(instrBCI);
Opcode opcode = instruction.getOpcode();
// =======================
// The Rules
// =======================
// *RETURN ends a chain. Chain is discarded if not required length
// INVOKE* drops through to next bytecode
// GOTO* is followed
// IF*, TABLESWITCH, and LOOKUPSWITCH - drop through
// JSR, JSR_W, RET are not followed - discard the chain
// ATHROW ends a chain
// loops are detected and end the parsing
switch (opcode)
{
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case ARETURN:
case RETURN:
stopChain = true;
break;
case ATHROW:
stopChain = true;
break;
case JSR:
case JSR_W:
case RET:
abandonChain = true;
break;
case GOTO:
case GOTO_W:
int gotoBCI = ((BCParamNumeric) instruction.getParameters().get(0)).getValue();
if (!visitedBCI.contains(gotoBCI))
{
index = getIndexForBCI(instructions, gotoBCI);
}
break;
default:
index++;
break;
}
chain.add(opcode);
if (stopChain)
{
if (chain.size() == maxLength)
{
storeChain();
}
reset();
break;
}
else if (abandonChain)
{
reset();
break;
}
else if (chain.size() == maxLength)
{
storeChain();
reset();
break;
}
}
}