use of co.paralleluniverse.common.util.VisibleForTesting in project quasar by puniverse.
the class QuasarInstrumentor method instrumentClass.
@VisibleForTesting
byte[] instrumentClass(ClassLoader loader, String className, InputStream is, boolean forceInstrumentation) throws IOException {
className = className != null ? className.replace('.', '/') : null;
byte[] cb = toByteArray(is);
MethodDatabase db = getMethodDatabase(loader);
if (className != null) {
log(LogLevel.INFO, "TRANSFORM: %s %s", className, (db.getClassEntry(className) != null && db.getClassEntry(className).requiresInstrumentation()) ? "request" : "");
examine(className, "quasar-1-preinstr", cb);
} else {
log(LogLevel.INFO, "TRANSFORM: null className");
}
// Phase 1, add a label before any suspendable calls, event API is enough
final ClassReader r1 = new ClassReader(cb);
final ClassWriter cw1 = new ClassWriter(r1, 0);
final LabelSuspendableCallSitesClassVisitor ic1 = new LabelSuspendableCallSitesClassVisitor(cw1, db);
r1.accept(ic1, 0);
cb = cw1.toByteArray();
examine(className, "quasar-2", cb);
// Phase 2, instrument, tree API
final ClassReader r2 = new ClassReader(cb);
final ClassWriter cw2 = new DBClassWriter(db, r2);
final ClassVisitor cv2 = (check && EXAMINED_CLASS == null) ? new CheckClassAdapter(cw2) : cw2;
final InstrumentClass ic2 = new InstrumentClass(cv2, db, forceInstrumentation);
try {
r2.accept(ic2, ClassReader.SKIP_FRAMES);
cb = cw2.toByteArray();
} catch (final Exception e) {
if (ic2.hasSuspendableMethods()) {
error("Unable to instrument class " + className, e);
throw e;
} else {
if (!MethodDatabase.isProblematicClass(className))
log(LogLevel.DEBUG, "Unable to instrument class " + className);
return null;
}
}
examine(className, "quasar-4", cb);
// Phase 4, fill suspendable call offsets, event API is enough
final OffsetClassReader r3 = new OffsetClassReader(cb);
final ClassWriter cw3 = new ClassWriter(r3, 0);
final SuspOffsetsAfterInstrClassVisitor ic3 = new SuspOffsetsAfterInstrClassVisitor(cw3, db);
r3.accept(ic3, 0);
cb = cw3.toByteArray();
// DEBUG
if (EXAMINED_CLASS != null) {
examine(className, "quasar-5-final", cb);
if (check) {
ClassReader r4 = new ClassReader(cb);
ClassVisitor cv4 = new CheckClassAdapter(new TraceClassVisitor(null), true);
r4.accept(cv4, 0);
}
}
return cb;
}
Aggregations