Skip to content

Commit

Permalink
Fix: don't track <init> invocations to avoid verification errors
Browse files Browse the repository at this point in the history
  • Loading branch information
tsitelov committed Sep 1, 2017
1 parent ebf50f9 commit f8e066d
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private byte[] transformImpl(ClassLoader loader, String internalClassName,
ClassWriter cw = computeFrames ?
new FrameClassWriter(cr, loader) :
new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor classTransformer = new ClassTransformer(cw, classAnalyzer.contexts);
ClassVisitor classTransformer = new ClassTransformer(cw, classAnalyzer.contexts, classAnalyzer.classVersion);
int transformFlags =
(config.isSkipDebug() ? ClassReader.SKIP_DEBUG : 0) +
(config.isNoFrames() || computeFrames ? ClassReader.SKIP_FRAMES : 0);
Expand Down Expand Up @@ -255,16 +255,18 @@ public MethodVisitor visitMethod(final int access, final String mname, final Str
}
Context context = new Context(config, ciCache, loader, binaryClassName, cname, mname, desc);
contexts.add(context);
return new MethodAnalyzer(new GeneratorAdapter(new EmptyMethodVisitor(), access, mname, desc), context);
return new MethodAnalyzer(new GeneratorAdapter(new EmptyMethodVisitor(), access, mname, desc), context, classVersion);
}
}

private class ClassTransformer extends ClassVisitor {
private final Iterator<Context> contextIterator;
private final int classVersion;

public ClassTransformer(ClassVisitor cv, List<Context> contexts) {
public ClassTransformer(ClassVisitor cv, List<Context> contexts, int classVersion) {
super(TransformerUtil.ASM_API, cv);
this.contextIterator = contexts.iterator();
this.classVersion = classVersion;
}

@Override
Expand All @@ -281,7 +283,7 @@ public MethodVisitor visitMethod(final int access, final String mname, final Str
MethodVisitor visitor = super.visitMethod(access, mname, desc, signature, exceptions);
visitor = new TryCatchBlockSorter(visitor, access, mname, desc, signature, exceptions);
Context context = contextIterator.next();
visitor = new MethodTransformer(new GeneratorAdapter(visitor, access, mname, desc), context);
visitor = new MethodTransformer(new GeneratorAdapter(visitor, access, mname, desc), context, classVersion);
visitor = new JSRInlinerAdapter(visitor, access, mname, desc, signature, exceptions);
return visitor;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ abstract class AbstractMethodVisitor extends MethodVisitor {

protected final GeneratorAdapter mv;
protected final Context context;
private final int classVersion;

public AbstractMethodVisitor(GeneratorAdapter mv, Context context) {
public AbstractMethodVisitor(GeneratorAdapter mv, Context context, int classVersion) {
super(TransformerUtil.ASM_API, mv);
this.mv = mv;
this.context = context;
this.classVersion = classVersion;
}

protected abstract void visitMarkDeclareLocationStack();
Expand Down Expand Up @@ -193,7 +195,7 @@ public void visitMethodInsn(final int opcode, final String owner, final String n
boolean isArrayClone = isClone && owner.startsWith("[");
boolean isObjectClone = isClone && AProfRegistry.isDirectCloneClass(cname);

if (context.isMethodInvocationTracked(cname, opcode, owner, name, desc)) {
if (context.isMethodInvocationTracked(cname, opcode, owner, name, desc, classVersion)) {
visitTrackedMethodInsn(opcode, owner, name, desc, intf);
} else {
mv.visitMethodInsn(opcode, owner, name, desc, intf);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,13 @@ private void buildSignatureString(StringBuilder sb) {
sb.append(')');
}

public boolean isMethodInvocationTracked(String cname, int opcode, String owner, String name, String desc) {
public boolean isMethodInvocationTracked(String cname, int opcode, String owner, String name, String desc,
int transformedClassVersion)
{
if (owner.startsWith("["))
return false; // do not track array method invocations
if (transformedClassVersion >= Opcodes.V1_7 && TransformerUtil.INIT.equals(name))
return false; // <init> invocations don't pass verifier in modern JVMs
if (config.isMethodTracked(cname, name))
return true; // direct invocation of tracked method through its actual class
if (opcode != Opcodes.INVOKEVIRTUAL && opcode != Opcodes.INVOKEINTERFACE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
* @author Dmitry Paraschenko
*/
class MethodAnalyzer extends AbstractMethodVisitor {
public MethodAnalyzer(GeneratorAdapter mv, Context context) {
super(mv, context);
public MethodAnalyzer(GeneratorAdapter mv, Context context, int classVersion) {
super(mv, context, classVersion);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class MethodTransformer extends AbstractMethodVisitor {

private Label startFinally;

public MethodTransformer(GeneratorAdapter mv, Context context) {
super(mv, context);
public MethodTransformer(GeneratorAdapter mv, Context context, int classVersion) {
super(mv, context, classVersion);
}

private void pushAllocationPoint(String desc) {
Expand Down

0 comments on commit f8e066d

Please sign in to comment.