Search in sources :

Example 1 with DetectedChange

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();
}
Also used : DetectedChange(com.oracle.truffle.espresso.redefinition.DetectedChange) RuntimeConstantPool(com.oracle.truffle.espresso.classfile.RuntimeConstantPool)

Aggregations

RuntimeConstantPool (com.oracle.truffle.espresso.classfile.RuntimeConstantPool)1 DetectedChange (com.oracle.truffle.espresso.redefinition.DetectedChange)1