void Method::_set_nop() { bool verbose = false; Global_Env *env = VM_Global_State::loader_env; if (get_name() != env->Init_String || get_descriptor() != env->VoidVoidDescriptor_String) { return; } if(is_native()) { return; } unsigned len = _byte_code_length; if(!len) { return; } U_8* bc = _byte_codes; Nop_Stack_State stack_state = NS_StackEmpty; if(verbose) { printf("=========== nop[%d]: %s.%s%s\n", len, get_class()->get_name()->bytes, get_name()->bytes, get_descriptor()->bytes); } for (unsigned idx = 0; idx < len; idx++) { U_8 b = bc[idx]; if(verbose) { printf("\tbc[%d]=%d, state=%d\n", idx, b, stack_state); } if(b == 0xb1) { // return if(verbose) { printf("+++++++ nop: %s.%s%s\n", get_class()->get_name()->bytes, get_name()->bytes, get_descriptor()->bytes); } _flags.is_nop = TRUE; return; } switch(stack_state) { case NS_StackEmpty: switch(b) { case 0x2a: // aload_0 stack_state = NS_ThisPushed; break; default: return; } break; case NS_ThisPushed: switch(b) { case 0x01: // aconst_null case 0x03: // iconst_0 stack_state = NS_ThisAndZeroPushed; break; case 0xb7: // invokespecial { unsigned index = (bc[idx + 1] << 8) + bc[idx + 2]; if(verbose) { printf("\tinvokespecial, index=%d\n", index); } Method_Handle mh = resolve_special_method_env(VM_Global_State::loader_env, get_class(), index, false); Method *callee = (Method *)mh; if(!callee) { if(verbose) { printf("\tinvokespecial, callee==null\n"); } return; } if(callee == this) { return; } if(verbose) { printf("invokespecial: %s.%s%s\n", callee->get_class()->get_name()->bytes, callee->get_name()->bytes, callee->get_descriptor()->bytes); } if(!callee->is_nop()) { return; } const char *descr = callee->get_descriptor()->bytes; if(descr[1] != ')') { return; } if(verbose) { printf("invokespecial nop: %s.%s%s\n", callee->get_class()->get_name()->bytes, callee->get_name()->bytes, callee->get_descriptor()->bytes); } } stack_state = NS_StackEmpty; idx += 2; break; default: return; } break; case NS_ThisAndZeroPushed: switch(b) { case 0xb5: // putfield stack_state = NS_StackEmpty; if(verbose) { printf("\tputfield\n"); } idx += 2; break; default: return; } break; default: LDIE(57, "Unexpected stack state"); return; } } LDIE(56, "should'nt get here"); } //Method::_set_nop
// // resolve constant pool reference to a method // used for invokespecial // Method_Handle resolve_special_method(Compile_Handle h, Class_Handle c, unsigned index) { return resolve_special_method_env(compile_handle_to_environment(h), c, index, false); } //resolve_special_method