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));
}
}
}
}
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]);
}
Aggregations