我试图将asm用于BCI,我有一个要求,我应该注入“if condition”,所以我尝试使用下面的东西
Below is the code snippet..if i comment the jump instruction things work fine..with jump instruction i see verifyerror
@Override
protected void onMethodEnter() {
try{
visitor.visitVarInsn(ALOAD, 0);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
Label jump = new Label();
visitor.visitJumpInsn(IFEQ,jump);
visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello","(Z)V");
visitor.visitVarInsn(ALOAD, 0);
visitor.visitInsn(ICONST_1);
visitFieldInsn(PUTFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitLabel(jump);
visitor.visitVarInsn(ALOAD, 0);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello",
"()V");
}catch(Exception e){
e.printStackTrace();
}
}
但是当我尝试运行时,我得到以下异常
java.lang.VerifyError: JVMVRFY036 stack underflow; class=com/vish/MyWrapper, method=service()V, pc=10
at java.lang.J9VMInternals.verifyImpl(Native Method)
at java.lang.J9VMInternals.verify(J9VMInternals.java:72)
at java.lang.J9VMInternals.verify(J9VMInternals.java:70)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:134)
如果我评论跳转指令,那么一切正常。
我做了一些阅读并且发现由于使用了JumpInstructions而有可能弄乱堆栈映射帧,并且还读到使用COMPUTE_FRAMES选项和SKIP_FRAMES将导致堆栈映射帧的自动计算< / p>
“public static final int COMPUTE_FRAMES 标记以从头开始自动计算方法的堆栈映射帧。如果设置了此标志,则忽略对MethodVisitor.visitFrame(int,int,java.lang.Object [],int,java.lang.Object [])方法的调用,并从中重新计算堆栈映射帧。方法字节码。 visitMaxs方法的参数也被忽略并从字节码重新计算。换句话说,computeFrames意味着computeMaxs。“
任何人都可以解释我在做什么错误。我还需要在跳转指令的情况下计算堆栈映射帧吗?如果是这样的话,可以在某个地方获取样本堆栈映射帧的计算方法吗? ?
由于
答案 0 :(得分:1)
这里介绍的指令:
visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello","(Z)V");
...在堆栈上需要一个布尔(整数)参数。如果IFEQ
存在,则堆栈为空。如果您注释掉IFEQ
,则堆栈具有参数。堆栈下溢是通过调用方法而没有堆栈上的必要参数引起的。这与堆栈帧映射无关。
答案 1 :(得分:1)
问题在于你错过了第一个sayHello
的参数。如果您想传递getCached
的结果,则需要在其前添加另一个visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
。
假设这是预期的,代码应该是
visitor.visitVarInsn(ALOAD, 0);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
Label jump = new Label();
visitor.visitJumpInsn(IFEQ,jump);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello","(Z)V");
visitor.visitVarInsn(ALOAD, 0);
visitor.visitInsn(ICONST_1);
visitFieldInsn(PUTFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitLabel(jump);
visitor.visitVarInsn(ALOAD, 0);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello",
"()V");