int regNum = startedLocal.getReg();
startedLocal = filterSpec(startedLocal);
aboutToProcess(address, regNum);
RegisterSpec existingLocal = regs.get(regNum);
if (startedLocal.equalsUsingSimpleType(existingLocal)) {
// Silently ignore a redundant start.
return;
}
RegisterSpec movedLocal = regs.findMatchingLocal(startedLocal);
if (movedLocal != null) {
/*
* The same variable was moved from one register to another.
* So add an end for its old location.
*/
addOrUpdateEnd(address, Disposition.END_MOVED, movedLocal);
}
int endAt = endIndices[regNum];
if (existingLocal != null) {
/*
* There is an existing (but non-matching) local.
* Add an explicit end for it.
*/
add(address, Disposition.END_REPLACED, existingLocal);
} else if (endAt >= 0) {
/*
* Look for an end local for the same register at the
* same address. If found, then update it or delete
* it, depending on whether or not it represents the
* same variable as the one being started.
*/
Entry endEntry = result.get(endAt);
if (endEntry.getAddress() == address) {
if (endEntry.matches(startedLocal)) {
/*
* There was already an end local for the same
* variable at the same address. This turns
* out to be superfluous, as we are starting
* up the exact same local. This situation can
* happen when a single local variable got
* somehow "split up" during intermediate
* processing. In any case, rather than represent
* the end-then-start, just remove the old end.
*/
result.set(endAt, null);
nullResultCount++;
regs.put(startedLocal);
endIndices[regNum] = -1;
return;
} else {
/*
* There was a different variable ended at the
* same address. Update it to indicate that
* it was ended due to a replacement (rather than
* ending for no particular reason).
*/
endEntry = endEntry.withDisposition(
Disposition.END_REPLACED);
result.set(endAt, endEntry);
}
}
}
/*
* The code above didn't find and remove an unnecessary
* local end, so we now have to add one or more entries to
* the output to capture the transition.
*/
/*
* If the local just below (in the register set at reg-1)
* is of category-2, then it is ended by this new start.
*/
if (regNum > 0) {
RegisterSpec justBelow = regs.get(regNum - 1);
if ((justBelow != null) && justBelow.isCategory2()) {
addOrUpdateEnd(address,
Disposition.END_CLOBBERED_BY_NEXT,
justBelow);
}
}
/*
* Similarly, if this local is category-2, then the local
* just above (if any) is ended by the start now being
* emitted.
*/
if (startedLocal.isCategory2()) {
RegisterSpec justAbove = regs.get(regNum + 1);
if (justAbove != null) {
addOrUpdateEnd(address,
Disposition.END_CLOBBERED_BY_PREV,
justAbove);
}