Search in sources :

Example 1 with Types

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;
}
Also used : Types(com.oracle.truffle.espresso.descriptors.Types) ClassfileStream(com.oracle.truffle.espresso.classfile.ClassfileStream) ArrayList(java.util.ArrayList) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) ParserKlass(com.oracle.truffle.espresso.impl.ParserKlass)

Aggregations

ClassfileStream (com.oracle.truffle.espresso.classfile.ClassfileStream)1 Types (com.oracle.truffle.espresso.descriptors.Types)1 ObjectKlass (com.oracle.truffle.espresso.impl.ObjectKlass)1 ParserKlass (com.oracle.truffle.espresso.impl.ParserKlass)1 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)1 ArrayList (java.util.ArrayList)1