ASM Bytecode to identify for / while loops

2019-09-23 08:22发布

问题:

Using ASM Bytecode Can we identify for loops or while loops present in the method body?

回答1:

It depends on which information you want to extract. In principle, you can detect loops by searching for backward branches. A loop can’t work without and with usual code structures you won’t find backward branches which are not part of a loop.

So if you want to have them named explicitly, all of the bytecode instructions goto, goto_w, if_acmpeq, if_acmpne, if_icmpeq, if_icmpge, if_icmpgt, if_icmple, if_icmplt, if_icmpne, ifeq, ifge, ifgt, ifle, iflt, ifne, ifnonnull, ifnull may indicate a loop if they point backwards.

But in most cases you will have a hard time telling what kind of loop you have. There is no significant difference between a for loop and a while loop in the compiled code. E.g., the following code fragments are entirely equivalent:

  • for(a();b();c()) {
      d();
    }
    
  • a();
    for(;b();) {
      d();
      c();
    }
    
  • a();
    for(;;) {
      if(!b()) break;
      d();
      c();
    }
    
  • a();
    while(b()) {
      d();
      c();
    }
    

It will become even worse with more complicated structure, e.g. when you want to find out whether two backward branches pointing to the same code location belong to a single loop with a conditional continue statement within the body or to two nested loops. It can turn out to be impossible.