use of com.oracle.truffle.espresso.redefinition.DetectedChange in project graal by oracle.
the class ObjectKlass method redefineClass.
public void redefineClass(ChangePacket packet, List<ObjectKlass> invalidatedClasses, Ids<Object> ids) {
DetectedChange change = packet.detectedChange;
if (change.isChangedSuperClass()) {
// within this class.
if (getDeclaredFields().length > 0) {
ExtensionFieldsMetadata extension = getExtensionFieldsMetadata(true);
for (Field declaredField : getDeclaredFields()) {
if (!declaredField.isStatic()) {
declaredField.removeByRedefintion();
int nextFieldSlot = getContext().getClassRedefinition().getNextAvailableFieldSlot();
LinkedField.IdMode mode = LinkedKlassFieldLayout.getIdMode(getLinkedKlass().getParserKlass());
LinkedField linkedField = new LinkedField(declaredField.linkedField.getParserField(), nextFieldSlot, mode);
Field field = new RedefineAddedField(getKlassVersion(), linkedField, getConstantPool(), false);
extension.addNewInstanceField(field);
}
}
}
}
if (packet.parserKlass == null) {
// no further changes
return;
}
ParserKlass parserKlass = packet.parserKlass;
KlassVersion oldVersion = klassVersion;
LinkedKlass oldLinkedKlass = oldVersion.linkedKlass;
RuntimeConstantPool pool = new RuntimeConstantPool(getContext(), parserKlass.getConstantPool(), oldVersion.pool.getClassLoader());
// class structure
ObjectKlass[] superInterfaces = change.getSuperInterfaces();
LinkedKlass[] interfaces = new LinkedKlass[superInterfaces.length];
for (int i = 0; i < superInterfaces.length; i++) {
interfaces[i] = superInterfaces[i].getLinkedKlass();
}
LinkedKlass linkedKlass;
if (Modifier.isInterface(change.getSuperKlass().getModifiers())) {
linkedKlass = LinkedKlass.redefine(parserKlass, null, interfaces, oldLinkedKlass);
} else {
linkedKlass = LinkedKlass.redefine(parserKlass, change.getSuperKlass().getLinkedKlass(), interfaces, oldLinkedKlass);
}
klassVersion = new KlassVersion(oldVersion, pool, linkedKlass, packet, invalidatedClasses, ids);
// fields
if (!change.getAddedStaticFields().isEmpty() || !change.getAddedInstanceFields().isEmpty()) {
Map<ParserField, Field> compatibleFields = change.getMappedCompatibleFields();
ExtensionFieldsMetadata extension = getExtensionFieldsMetadata(true);
// add new fields to the extension object
extension.addNewStaticFields(klassVersion, change.getAddedStaticFields(), pool, compatibleFields, getContext().getClassRedefinition());
extension.addNewInstanceFields(klassVersion, change.getAddedInstanceFields(), pool, compatibleFields, getContext().getClassRedefinition());
// make sure all new fields trigger re-resolution of fields
// with same name + type in the full class hierarchy
markForReResolution(change.getAddedStaticFields(), invalidatedClasses);
markForReResolution(change.getAddedInstanceFields(), invalidatedClasses);
}
for (Field removedField : change.getRemovedFields()) {
removedField.removeByRedefintion();
}
incrementKlassRedefinitionCount();
oldVersion.assumption.invalidate();
}
Aggregations