如何使用visitLdcInsn加载Object

时间:2013-09-30 12:50:25

标签: bytecode java-bytecode-asm bytecode-manipulation

我正在使用ASM来注入代码并且到目前为止一直很幸运,在压力测试期间我观察到我看到一些性能下降,因为我编写的代码正在进行大量静态调用,以优化它我尝试缓存我使用的变量。在原始代码中,这就是我所做的

  visitor.visitLdcInsn(getMethodName());
  visitor.visitLdcInsn(getDescriptor());
  visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MYTRACKER.HELPER_CLASS,     
          MYTrackingConstants.HELPER_GET_CLIENT_METHOD,MYTrackingConstants.HELPER_GET_CLIENT_METHOD_DESC);
.
.

上面的静态调用导致性能问题,因为它被称为时间,为了优化它我缓存了对象并在同一个类中添加了一个getter方法并尝试使用它,上面的代码现在由下面的代码替换< / p>

visitor.visitLdcInsn(getRTTDescriptor());

但是当我跑步时,我得到了这个例外

      [err] java.lang.IllegalArgumentException: value com.vish.MyTransformDescriptor@63f463f4
      [err]     at org.objectweb.asm.ClassWriter.a(Unknown Source)
      [err]     at [internal classes]
      [err]     at  sun.instrument.TransformerManager.transform(TransformerManager.java:181)
      [err]     at  sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:377)
      [err]     at java.lang.ClassLoader.defineClassImpl(Native Method) 
      [err]     at java.lang.ClassLoader.defineClass(ClassLoader.java:275)

在阅读javadoc for visitLdcInsn后,我意识到我们不能直接使用Object类型的任何东西(getDescriptor返回Object,其中getMethodName和getDescriptor返回字符串),除非它是org.objectweb.asm.Type你可以帮助我或者任何人提供了一个示例示例,说明如何使用Type来加载我的对象?

以下是我的代码片段

public RTMethodAdapter{
Object rttd;
public RTMethodAdapter(MethodVisitor visitor, MethodInfo mInfo, String reqOpsType, String classname,Object rttd, AnalyzerAdapter aa)
{
 . 
 .
 .
 this.rttd = rttd;
}

public Object getRTTDescriptor(){
    return rttd;
}
public String getMethodName() {
    return methodInfo.getMethodName();
}

public String getDescriptor() {
    return methodInfo.getDescriptor();
}
}

由于

VishwanathB

1 个答案:

答案 0 :(得分:1)

Ldc代表负载常数。您只能将它用于(重新)编写类时已知的常量。

此外,它只能用于特定类型的常量:int,long,float,double,strings,classes,methodhandles和methodstypes。并且常量字符串限制为64kb。

最后,这可能不会产生任何影响,因为如果值真的是常量,JVM应该优化这样的事情。你有没有确定这确实是一个问题?