Skip to content

Commit b33e610

Browse files
committed
Simplify class hierearchy of visitors
1 parent 3317f7b commit b33e610

7 files changed

Lines changed: 157 additions & 76 deletions

Code/ChroniclerJ/src/main/java/edu/columbia/cs/psl/chroniclerj/replay/NonDeterministicReplayClassVisitor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.objectweb.asm.tree.ClassNode;
1717
import org.objectweb.asm.tree.FieldNode;
1818
import org.objectweb.asm.tree.MethodInsnNode;
19+
import org.objectweb.asm.util.CheckClassAdapter;
1920

2021
import edu.columbia.cs.psl.chroniclerj.Instrumenter;
2122
import edu.columbia.cs.psl.chroniclerj.MethodCall;
@@ -28,7 +29,7 @@ public class NonDeterministicReplayClassVisitor extends ClassVisitor implements
2829
private boolean isAClass = true;
2930

3031
public NonDeterministicReplayClassVisitor(int api, ClassVisitor cv) {
31-
super(api, cv);
32+
super(api, new CheckClassAdapter(cv));
3233

3334
}
3435

Code/ChroniclerJ/src/main/java/edu/columbia/cs/psl/chroniclerj/replay/NonDeterministicReplayMethodVisitor.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.objectweb.asm.Type;
1313
import org.objectweb.asm.commons.AdviceAdapter;
1414
import org.objectweb.asm.commons.AnalyzerAdapter;
15+
import org.objectweb.asm.commons.InstructionAdapter;
1516
import org.objectweb.asm.tree.MethodInsnNode;
1617

1718
import edu.columbia.cs.psl.chroniclerj.CallbackRegistry;
@@ -23,7 +24,7 @@
2324
import edu.columbia.cs.psl.chroniclerj.struct.AnnotatedMethod;
2425
import edu.columbia.cs.psl.chroniclerj.visitor.NonDeterministicLoggingMethodVisitor;
2526

26-
public class NonDeterministicReplayMethodVisitor extends AdviceAdapter implements Opcodes {
27+
public class NonDeterministicReplayMethodVisitor extends InstructionAdapter implements Opcodes {
2728
private static Logger logger = Logger.getLogger(NonDeterministicReplayMethodVisitor.class);
2829

2930
private String name;
@@ -69,7 +70,7 @@ public void visitCode() {
6970
protected NonDeterministicReplayMethodVisitor(int api, MethodVisitor mv, int access,
7071
String name, String desc, String classDesc, boolean isFirstConstructor,
7172
AnalyzerAdapter analyzer, boolean isCallbackInit) {
72-
super(api, mv, access, name, desc);
73+
super(api, mv);
7374
this.name = name;
7475
this.desc = desc;
7576
this.classDesc = classDesc;
@@ -86,6 +87,10 @@ public void setClassVisitor(NonDeterministicReplayClassVisitor coaClassVisitor)
8687
this.parent = coaClassVisitor;
8788
}
8889

90+
@Override
91+
public void visitMaxs(int maxStack, int maxLocals) {
92+
super.visitMaxs(maxStack+5, maxLocals);
93+
}
8994
@Override
9095
public void visitEnd() {
9196
super.visitEnd();
@@ -342,7 +347,7 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
342347
// replayFieldName);
343348
// visitLabel(fallThrough);
344349

345-
arrayLoad(t);
350+
super.visitInsn(t.getOpcode(IALOAD));
346351

347352
/*
348353
* stack (grows down): dest src
@@ -351,15 +356,15 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
351356
/*
352357
* stack (grows down): src dest
353358
*/
354-
push(0);
359+
iconst(0);
355360
/*
356361
* stack (grows down): src dest 0
357362
*/
358363
swap();
359364
/*
360365
* stack (grows down): src 0 dest
361366
*/
362-
push(0);
367+
iconst(0);
363368
/*
364369
* stack (grows down): src 0 dest 0
365370
*/
@@ -368,7 +373,7 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
368373
.getLogFieldName(t), MethodCall.getLogFieldType(t)
369374
.getDescriptor());
370375
loadReplayIndex(replayClassName, replayFieldName);
371-
arrayLoad(t);
376+
super.visitInsn(t.getOpcode(IALOAD));
372377
mv.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
373378
mv.visitInsn(ARRAYLENGTH);
374379
incrementReplayIndex(replayClassName, replayFieldName);
@@ -425,7 +430,7 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
425430
.getLogFieldType().getDescriptor());
426431

427432
loadReplayIndex(m.getReplayClassName(), m.getLogFieldName());
428-
arrayLoad(m.getReturnType());
433+
super.visitInsn(m.getReturnType().getOpcode(IALOAD));
429434
if(m.getReturnType().getSort() == Type.OBJECT || m.getReturnType().getSort() == Type.ARRAY)
430435
super.visitTypeInsn(CHECKCAST, m.getReturnType().getInternalName());
431436
incrementReplayIndex(m.getReplayClassName(), m.getLogFieldName());
@@ -438,13 +443,17 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
438443

439444
} else {
440445
super.visitMethodInsn(opcode, owner, name, desc, itfc);
446+
if(constructor && !superInitialized && opcode == INVOKESPECIAL && name.equals("<init>"))
447+
{
448+
onMethodEnter();
449+
superInitialized = true;
450+
}
441451
}
442452
} catch (Exception ex) {
443453
logger.error("Unable to instrument method call", ex);
444454
}
445455
}
446456

