package alt.jiapi.util;
import java.util.ArrayList;
import alt.jiapi.Rule;
import alt.jiapi.JiapiException;
import alt.jiapi.reflect.Instruction;
import alt.jiapi.reflect.InstructionList;
import alt.jiapi.reflect.instruction.Opcodes;
/**
* HotSpotLocator locates HotSpots from InstructionList.<p>
*
* @see HotSpot definition of HotSpot
* @author Mika Riekkinen
*/
public class HotSpotLocator {
private InstructionList il;
private byte[] opCodes;
private Rule rule;
/**
* Create new HotSpotLocator.
* HotSpotLocator scans for given opCode, and when found creates
* a HotSpot of that Instruction, and possibly some Instructions
* just before it.
*
* @param il InstructionList to scan for hotspots
* @param opCode opCode, that triggers creation of hotspot
*/
public HotSpotLocator(InstructionList il, byte opCode) {
this(il, new byte[] { opCode }, "*");
}
/**
* Create new HotSpotLocator.
* HotSpotLocator scans for any of the given opCodes, and when found
* creates a HotSpot of that Instruction, and possibly some Instructions
* just before it.
*
* @param il InstructionList to scan for hotspots
* @param opCodes An array of opCodes, that may trigger creation of hotspot
*/
public HotSpotLocator(InstructionList il, byte[] opCodes) {
this(il, opCodes, "*");
}
/**
* Create new HotSpotLocator.
* HotSpotLocator scans for any of the given opCodes, and when found
* creates a HotSpot of that Instruction, and possibly some Instructions
* just before it.<p>
*
* HotSpot is accepted only, if resolution matches to the name of
* the hotspot(HotSpot.getName())
*
* @param il InstructionList to scan for hotspots
* @param opCodes An array of opCodes, that may trigger creation of hotspot
* @param resolution Resolution to use
*/
public HotSpotLocator(InstructionList il, byte[] opCodes, String resolution) {
// if (il == null) {
// il = new InstructionList();
// }
this.il = il;
this.opCodes = opCodes;
try {
rule = new Rule(resolution);
}
catch(JiapiException je) {
}
}
/**
* Get all the hotspots that was found. Note, that HotSpots found
* may overlap each other. This could happen, for example, if
* a return value of one invocation is a parameter to another one.
*
* @return An array of HotSpots. If no HotSpots were found, an array
* of length 0 is returned.
*/
public HotSpot[] getHotSpots() {
ArrayList al = new ArrayList();
for (int i = 0; i < il.size(); i++) {
Instruction ins = il.get(i);
short opCode = ins.getOpcode();
for (int j = 0; j < opCodes.length; j++) {
if (opCode == opCodes[j]) {
HotSpot hs = createHotSpot(il, i);
// if (rule.match(hs.getName()))
al.add(hs);
}
}
}
return (HotSpot[])al.toArray(new HotSpot[0]);
}
/**
* Create HotSpot.
* InstructionList is scanned backwards until stack consumption
* of Instruction at given index is satisfied.
*
* @param il InstructionList
* @param idx hotspot Instruction.
*/
private HotSpot createHotSpot(InstructionList il, int idx) {
Instruction end = il.get(idx);
Instruction start = end;
int stackConsumption = end.stackConsumption();
while(stackConsumption > 0) {
start = il.get(idx - 1); // Previous instruction
stackConsumption -= start.stackUsage();
idx--;
}
return new HotSpot(il, start, end);
}
}