use of com.oracle.truffle.espresso.descriptors.Types in project graal by oracle.
the class ClassRedefinition method detectClassChanges.
public List<ChangePacket> detectClassChanges(HotSwapClassInfo[] classInfos) throws RedefintionNotSupportedException {
List<ChangePacket> result = new ArrayList<>(classInfos.length);
EconomicMap<ObjectKlass, ChangePacket> temp = EconomicMap.create(1);
EconomicSet<ObjectKlass> superClassChanges = EconomicSet.create(1);
for (HotSwapClassInfo hotSwapInfo : classInfos) {
ObjectKlass klass = hotSwapInfo.getKlass();
if (klass == null) {
// New anonymous inner class
result.add(new ChangePacket(hotSwapInfo, ClassChange.NEW_CLASS));
continue;
}
byte[] bytes = hotSwapInfo.getBytes();
ParserKlass parserKlass;
ParserKlass newParserKlass = null;
ClassChange classChange;
DetectedChange detectedChange = new DetectedChange();
StaticObject loader = klass.getDefiningClassLoader();
Types types = klass.getContext().getTypes();
parserKlass = ClassfileParser.parse(new ClassfileStream(bytes, null), loader, types.fromName(hotSwapInfo.getName()), context);
if (hotSwapInfo.isPatched()) {
byte[] patched = hotSwapInfo.getPatchedBytes();
newParserKlass = parserKlass;
// we detect changes against the patched bytecode
parserKlass = ClassfileParser.parse(new ClassfileStream(patched, null), loader, types.fromName(hotSwapInfo.getNewName()), context);
}
classChange = detectClassChanges(parserKlass, klass, detectedChange, newParserKlass);
if (classChange == ClassChange.CLASS_HIERARCHY_CHANGED && detectedChange.getSuperKlass() != null) {
// keep track of unhandled changed super classes
ObjectKlass superKlass = detectedChange.getSuperKlass();
ObjectKlass oldSuperKlass = klass.getSuperKlass();
ObjectKlass commonSuperKlass = (ObjectKlass) oldSuperKlass.findLeastCommonAncestor(superKlass);
while (superKlass != commonSuperKlass) {
superClassChanges.add(superKlass);
superKlass = superKlass.getSuperKlass();
}
}
ChangePacket packet = new ChangePacket(hotSwapInfo, newParserKlass != null ? newParserKlass : parserKlass, classChange, detectedChange);
result.add(packet);
temp.put(klass, packet);
}
// add superclass change information to result
for (ObjectKlass superKlass : superClassChanges) {
ChangePacket packet = temp.get(superKlass);
if (packet != null) {
// update changed super klass
packet.detectedChange.markChangedSuperClass();
} else {
// create new packet to signal a subclass was changed but the superclass didn't
DetectedChange change = new DetectedChange();
change.markChangedSuperClass();
packet = new ChangePacket(HotSwapClassInfo.createForSuperClassChanged(superKlass), null, ClassChange.CLASS_HIERARCHY_CHANGED, change);
result.add(packet);
}
}
return result;
}
Aggregations