Commit 084c28a8 authored by Lubomir Bulej's avatar Lubomir Bulej

DiSL: Minimal modifications to allow controlling bypass generation from the client.

Test: Updated Agent and OnPlaceTransformer pass an empty set of code options to DiSL (to compile).
parent a8e5eec6
......@@ -5,6 +5,7 @@ import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import ch.usi.dag.disl.DiSL;
import ch.usi.dag.disl.DiSL.CodeOption;
public class Transformer implements ClassFileTransformer {
......@@ -27,7 +28,9 @@ public class Transformer implements ClassFileTransformer {
disl = new DiSL(false);
}
instrumentedClass = disl.instrument(classfileBuffer);
instrumentedClass = disl.instrument(
classfileBuffer, CodeOption.setOf (/* TODO Set options */)
);
if(instrumentedClass != null) {
......
......@@ -12,6 +12,7 @@ import org.objectweb.asm.util.CheckClassAdapter;
import org.objectweb.asm.util.TraceClassVisitor;
import ch.usi.dag.disl.DiSL;
import ch.usi.dag.disl.DiSL.CodeOption;
public class OnPlaceTransformer {
......@@ -48,7 +49,9 @@ public class OnPlaceTransformer {
new TraceClassVisitor(new PrintWriter(System.out))), 0);
// instrument class
byte[] instrCode = disl.instrument(origCode);
byte[] instrCode = disl.instrument(
origCode, CodeOption.setOf (/* TODO Set options */)
);
if(instrCode != null) {
......
package ch.usi.dag.disl;
import static ch.usi.dag.disl.DiSL.CodeOption.CREATE_BYPASS;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
......@@ -212,7 +214,7 @@ public class DiSL {
* {@code true} if the methods was changed, {@code false} otherwise.
*/
private boolean instrumentMethod (
final ClassNode classNode, final MethodNode methodNode
final ClassNode classNode, final MethodNode methodNode
) throws ReflectionException, StaticContextGenException,
ProcessorException, DynamicContextException, MarkerException {
......@@ -406,8 +408,9 @@ public class DiSL {
* @param classNode class node to instrument
* @return instrumented class
*/
private InstrumentedClass instrumentClass(ClassNode classNode)
throws DiSLException {
private InstrumentedClass instrumentClass(
ClassNode classNode, final Set <CodeOption> codeOptions
) throws DiSLException {
// NOTE that class can be changed without changing any method
// - adding thread local fields
......@@ -481,7 +484,7 @@ public class DiSL {
/**
* Instruments array of bytes representing a class
*
* @param classAsBytes class as array of bytes
* @param originalCode class as array of bytes
* @return instrumented class as array of bytes
*/
// TODO ! current static context interface does not allow to have nice
......@@ -489,17 +492,17 @@ public class DiSL {
// also invokes the required method and returns result - if this method
// (and static context class itself) will be synchronized, it should work
public synchronized byte [] instrument (
byte [] classAsBytes
byte [] originalCode, final Set <CodeOption> codeOptions
) throws DiSLException {
// keep the currently processed class around in case of errors
if (debug) {
__dumpClassToFile (classAsBytes, "err.class");
__dumpClassToFile (originalCode, "err.class");
}
// apply transformer first
if (transformer != null) {
try {
classAsBytes = transformer.transform(classAsBytes);
originalCode = transformer.transform(originalCode);
}
catch (Exception e) {
throw new TransformerException("Transformer error", e);
......@@ -507,7 +510,7 @@ public class DiSL {
}
// create class reader
ClassReader classReader = new ClassReader(classAsBytes);
ClassReader classReader = new ClassReader(originalCode);
// AfterInitBodyMarker uses AdviceAdapter
// - classNode with API param is required by ASM 4.0 guidelines
......@@ -515,14 +518,14 @@ public class DiSL {
classReader.accept(classNode, ClassReader.EXPAND_FRAMES);
InstrumentedClass instrClass = instrumentClass(classNode);
InstrumentedClass instrClass = instrumentClass(classNode, codeOptions);
if(instrClass == null) {
// propagate uninstrumented classes
// useful, when transformer is doing some job on all classes
if(transPropagateUninstr) {
return classAsBytes;
return originalCode;
}
return null;
......@@ -530,10 +533,10 @@ public class DiSL {
ClassNode instrCN = instrClass.getClassNode();
// if dynamic bypass is enabled use code merger
if(useDynamicBypass) {
// if bypass is desired, merge original and instrumented method code
if(codeOptions.contains (CREATE_BYPASS)) {
ClassReader origCR = new ClassReader(classAsBytes);
ClassReader origCR = new ClassReader(originalCode);
ClassNode origCN = new ClassNode();
origCR.accept(origCN, ClassReader.EXPAND_FRAMES);
......
......@@ -6,10 +6,12 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import ch.usi.dag.disl.DiSL;
import ch.usi.dag.disl.DiSL.CodeOption;
import ch.usi.dag.disl.exception.DiSLException;
import ch.usi.dag.disl.util.Constants;
......@@ -71,7 +73,8 @@ public class Worker extends Thread {
instrClass = instrument (
new String (request.getControl ()),
request.getClassCode ()
request.getClassCode (),
CodeOption.setOf (request.getFlags ())
);
instrumentationTime.addAndGet (System.nanoTime () - startTime);
......@@ -121,7 +124,7 @@ public class Worker extends Thread {
private byte [] instrument (
String className, byte [] origCode
String className, byte [] origCode, Set <CodeOption> options
) throws DiSLServerException, DiSLException {
// backup for empty class name
......@@ -135,7 +138,7 @@ public class Worker extends Thread {
}
// instrument the bytecode according to given options
byte [] instrCode = disl.instrument (origCode);
byte [] instrCode = disl.instrument (origCode, options);
// dump instrumented byte code
if (instrPath != null && instrCode != null) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment