ASM으로 메소드 변경하기
메소드의 실행 시간을 알아내는 코드를 삽입하는 작업을 수행한다.
원본 코드로 <code 1>을 사용한다.
<code 1>
변경을 통해 <code 2>와 같이 되도록 한다.
<code 2>
ASMifier를 통해 어떻게 바뀌어야 하는 지 알아보자.
<code 3>
변경하기 전은 위와 같다.
변경 후는 어떤지 보면
<code 4>
<code 3> 과 <code 4>를 비교해 보면
mv.visitLdcInsn(new Long(100L));
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "sleep", "(J)V", false);
위 코드를 기준으로 아래 위로 추가된 내용이 보인다.
여기서 어려운 점은, 메소드를 추가 할때와는 달리 기존의 코드 앞뒤에 새로운 코드를 추가해야한다는 것이다. 또한, 메소드 내에서 지역 변수를 하나 사용해야 한다. 이 변수는 메소드의 시작부인 MethodVisitor의 visitCode()에서 수행한다. 코드의 마지막은 visitInsn() 메소드에서 리턴에 해당하는 opcode를 검사하여 수행한다. mv.visitVarInsn(LLOAD, 1);의 두번째 인자인 1의 경우 로컬 변수 인덱스를 나타내는데, 위 코드에서는 this를 제외하고 메소드에 다른 인자가 없으므로 1이지만 일반적인 메소드에 적용하기 위해서는 이 값을 판단 할 수 있어야 한다. 이런 지역 변수를 추가하고 인덱스 알아오는데 도움을 주는 클래스가 LocalVariablesSorter이다. 이를 이용하여 메소드를 변환하는 MethodVisitor를 만들어 보자.
<code 5>
지역 변수 추가를 위해 LocalVariablesSorter 를 상속받아 사용했다. newLocal이라는 메소드가 이를 수행한다. 리턴 값은 할당된 지역 변수의 인덱스 값이다.
<code 6>
위 코드를 사용하여 <code 1>을 변환한다.
'프로그래밍 > BCI' 카테고리의 다른 글
[Java] ASM JSR/RET are not supported with computeFrames option (0) | 2015.03.26 |
---|---|
BCI(Byte Code Instrumentation) (0) | 2015.03.26 |
[Java] ASM을 이용한 메소드 추가 하기 (0) | 2015.03.23 |
[Java] ASM으로 메소드 생성 하기 (0) | 2015.03.23 |
[Java] ASM ClassWriter options (0) | 2015.03.23 |