447-
@Override
448457
protected void onMethodEnter() {
449458
if (this.name.equals("<init>") && isCallbackInit) {
450459
super.visitVarInsn(ALOAD, 0);

Code/ChroniclerJ/src/main/java/edu/columbia/cs/psl/chroniclerj/visitor/CallbackDuplicatingClassVisitor.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.objectweb.asm.commons.LocalVariablesSorter;
1111
import org.objectweb.asm.tree.MethodNode;
1212

13+
1314
/**
1415
* If we identify a method as a callback method: Rename it. the renamed one will
1516
* then not be logged. Create a new method with the original name, and the only
@@ -58,17 +59,19 @@ public void visitEnd() {
5859
caa.setLocalVariableSorter(lvsorter);
5960

6061
if ((mn.access & Opcodes.ACC_STATIC) == 0) // not static
61-
clmv.loadThis();
62+
clmv.visitVarInsn(Opcodes.ALOAD, 0);
6263

6364
// load all of the arguments onto the stack again
6465
Type[] args = Type.getArgumentTypes(mn.desc);
6566

67+
int j = 0;
6668
for (int i = 0; i < args.length; i++) {
67-
clmv.loadArg(i);
69+
clmv.load(j, args[i]);
70+
j+= args[i].getSize();
6871
}
6972
clmv.visitMethodInsn((mn.access & Opcodes.ACC_STATIC) == 0 ? Opcodes.INVOKESPECIAL
7073
: Opcodes.INVOKESTATIC, className, "_chronicler_" + mn.name, mn.desc, false);
71-
clmv.returnValue();
74+
clmv.visitInsn(Type.getReturnType(mn.desc).getOpcode(Opcodes.IRETURN));
7275
clmv.visitMaxs(0, 0);
7376

7477
clmv.visitEnd();

Code/ChroniclerJ/src/main/java/edu/columbia/cs/psl/chroniclerj/visitor/CallbackLoggingMethodVisitor.java

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import org.objectweb.asm.Opcodes;
66
import org.objectweb.asm.Type;
77
import org.objectweb.asm.commons.AdviceAdapter;
8+
import org.objectweb.asm.commons.InstructionAdapter;
89
import org.objectweb.asm.commons.LocalVariablesSorter;
10+
import org.objectweb.asm.commons.Method;
911

1012
import edu.columbia.cs.psl.chroniclerj.CallbackInvocation;
1113
import edu.columbia.cs.psl.chroniclerj.CallbackRegistry;
1214
import edu.columbia.cs.psl.chroniclerj.Log;
1315

14-
public class CallbackLoggingMethodVisitor extends AdviceAdapter implements Opcodes {
16+
public class CallbackLoggingMethodVisitor extends InstructionAdapter implements Opcodes {
1517

1618
private String className;
1719

@@ -27,7 +29,7 @@ public class CallbackLoggingMethodVisitor extends AdviceAdapter implements Opcod
2729

2830
public CallbackLoggingMethodVisitor(MethodVisitor mv, int access, String name,
2931
String desc, String classname, LocalVariablesSorter lvsorter, CloningAdviceAdapter caa) {
30-
super(Opcodes.ASM5, mv, access, name, desc);
32+
super(Opcodes.ASM5, mv);
3133
this.className = classname;
3234
this.methodName = name;
3335
this.methodDesc = desc;
@@ -38,14 +40,64 @@ public CallbackLoggingMethodVisitor(MethodVisitor mv, int access, String name,
3840
}
3941

4042
@Override
43+
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
44+
super.visitMethodInsn(opcode, owner, name, desc, itf);
45+
if(isInit && opcode == INVOKESPECIAL && name.equals("<init>"))
46+
{
47+
onMethodEnter();
48+
isInit = false;
49+
}
50+
}
4151
protected void onMethodEnter() {
4252
if (this.isInit) {
4353
super.visitVarInsn(ALOAD, 0);
4454
super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(CallbackRegistry.class),
4555
"register", "(Ljava/lang/Object;)V", false);
4656
}
4757
}
48-
58+
private static Type getBoxedType(final Type type) {
59+
switch (type.getSort()) {
60+
case Type.BYTE:
61+
return Type.BYTE_TYPE;
62+
case Type.BOOLEAN:
63+
return Type.BOOLEAN_TYPE;
64+
case Type.SHORT:
65+
return Type.SHORT_TYPE;
66+
case Type.CHAR:
67+
return Type.CHAR_TYPE;
68+
case Type.INT:
69+
return Type.INT_TYPE;
70+
case Type.FLOAT:
71+
return Type.FLOAT_TYPE;
72+
case Type.LONG:
73+
return Type.LONG_TYPE;
74+
case Type.DOUBLE:
75+
return Type.DOUBLE_TYPE;
76+
}
77+
return type;
78+
}
79+
public void box(final Type type) {
80+
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
81+
return;
82+
}
83+
if (type == Type.VOID_TYPE) {
84+
aconst(NULL);
85+
} else {
86+
Type boxed = getBoxedType(type);
87+
anew(boxed);
88+
if (type.getSize() == 2) {
89+
// Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
90+
dupX2();
91+
dupX2();
92+
pop();
93+
} else {
94+
// p -> po -> opo -> oop -> o
95+
dupX1();
96+
swap();
97+
}
98+
invokespecial(boxed.getInternalName(), "<init>", "("+type.getDescriptor()+")V", false);
99+
}
100+
}
49101
@Override
50102
public void visitCode() {
51103
super.visitCode();
@@ -55,8 +107,22 @@ public void visitCode() {
55107
super.visitLdcInsn(className);
56108
super.visitLdcInsn(methodName);
57109
super.visitLdcInsn(methodDesc);
58-
super.loadArgArray();
59-
super.loadThis();
110+
111+
Type[] args = Type.getArgumentTypes(methodDesc);
112+
iconst(args.length);
113+
newarray(OBJECT_TYPE);
114+
int j = 0;
115+
for (int i = 0; i < args.length; i++) {
116+
dup();
117+
iconst(i);
118+
load(j,args[i]);
119+
120+
box(args[i]);
121+
j += args[i].getSize();
122+
visitInsn(Opcodes.AASTORE);
123+
}
124+
125+
super.visitVarInsn(Opcodes.ALOAD, 0);
60126
super.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(CallbackInvocation.class),
61127
"<init>",
62128
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;Ljava/lang/Object;)V", false);

0 commit comments

Comments
 (0)