Как использовать visitLdcInsn для загрузки объекта

Я использую 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 в тот же класс и попытался его использовать, приведенный выше код теперь заменен ниже.

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 для visitLdcInsn я понял, что мы не можем просто напрямую использовать что-либо типа Object (getDescriptor возвращает Object, где as getMethodName и getDescriptor возвращают строку), если только это не org.objectweb.asm.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();
}
}

Спасибо

Вишванат Б


person VishwanathB    schedule 30.09.2013    source источник


Ответы (1)


Ldc означает постоянную нагрузку. Вы можете использовать его только для констант, которые известны при (пере) написании класса.

Кроме того, его можно использовать только для определенных типов констант: целые, длинные, числа с плавающей запятой, двойные числа, строки, классы, дескрипторы методов и типы методов. И постоянные строки ограничены 64 КБ.

Наконец, это, вероятно, не будет иметь значения, поскольку JVM все равно должна оптимизировать такие вещи, если значение действительно является константой. Вы профилировали, чтобы определить, что это действительно проблема?

person Antimony    schedule 30.09.2013
comment
Спасибо Antimony, я видел этот javadoc из ASM 4.0, и я вижу это для visitLdcInsn } else if (cst instanceof Type) { int sort = ((Type) cst).getSort(); if (sort == Type.OBJECT) { // ... } } else if (cst instanceof Handle) { // ... } else { // генерировать исключение } cst - константа для загрузки в стек. Этот параметр должен быть ненулевым целым числом, числом с плавающей запятой, длинным, двойным, строкой, типом ОБЪЕКТА или сортировкой МАССИВ для констант .class, читая это, я подумал, что может быть способ загрузить объект. - person VishwanathB; 30.09.2013