private void handleChainStartingAtIndex()

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;
			}
		}
	}