Моя цель - вставить немного кода инструментария в начале каждого базового блока кода. Это похоже на довольно простую задачу с ControlFlow.Block и CtMethod.insertAt() Javaassist. Вот соответствующий фрагмент кода до сих пор (он находится в функции преобразования):Код Javassist's CtMethod.insertAt (строка, src) при неправильной позиции байткода
ControlFlow flow=new ControlFlow(m); //m is the CtMethod currently being instrumented
Block[] blockArray=flow.basicBlocks();
for(Block thisbb : blockArray){
//Dynamically Update Method Statistics
String blockUpdate=new String();
String thisbbIndex=Integer.toString(thisbb.index());
blockUpdate+=mse+".setBlockIndex("+thisbbIndex+"); ";
blockUpdate="{ " + blockUpdate + "} ";
//Insert
int pos=m.getMethodInfo().getLineNumber(thisbb.position()); //Source code line position from binary line position
System.out.print("At "+pos+": "+blockUpdate);
int n=m.insertAt(pos, blockUpdate);
System.out.println(" -> "+n);
}
Обратите внимание, что параметр «строка» в CtMethod.insertAt(line,srcCode)
является исходным кодом положения линии, а не линия положения байткода. В исходном коде некоторые базовые блоки сообщают тот же номер строки! Вот результат:
At 6: { _JDA_mse.setBlockIndex(0); } -> 6
At 8: { _JDA_mse.setBlockIndex(1); } -> 8
At 8: { _JDA_mse.setBlockIndex(2); } -> 8
At 8: { _JDA_mse.setBlockIndex(3); } -> 8
At 8: { _JDA_mse.setBlockIndex(4); } -> 8
At 8: { _JDA_mse.setBlockIndex(5); } -> 8
At 8: { _JDA_mse.setBlockIndex(6); } -> 8
At #
представляет собой место, которое я просил код, который будет помещен в, и -> #
представляет расположение в исходном коде, что он был фактически вставлен (если все работает, они должны быть тоже самое). Все внутри { ... }
- это код, который я хочу разместить (_JDA_mse
- это локальная переменная, которую я добавил к функции с помощью методов Javassist, поэтому нет никаких проблем с ее использованием).
Проблема заключается в том, что for(int i=0; i<size; ++i)
содержит несколько базовых блоков, которые неотделимы от исходного кода, но четко различаются в байте-коде. Вот почему несколько базовых блоков сопоставляются с одной и той же исходной строкой, и это просто показывает, что строки исходного кода не обеспечивают достаточной точности инструментария для регистрации базовых блоков. Есть ли способ эмулировать CtMethod.insertAt (bytecodePosition, srcString) вместо использования предоставленного CtMethod.insertAt (sourceLine, srcString)?