Search in sources :

Example 11 with ObjectKlass

use of com.oracle.truffle.espresso.impl.ObjectKlass in project graal by oracle.

the class InnerClassRedefiner method findLoadedInnerClasses.

Set<ObjectKlass> findLoadedInnerClasses(Klass klass) {
    // we use a cache to store inner/outer class mappings
    Map<Symbol<Symbol.Type>, Set<ObjectKlass>> classLoaderMap = innerKlassCache.get(klass.getDefiningClassLoader());
    if (classLoaderMap == null) {
        classLoaderMap = new HashMap<>();
        // register a listener on the registry to fill in
        // future loaded anonymous inner classes
        ClassRegistry classRegistry = context.getRegistries().getClassRegistry(klass.getDefiningClassLoader());
        classRegistry.registerOnLoadListener(new DefineKlassListener() {

            @Override
            public void onKlassDefined(ObjectKlass objectKlass) {
                InnerClassRedefiner.this.onKlassDefined(objectKlass);
            }
        });
        // do a one-time look up of all currently loaded
        // classes for this loader and fill in the map
        List<Klass> loadedKlasses = classRegistry.getLoadedKlasses();
        for (Klass loadedKlass : loadedKlasses) {
            if (loadedKlass instanceof ObjectKlass) {
                ObjectKlass objectKlass = (ObjectKlass) loadedKlass;
                Matcher matcher = ANON_INNER_CLASS_PATTERN.matcher(loadedKlass.getNameAsString());
                if (matcher.matches()) {
                    Symbol<Symbol.Name> outerClassName = getOuterClassName(loadedKlass.getName());
                    if (outerClassName != null && outerClassName.length() > 0) {
                        Symbol<Symbol.Type> outerType = context.getTypes().fromName(outerClassName);
                        Set<ObjectKlass> innerKlasses = classLoaderMap.get(outerType);
                        if (innerKlasses == null) {
                            innerKlasses = new HashSet<>(1);
                            classLoaderMap.put(outerType, innerKlasses);
                        }
                        innerKlasses.add(objectKlass);
                    }
                }
            }
        }
        // add to cache
        innerKlassCache.put(klass.getDefiningClassLoader(), classLoaderMap);
    }
    Set<ObjectKlass> innerClasses = classLoaderMap.get(klass.getType());
    return innerClasses != null ? innerClasses : new HashSet<>(0);
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) ClassRegistry(com.oracle.truffle.espresso.impl.ClassRegistry) Matcher(java.util.regex.Matcher) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass)

Example 12 with ObjectKlass

use of com.oracle.truffle.espresso.impl.ObjectKlass in project graal by oracle.

the class InnerClassRedefiner method onKlassDefined.

private void onKlassDefined(ObjectKlass klass) {
    Matcher matcher = ANON_INNER_CLASS_PATTERN.matcher(klass.getNameAsString());
    if (matcher.matches()) {
        Map<Symbol<Symbol.Type>, Set<ObjectKlass>> classLoaderMap = innerKlassCache.get(klass.getDefiningClassLoader());
        // found inner class, now hunt down the outer
        Symbol<Symbol.Name> outerName = getOuterClassName(klass.getName());
        Symbol<Symbol.Type> outerType = context.getTypes().fromName(outerName);
        Set<ObjectKlass> innerKlasses = classLoaderMap.get(outerType);
        if (innerKlasses == null) {
            innerKlasses = new HashSet<>(1);
            classLoaderMap.put(outerType, innerKlasses);
        }
        innerKlasses.add(klass);
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Matcher(java.util.regex.Matcher) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass)

Example 13 with ObjectKlass

use of com.oracle.truffle.espresso.impl.ObjectKlass in project graal by oracle.

the class ClassRedefinition method redefineClass.

public int redefineClass(ChangePacket packet, List<ObjectKlass> invalidatedClasses, List<ObjectKlass> redefinedClasses) {
    try {
        switch(packet.classChange) {
            case METHOD_BODY_CHANGE:
            case CONSTANT_POOL_CHANGE:
            case CLASS_NAME_CHANGED:
            case ADD_METHOD:
            case REMOVE_METHOD:
            case SCHEMA_CHANGE:
                doRedefineClass(packet, invalidatedClasses, redefinedClasses);
                return 0;
            case CLASS_HIERARCHY_CHANGED:
                context.markChangedHierarchy();
                doRedefineClass(packet, invalidatedClasses, redefinedClasses);
                return 0;
            case NEW_CLASS:
                ClassInfo classInfo = packet.info;
                // if there is a currently loaded class under that name
                // we have to replace that in the class loader registry etc.
                // otherwise, don't eagerly define the new class
                Symbol<Symbol.Type> type = context.getTypes().fromName(classInfo.getName());
                ClassRegistry classRegistry = context.getRegistries().getClassRegistry(classInfo.getClassLoader());
                Klass loadedKlass = classRegistry.findLoadedKlass(type);
                if (loadedKlass != null) {
                    // OK, we have to define the new klass instance and
                    // inject it under the existing JDWP ID
                    classRegistry.onInnerClassRemoved(type);
                    ObjectKlass newKlass = classRegistry.defineKlass(type, classInfo.getBytes());
                    packet.info.setKlass(newKlass);
                }
                return 0;
            default:
                return 0;
        }
    } catch (EspressoException ex) {
        // we get from parsing the class file
        return ErrorCodes.INVALID_CLASS_FORMAT;
    }
}
Also used : ClassRegistry(com.oracle.truffle.espresso.impl.ClassRegistry) Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ParserKlass(com.oracle.truffle.espresso.impl.ParserKlass) EspressoException(com.oracle.truffle.espresso.runtime.EspressoException) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass)

