Search in sources :

Example 1 with RedefineInfo

use of com.oracle.truffle.espresso.jdwp.api.RedefineInfo in project graal by oracle.

the class JDKProxyRedefinitionPlugin method collectExtraClassesToReload.

@Override
@TruffleBoundary
public synchronized void collectExtraClassesToReload(List<RedefineInfo> redefineInfos, List<RedefineInfo> additional) {
    for (RedefineInfo redefineInfo : redefineInfos) {
        KlassRef klass = redefineInfo.getKlass();
        if (klass != null) {
            List<ProxyCache> list = cache.getOrDefault(klass, Collections.emptyList());
            for (ProxyCache proxyCache : list) {
                StaticObject result = (StaticObject) proxyGeneratorMethodCallNode.call(proxyCache.proxyName, proxyCache.interfaces, proxyCache.classModifier);
                byte[] proxyBytes = (byte[]) getContext().getMeta().toHostBoxed(result);
                additional.add(new RedefineInfo(proxyCache.klass, proxyBytes));
            }
        }
    }
}
Also used : RedefineInfo(com.oracle.truffle.espresso.jdwp.api.RedefineInfo) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) KlassRef(com.oracle.truffle.espresso.jdwp.api.KlassRef) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)

Example 2 with RedefineInfo

use of com.oracle.truffle.espresso.jdwp.api.RedefineInfo in project graal by oracle.

the class InnerClassRedefiner method matchAnonymousInnerClasses.

public HotSwapClassInfo[] matchAnonymousInnerClasses(List<RedefineInfo> redefineInfos, List<ObjectKlass> removedInnerClasses) throws RedefintionNotSupportedException {
    hotswapState.clear();
    ArrayList<RedefineInfo> unhandled = new ArrayList<>(redefineInfos);
    Map<Symbol<Symbol.Name>, HotSwapClassInfo> handled = new HashMap<>(redefineInfos.size());
    // build inner/outer relationship from top-level to leaf class in order
    // each round below handles classes where the outer class was previously
    // handled
    int handledSize = 0;
    int previousHandledSize = -1;
    while (!unhandled.isEmpty() && handledSize > previousHandledSize) {
        Iterator<RedefineInfo> it = unhandled.iterator();
        while (it.hasNext()) {
            RedefineInfo redefineInfo = it.next();
            Symbol<Symbol.Name> klassName = ClassfileParser.getClassName(redefineInfo.getClassBytes(), context);
            Matcher matcher = ANON_INNER_CLASS_PATTERN.matcher(klassName.toString());
            if (matcher.matches()) {
                // don't assume that associated old klass instance represents this redefineInfo
                redefineInfo.clearKlass();
                // anonymous inner class or nested named
                // inner class of an anonymous inner class
                // get the outer classinfo if present
                HotSwapClassInfo info = handled.get(getOuterClassName(klassName));
                if (info != null) {
                    HotSwapClassInfo classInfo = ClassInfo.create(klassName, redefineInfo.getClassBytes(), info.getClassLoader(), context);
                    info.addInnerClass(classInfo);
                    handled.put(klassName, classInfo);
                    it.remove();
                }
            } else {
                // pure named class
                it.remove();
                if (redefineInfo.getKlass() != null) {
                    HotSwapClassInfo classInfo = ClassInfo.create(redefineInfo, context);
                    handled.put(klassName, classInfo);
                    hotswapState.put(klassName, classInfo);
                }
            }
        }
        previousHandledSize = handledSize;
        handledSize = handled.size();
    }
    // store renaming rules to be used for constant pool patching when class renaming happens
    Map<StaticObject, Map<Symbol<Symbol.Name>, Symbol<Symbol.Name>>> renamingRules = new HashMap<>(0);
    // begin matching from collected top-level classes
    for (HotSwapClassInfo info : hotswapState.values()) {
        matchClassInfo(info, removedInnerClasses, renamingRules);
    }
    // get the full list of changed classes
    ArrayList<HotSwapClassInfo> result = new ArrayList<>();
    collectAllHotswapClasses(hotswapState.values(), result);
    // now, do the constant pool patching
    for (HotSwapClassInfo classInfo : result) {
        if (classInfo.getBytes() != null) {
            Map<Symbol<Symbol.Name>, Symbol<Symbol.Name>> rules = renamingRules.get(classInfo.getClassLoader());
            if (rules != null && !rules.isEmpty()) {
                try {
                    classInfo.patchBytes(ConstantPoolPatcher.patchConstantPool(classInfo.getBytes(), rules, context));
                } catch (ClassFormatError ex) {
                    throw new RedefintionNotSupportedException(ErrorCodes.INVALID_CLASS_FORMAT);
                }
            }
        }
    }
    hotswapState.clear();
    return result.toArray(new HotSwapClassInfo[0]);
}
Also used : RedefineInfo(com.oracle.truffle.espresso.jdwp.api.RedefineInfo) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) Matcher(java.util.regex.Matcher) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) ArrayList(java.util.ArrayList) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) HashMap(java.util.HashMap) Map(java.util.Map) WeakHashMap(java.util.WeakHashMap)

Aggregations

RedefineInfo (com.oracle.truffle.espresso.jdwp.api.RedefineInfo)2 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)2 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)1 Symbol (com.oracle.truffle.espresso.descriptors.Symbol)1 KlassRef (com.oracle.truffle.espresso.jdwp.api.KlassRef)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 WeakHashMap (java.util.WeakHashMap)1 Matcher (java.util.regex.Matcher)1