The old verifier tries to verified unreachable code

Keith McGuigan keith.mcguigan at oracle.com
Sun Aug 19 19:02:39 PDT 2012


Hi Rémi,

Neither the old nor new verifier does any control-flow analysis to 
determine which parts of the bytecode are reachable; they both iterate 
over all the bytecodes (the old one potentially more than once) to 
ensure that the incoming and outgoing state of each bytecode is valid.

So throwing a verifier error in this situation is expected, and is, I 
believe, required by the Java Virtual Machine Specification.

--
- Keith

On 8/19/2012 10:00 AM, Rémi Forax wrote:
> Hi guys,
> I suppose that the bytecode verifier belong to this list,
> the following code while stupid should in my opinion be a valid bytecode
> given that the bytecode at 3 is not reachable
>
> public void foo()
> Code:
>     Stack=0, Locals=2, Args_size=1
>     0:   goto    6
>     3:   astore_1
>     4:   return
>    Exception table:
>     from   to  target type
>       3     4     3   any
>
> but it seems that the old verifier requires the stack to be at least 1
> even if
> the exception handler is never reachable.
>
> Here is a simple code using ASM to reproduce the bug.
>
> public static void main(String[] args) {
>      ClassWriter writer = new ClassWriter(0);
>      writer.visit(V1_5, ACC_PUBLIC|ACC_SUPER, "Foo", null,
> "java/lang/Object", null);
>      MethodVisitor mv = writer.visitMethod(ACC_PUBLIC, "foo", "()V",
> null, null);
>      mv.visitCode();
>
>      Label start = new Label();
>      Label end = new Label();
>      Label handler = new Label();
>      mv.visitTryCatchBlock(start, end, handler, null);
>
>      Label label = new Label();
>      mv.visitJumpInsn(GOTO, label);
>
>      mv.visitLabel(handler);
>      mv.visitLabel(start);
>      mv.visitVarInsn(ASTORE, 1);
>      mv.visitLabel(end);
>
>      mv.visitLabel(label);
>      mv.visitInsn(RETURN);
>
>      mv.visitMaxs(0, 2);
>      mv.visitEnd();
>      writer.visitEnd();
>
>      final byte[] byteArray = writer.toByteArray();
>      Class<?> clazz = new ClassLoader() {
>        Class<?> def() {
>          return defineClass("Foo", byteArray, 0, byteArray.length);
>        }
>      }.def();
>
>      clazz.getDeclaredMethods();
>    }
>
> cheers,
> Rémi
>


More information about the hotspot-runtime-dev mailing list