Example 14 with ObjectKlass

use of com.oracle.truffle.espresso.impl.ObjectKlass in project graal by oracle.

the class ClassRedefinition method doRedefineClass.

private void doRedefineClass(ChangePacket packet, List<ObjectKlass> invalidatedClasses, List<ObjectKlass> redefinedClasses) {
    ObjectKlass oldKlass = packet.info.getKlass();
    if (packet.info.isRenamed()) {
        // renaming a class is done by
        // 1. Rename the 'name' and 'type' Symbols in the Klass
        // 2. Update the loaded class cache in the associated ClassRegistry
        // 3. Set the guest language java.lang.Class#name field to null
        // 4. update the JDWP refType ID for the klass instance
        // 5. replace/record a classloader constraint for the new type and klass combination
        Symbol<Symbol.Name> newName = packet.info.getName();
        Symbol<Symbol.Type> newType = context.getTypes().fromName(newName);
        oldKlass.patchClassName(newName, newType);
        ClassRegistry classRegistry = context.getRegistries().getClassRegistry(packet.info.getClassLoader());
        classRegistry.onClassRenamed(oldKlass);
        InterpreterToVM.setFieldObject(StaticObject.NULL, oldKlass.mirror(), context.getMeta().java_lang_Class_name);
    }
    if (packet.classChange == ClassChange.CLASS_HIERARCHY_CHANGED) {
        oldKlass.removeAsSubType();
    }
    oldKlass.redefineClass(packet, invalidatedClasses, ids);
    redefinedClasses.add(oldKlass);
    if (redefineListener.shouldRerunClassInitializer(oldKlass, packet.detectedChange.clinitChanged())) {
        context.rerunclinit(oldKlass);
    }
}
Also used : ClassRegistry(com.oracle.truffle.espresso.impl.ClassRegistry) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass)

Example 15 with ObjectKlass

use of com.oracle.truffle.espresso.impl.ObjectKlass in project graal by oracle.

the class ClassRedefinition method getLoadedKlass.

private static Klass getLoadedKlass(Symbol<Symbol.Type> klassType, ObjectKlass oldKlass) throws RedefintionNotSupportedException {
    Klass klass;
    klass = oldKlass.getContext().getRegistries().findLoadedClass(klassType, oldKlass.getDefiningClassLoader());
    if (klass == null) {
        // new super interface must be loaded eagerly then
        StaticObject resourceGuestString = oldKlass.getMeta().toGuestString(Types.binaryName(klassType));
        try {
            StaticObject loadedClass = (StaticObject) oldKlass.getMeta().java_lang_ClassLoader_loadClass.invokeDirect(oldKlass.getDefiningClassLoader(), resourceGuestString);
            klass = loadedClass.getMirrorKlass();
        } catch (Throwable t) {
            throw new RedefintionNotSupportedException(ErrorCodes.ABSENT_INFORMATION);
        }
    }
    return klass;
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ParserKlass(com.oracle.truffle.espresso.impl.ParserKlass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject)

Aggregations

ObjectKlass (com.oracle.truffle.espresso.impl.ObjectKlass)35 Klass (com.oracle.truffle.espresso.impl.Klass)15 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)12 JavaType (com.oracle.truffle.espresso.substitutions.JavaType)10 ArrayKlass (com.oracle.truffle.espresso.impl.ArrayKlass)9 ArrayList (java.util.ArrayList)8 Method (com.oracle.truffle.espresso.impl.Method)7 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)6 RuntimeConstantPool (com.oracle.truffle.espresso.classfile.RuntimeConstantPool)5 Field (com.oracle.truffle.espresso.impl.Field)5 ParserKlass (com.oracle.truffle.espresso.impl.ParserKlass)5 NoSafepoint (com.oracle.truffle.espresso.jni.NoSafepoint)5 Symbol (com.oracle.truffle.espresso.descriptors.Symbol)4 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)4 ClassRegistry (com.oracle.truffle.espresso.impl.ClassRegistry)4 Meta (com.oracle.truffle.espresso.meta.Meta)4 Matcher (java.util.regex.Matcher)4 InnerClassesAttribute (com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute)3 EspressoException (com.oracle.truffle.espresso.runtime.EspressoException)3 FrameInstance (com.oracle.truffle.api.frame.FrameInstance)2